在OpenCV中创建基于Kmeans数据的聚类图像

3

我正在尝试从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个回答

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 );
    }

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

编辑现在你已经改变了代码,使用mImagefor循环中,那么你需要看看为什么会出现断言错误。断言消息是由模板代码非常混乱,所以这里是来自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将为nil。您无法在空矩阵上调用at。无论如何,请检查mImage的属性以查看哪个导致断言错误。


很抱歉我省略了一些变量,因为我只是在测试不同的技术,看看能否得到结果。mRegion只是一个与mImage具有相同维度和类型的空矩阵。我尝试使用mImage,但出现了错误,所以我尝试使用空矩阵,但仍然出现了相同的错误。 - Seb
那么在这种情况下,我是否需要将我的256x256图像转换为一个65536x1的数组? - Seb
不,256x256是可以的。那是dims <= 2测试。你可能失败了,因为data为空或i大于点数。在for循环之前尝试添加cout << "data: " << mImage.data << endl; - SSteve
当我尝试转换矩阵时,似乎我的数据丢失了。现在我必须找出如何保留数据。感谢您的帮助。 - Seb
1
原来直接在图像上运行kmeans是不行的。它需要在一个包含坐标的n行1列矩阵上运行。在这种情况下,它们是2D坐标。我自己没有做过这个,但也许你可以在输入图像上运行一个阈值,然后用高于阈值的像素的维度填充一个矩阵。 - SSteve

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接