不知道“k”的OpenCV中的分层k-Means

Posted

技术标签:

【中文标题】不知道“k”的OpenCV中的分层k-Means【英文标题】:Hierarchical k-Means in OpenCV without knowledge of "k" 【发布时间】:2011-07-24 14:22:09 【问题描述】:

我正在尝试对一组 4D 向量进行聚类,但事先不知道应该有多少个聚类。在过去,我已经能够使用 cvKmeans2 进行聚类,只要知道聚类的数量。我正在浏览 API 并遇到cv::flann::hierarchicalClustering。这看起来可以满足我的需要(即,执行 k-means,在必要时拆分集群,迭代直到拆分使结果恶化),但我真的在为“索引参数”而苦苦挣扎。

我发现我需要创建一个 index structure 作为第二个参数,但我从以下代码中得到一个错误:

cv::flann::Index fln_idx = cv::flann::KMeansIndexParams::createIndex( framePoints );

错误是:

../src/segmentation_1.cpp:592: error: cannot call member function ‘virtual flann::Index* cv::flann::KMeansIndexParams::createIndex(const cv::Mat&) const’ without object

framePoints定义如下:

CvMat *framePoints = cvCreateMat( frameTracklets.size( ), 4, CV_32FC1 );

我很确定我在做一些非常愚蠢的事情(我的 C++ 知识还可以,但不是很好)。我想我已经发布了所有相关的代码,但如果没有,请告诉我,我会发布更多。

提前致谢!

更新

我已按照 LumpN 的建议创建了一个 Kmeans 对象,使用以下内容:

cv::Mat centres;
cv::flann::KMeansIndexParams fln_idx = cv::flann::KMeansIndexParams();
fln_idx.createIndex( framePoints );

int numClust;
numClust = hierarchicalClustering(framePoints, centres, fln_idx);

现在,当我运行它时,我从hierarchicalClustering() 收到一条错误消息,上面写着“所需集群的数量应该是 >= 1”(我需要检查何时开始工作 - 我将使用实际错误)。我假设createIndex() 给了它起点,然后hierarchicalClustering() 拆分集群直到找到一个好的结果(不确定这是否是最佳的)。我需要用一些参数来调用cv::flann::KMeansIndexParams() 吗?我看过api,完全糊涂了! 再次感谢!

【问题讨论】:

值得注意的是 cvflann::HierarchicalClusteringIndex 类似于 k-means 但不是。它是 Muja & Lowe 使用分层聚类树森林快速匹配二元特征 (ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=6233169) 的方法的实现。它不是k-means,因为没有像k-means那样尝试减少整体失真的迭代步骤,即点到其聚类中心的距离平方和,它从数据中选择聚类中心而不是取平均值。 【参考方案1】:

您必须传递对createIndex 的引用,即createIndex(*framePoints)(注意星号!)。另一个错误可能是 createIndex 是一个非静态(成员)函数。在这种情况下,您必须创建一个 KMeansIndexParams 对象并在其上调用 createIndex

【讨论】:

感谢您的回复 :) 创建 KMeansIndexParams 对象解决了这个问题,但现在我有了另一个 - 它说所需的集群数必须至少为 1。我认为算法应该确定所需集群的数量?【参考方案2】:

“所需集群的数量必须至少为 1”。

所需的集群计数由 center.rows 确定。所以你必须先调整中心的大小。 例如:

Mat centers (clusterCount,DESCRIPTOR_SIZE,cv_32FC1);
int count = cv::flann::hierarchicalClustering<cvflann::L2<float> >(descriptors,centers,cvflann::KMeansIndexParams(32,11,cvflann::FLANN_CENTERS_KMEANSPP));

【讨论】:

以上是关于不知道“k”的OpenCV中的分层k-Means的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV:iOS中的k-means聚类

R中的分层k倍交叉验证

VLFeat 分层 k-means:词汇树中的节点数

OpenCV 完整例程42. 图像的灰度变换(比特平面分层)

OpenCV 完整例程41. 图像的灰度变换(灰度级分层)

聚类分析