Opencv 准备好数据(每行一个样本)以便使用k-means进行聚类?

Opencv 准备好数据(每行一个样本)以便使用k-means进行聚类?,opencv,cluster-analysis,k-means,sift,Opencv,Cluster Analysis,K Means,Sift,我试图使用kmeans函数对关键点(使用SIFT检测)进行聚类,但在准备使用时遇到了问题 使用以下代码将关键点保存到xml/yml文件中: int _tmain(int argc, _TCHAR* argv[]) { Mat img; img = imread("c:\\box.png", 0); SiftFeatureDetector detector; vector<KeyPoint> keypoints; detector.detect(img, keypoints);

我试图使用kmeans函数对关键点(使用SIFT检测)进行聚类,但在准备使用时遇到了问题

使用以下代码将关键点保存到xml/yml文件中:

int _tmain(int argc, _TCHAR* argv[])
{
Mat img;

img = imread("c:\\box.png", 0);

SiftFeatureDetector detector;
vector<KeyPoint> keypoints;
detector.detect(img, keypoints);



FileStorage fs("keypoint1.xml", FileStorage::WRITE);
write(fs, "keypoints1", keypoints);
fs.release();
该函数要求输入为每个样本一行。有人能解释一下吗,我的意思是上面的文件可以作为一行使用吗?它是否符合使用文件存储读取方法的kmeans

我想添加到文件并从中读取的原因是,假设我有100个图像,它们的关键点需要聚集。我想将所有这些文件附加到一个巨大的文件中,并对其进行集群


谢谢

筛选点的数量因图像而异,因此也没有固定长度的向量进行投影。此外,将它们连接起来以创建一个大向量的顺序意味着顺序很重要。SIFT特征是一组点(不是向量)


您需要更复杂的度量来定义相似性。欧几里德或其他基于向量的度量将不起作用。OpenCV的K-means需要向量输入,因此无法工作。

筛选点的数量随图像而异,因此也没有固定长度的向量进行投影。此外,将它们连接起来以创建一个大向量的顺序意味着顺序很重要。SIFT特征是一组点(不是向量)


您需要更复杂的度量来定义相似性。欧几里德或其他基于向量的度量将不起作用。OpenCV的K-means需要向量输入,因此无法工作。

Tom是正确的。通常使用SIFT时,每个图像使用多个关键点。这就是关键点检测背后的全部思想,即在后续步骤中,您尝试仅处理图像的“有趣”部分

因此,对于聚类图像,常规的SIFT特征将不能很好地工作。它们适用于全景构建等,您可以在多个图像中找到相同的关键点

然而,你可以“滥用”筛选关键点;这可能就是你想要复制的东西。如果你阅读相关的文章,而不是仅仅从编码的角度去理解它,肯定会有所帮助

这里有一个简单的介绍:

请注意,它们是如何使用常规栅格从每个图像中采样相同数量的关键点的。然而,他们仍然没有把它们放在一个巨大的数组中——这对相似性搜索不起作用。相反,它们执行一种降维

他们在所有图像的所有单个关键点上运行k-means,以获得1000个“公共”关键点,称为视觉单词。然后,他们将每个关键点转换为最佳匹配的视觉单词,并通过这种方式获得类似文本的图像表示。除了关键点没有人类可读的名称外,您可以想象将图像表示为类似于“sky fur fur forest sky fur water forest water water water forest”的图像,该图像中有一只海狸在湖中游泳


在这些单词包中,您可以再次运行聚类或相似性搜索。K-means不会很好地工作,因为向量是稀疏的。欧几里得距离对稀疏数据不起作用,而k-均值不幸是为欧几里得距离设计的。此外,手段不再稀疏,这使它们变得异常。最有可能的是,结果的方法彼此之间的相似性比实例更高,这使得整个分区都显得荒谬。

Tom是正确的。通常使用SIFT时,每个图像使用多个关键点。这就是关键点检测背后的全部思想,即在后续步骤中,您尝试仅处理图像的“有趣”部分

因此,对于聚类图像,常规的SIFT特征将不能很好地工作。它们适用于全景构建等,您可以在多个图像中找到相同的关键点

然而,你可以“滥用”筛选关键点;这可能就是你想要复制的东西。如果你阅读相关的文章,而不是仅仅从编码的角度去理解它,肯定会有所帮助

这里有一个简单的介绍:

请注意,它们是如何使用常规栅格从每个图像中采样相同数量的关键点的。然而,他们仍然没有把它们放在一个巨大的数组中——这对相似性搜索不起作用。相反,它们执行一种降维

他们在所有图像的所有单个关键点上运行k-means,以获得1000个“公共”关键点,称为视觉单词。然后,他们将每个关键点转换为最佳匹配的视觉单词,并通过这种方式获得类似文本的图像表示。除了关键点没有人类可读的名称外,您可以想象将图像表示为类似于“sky fur fur forest sky fur water forest water water water forest”的图像,该图像中有一只海狸在湖中游泳


在这些单词包中,您可以再次运行聚类或相似性搜索。K-means不会很好地工作,因为向量是稀疏的。欧几里得距离对稀疏数据不起作用,而k-均值不幸是为欧几里得距离设计的。此外,手段不再稀疏,这使它们变得异常。最有可能的是,结果的平均值彼此更相似,而不是与实例更相似,这使得整个分区变得荒谬。

筛选特征是一回事,每个特征的值构建了向量。当您从SIFT关键点提取SIFT描述符时,您正在提取4x4区域中8个可能方向上的梯度大小。因此,每个关键点都有一个具有128个特征的向量,或者如果需要,有128个维度。这和表示p是一样的
%YAML:1.0
keypoints1: [ 6.1368021965026855e+000, 5.2649226188659668e+000,
    4.0740542411804199e+000, 2.7943280029296875e+002, 0., 9109760, -1,
    6.1368021965026855e+000, 5.2649226188659668e+000,
    4.0740542411804199e+000, 3.4678604125976562e+002, 0., 9109760, -1,
    1.5903041076660156e+002, 2.4698186874389648e+001,
    4.1325736045837402e+000, 9.7977493286132813e+001, 0., 10158336, -1,
    1.6808378601074219e+002, 2.5029441833496094e+001,
    4.2399377822875977e+000, 9.7380126953125000e+001, 0., 11993344, -1,
    1.9952423095703125e+002, 4.4663669586181641e+001,
    5.0049328804016113e+000, 5.7439949035644531e+001, 0., 7275008, -1,
    3.0947158813476563e+002, 4.6865818023681641e+001,......................