【问题标题】:OpenCV's clustering function cvKMeans2() - why doesnt work when i use the centers parameterOpenCV 聚类函数 cv KMeans2() - 为什么当我使用中心参数时不起作用
【发布时间】:2011-11-13 08:57:48
【问题描述】:

我使用此代码。它应该打印集群标签然后是质心。但是中心点的“中心”矩阵似乎是空的,全是零。朋友们怎么了?

 #include <iostream>
   #include <stdio.h>


     #include "cxcore.h"
      #include "highgui.h"
        using namespace cv;


       int main( int argc, char** argv )
       {

        int i,j;


              CvMat* points = cvCreateMat( 5, 2, CV_32FC1 );
                CvMat* centers2 = cvCreateMat( 5, 2, CV_32FC1 );
               CvMat* clusters = cvCreateMat( 5, 1, CV_32SC1 );

               cvSetReal2D( points, 0, 0,1);
                  cvSetReal2D( points, 0, 1,1);
                   cvSetReal2D( points, 1, 0,2);
                    cvSetReal2D( points, 1, 1,2);
                     cvSetReal2D( points, 2, 0,6);
                        cvSetReal2D( points, 2, 1,6);
                      cvSetReal2D( points, 3, 0,5);
                       cvSetReal2D( points, 3, 1,5);
                              cvSetReal2D( points, 4, 0,10);
                             cvSetReal2D( points, 4, 1,10);
 cvKMeans2(points,3,clusters,cvTermCriteria(CV_TERMCRIT_EPS,1000,0 ), 
 1000,0,KMEANS_RANDOM_CENTERS,centers2,0);

 for(i=0;i<5;i++)
  printf( " %lf \n", cvGetReal2D(clusters,i, 0));

       for(i=0;i<5;i++){
              for(j=0;j<2;j++){
        printf( "center %i %i = %f \n", i, j, cvGetReal2D(centers2,i, j));
    }
  }


          cvReleaseMat(&points);
               cvReleaseMat(&centers2);
                  cvReleaseMat(&clusters);
                      }

【问题讨论】:

    标签: opencv k-means


    【解决方案1】:

    您的代码不起作用,因为 centers2 的大小大于请求的集群数。但是,您似乎发现了一个 OpenCV 错误 - centers2 必须重新分配,但没有。

    把你的代码改成

    CvMat* centers2 = cvCreateMat( 3, 2, CV_32FC1 );
    

    for(i=0;i<3;i++){
        for(j=0;j<2;j++){
            printf( "center %i %i = %f \n", i, j, cvGetReal2D(centers2,i, j));
    

    但最好使用 C++ 接口(C 版本的 kmeans 只是 C++ 实现的包装器):

    float pointsdata[] = { 1,1, 2,2, 6,6, 5,5, 10,10};
    Mat points(5, 2, CV_32F, pointsdata);
    Mat labels, centers;
    
    kmeans(points, 3, labels, TermCriteria(CV_TERMCRIT_EPS, 1000, 0), 1000, KMEANS_RANDOM_CENTERS, centers);
    
    cout << "labels: " << labels << endl;
    cout << "centers " << centers << endl;
    

    【讨论】:

    • 好吧,我已经尝试了一周的时间来使用 C++ 接口。但我无法理解如何使用这种类型访问 myelements。如果有 CvMat* points = cvCreateMat(5, 2, CV_32FC1) ; 然后我用 cvSetReal2D(points, 0, 0,1);我用 cvGetReal2D(clusters,i, 0)) 得到元素;但是当我有 Mat points(5, 2, CV_32F); 然后我用 float pointsdata[] = { 1,1, 2,2, 6 设置初始元素,6, 5,5, 10,10};垫点(5、2、CV_32F、pointsdata);但是如何获取我的元素?我的意思是,如果我想让浮点 c 与第一个元素相等,那么... c= ?? c=points.at(0,0)????
    • 如果您在元素访问方面遇到问题,最好发布另一个问题,但总的来说您是正确的 - mat.at&lt;float&gt;(0,0) 返回对单通道 CV_32F Mat 的第一个元素的引用。
    猜你喜欢
    • 2011-01-05
    • 2014-04-19
    • 2021-10-04
    • 2021-05-29
    • 2021-04-04
    • 2019-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多