从OpenCV中的kmeans数据创建聚簇图像

时间:2011-08-11 12:43:27

标签: c image-processing opencv k-means

我正在尝试根据从kmeans函数返回的数据创建聚簇图像。我尝试以类似的方式从OpenCV示例中提取数据,但这似乎让我崩溃了。经过一些进一步的研究后,我看到有人通过使用这些中心来取出数据,但没有对这些数据做任何事情,所以我的踪迹就在那里结束了。

我已经包含了我的代码片段以及我在下面做的事情。任何帮助将不胜感激。

修改 我已将代码恢复到原始状态,没有任何测试变量。上述错误仍然存​​在。我还在下面添加了一些关于我的图像的调试信息:

图片信息:

  • 尺寸:2
  • 图片数据:
  • 尺寸0:256
  • 尺寸1:256
  • Elemsize 1:12
  • Elemsize 2:4

当数据为NULL时,如果我在其上调用cv::imshow,我仍然可以查看数据。

// mImage is a cv::Mat that was created from a 256 x 256 image with the depth of
// CV_32F and 3 channels
// labels is a cv::Mat that was created by converting the image into a 256 x 256
// CV_8UC1 IplImage
kmeans(mImage, 6, labels, termcrit, 3, cv::KMEANS_PP_CENTERS, centers);
float* c = new float[6];
memcpy(c, centers.ptr<float>(0), sizeof(float)*6);

// Block of code that crashes when I do "mImage.at<cv::Point2f>(i)" with the error:
/* OpenCV Error: Assertion failed (dims <= 2 && data && (size.p[0] == 1 || 
       size.p[1] == 1) && (unsigned)i0 < (unsigned)(size.p[0] + size.p[1] - 1) && 
       elemSize() == (((((DataType<_Tp>::type) & ((512 - 1) << 3)) >> 3) + 1) << 
       ((((sizeof(size_t)/ 4+1)*16384|0x3a50) >> ((DataType<_Tp>::type) & 
       ((1 << 3) - 1))*2) & 3))) in unknown function, file 
       c:\opencv-2.3.0\modules\core\include\opencv2\core\mat.hpp, line 583 */

for(int i = 0; i < list.rows; i++)
{
    int clusterIdx = list.at<int>(i);
    cv::Point ipt = mImage.at<cv::Point2f>(i);
    circle( miplImage, ipt, 2, colorTab[clusterIdx], CV_FILLED, CV_AA );
}

1 个答案:

答案 0 :(得分:1)

您在调用mRegion.at()时收到断言错误。 mRegion定义在哪里?

以下是kmeans.cpp示例代码中的等效代码段:

    kmeans(points, clusterCount, labels, 
           TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0),
           3, KMEANS_PP_CENTERS, centers);

    img = Scalar::all(0);

    for( i = 0; i < sampleCount; i++ )
    {
        int clusterIdx = labels.at<int>(i);
        Point ipt = points.at<Point2f>(i);
        circle( img, ipt, 2, colorTab[clusterIdx], CV_FILLED, CV_AA );
    }

它对points的第一个参数和kmeans循环中ipt的来源使用相同的变量for。我想你可能想在mImage循环中使用for,而不是mRegion。

编辑现在您已经在for循环中更改了代码以使用mImage,您需要了解为什么会收到断言错误。断言消息非常混乱模板代码,所以这里来自mat.hpp:

dims <= 2 && data && (size.p[0] == 1 || size.p[1] == 1) &&
             (unsigned)i0 < (unsigned)(size.p[0] + size.p[1] - 1) &&
             elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type)

其中一项或多项测试失败。如果你使用的是空的mImage,那将是一个失败,因为data将是零。您无法在空矩阵上调用at。在任何情况下,检查mImage的属性以查看导致断言错误的原因。