OpenCV4Android Kmean无法按预期工作

问题描述:

此代码应为中心垫提供3行和clusterCount列数

This code should give centers mat with 3 rows and clusterCount number of columns

    Mat reshaped_image = imageMat.reshape(1, imageMat.cols()*imageMat.rows());
    Mat reshaped_image32f = new Mat();
    reshaped_image.convertTo(reshaped_image32f, CvType.CV_32F, 1.0 / 255.0);

    Mat labels = new Mat();
    TermCriteria criteria = new TermCriteria(TermCriteria.COUNT, 100, 1);
    Mat centers = new Mat();
    int clusterCount = 5, attempts = 1;
    Core.kmeans(reshaped_image32f, clusterCount, labels, criteria, attempts, Core.KMEANS_PP_CENTERS, centers);

我在C中尝试了相同的代码,并获得了3行和clusterCount列数的中心Mat。

I tried same code in C and got centers Mat with 3 rows and clusterCount number of columns.

但在java中,Core.kmeans返回4列和簇的行数。

But in java the Core.kmeans returning 4 columns and cluster number of rows.

centers.reshape(3);

所以现在重塑函数不适用于中心,因为行数取决于簇大小。在C中,行数总是不变的,即3。

so now the reshape function doesn't work on centers since the number of rows are depended on cluster size. In C the number of rows are always constant i.e 3.

所以在java中它给出错误

so in java it gives error


矩阵的行数不能除以新的行数

the number of rows of the matrix cannot be divided by new number of rows

有人可以弄清楚是什么问题。我甚至尝试过这个到我的代码并得到同样的错误。

Can someone figure out what is the problem. I even tried this which is similar to my code and got same error.

参考C代码:

    cv::Mat reshaped_image = image.reshape(1, image.cols * image.rows);
    cv::Mat reshaped_image32f;
    reshaped_image.convertTo(reshaped_image32f, CV_32FC1, 1.0 / 255.0);

    cv::Mat labels;
    int cluster_number = 5;
    cv::TermCriteria criteria(cv::TermCriteria::COUNT, 100, 1);
    cv::Mat centers;
    cv::kmeans(reshaped_image32f, cluster_number, labels, criteria, 1, cv::KMEANS_PP_CENTERS, centers);


最后它起作用了: -

Finally it worked :-

我使用bitmapToMat函数将位图转换为Mat,该函数返回RGBA图像。所以这些中心有4列而不是3列。

I converted bitmap to Mat using bitmapToMat function which returns a RGBA image. so the centers has 4 columns instead of 3.

如果要将位图转换为Mat,如果你需要BGR图像,那就这样做

If you are converting bitmap to Mat and if you need BGR image then do this

    Mat imageMat = new Mat();
    Utils.bitmapToMat(bitmap, imageMat);

    Imgproc.cvtColor(imageMat, imageMat, Imgproc.COLOR_BGRA2BGR);

干杯