如何在C ++ OpenCV中将图像(Mat)转换为inputArray?

时间:2015-10-06 17:35:59

标签: c++ opencv

我想对灰度图像的强度值应用k均值聚类。我真的很困惑如何将像素表示为矢量。因此,如果我的图片是H x W像素,那么我的矢量应该是H*W维。

我尝试过的是:

int myClass::myFunction(const cv::Mat& img)
{
    cv::Mat grayImg;    
    cvtColor(img, grayImg, CV_RGB2GRAY);    
    cv::Mat bestLabels, centers, clustered;
    cv::Mat p = cv::Mat::zeros(grayImg.cols*grayImg.rows, 1, CV_32F);
    int i = -1;
    for (int c = 0; c<img.cols; c++) {
        for (int r = 0; r < img.rows; r++) {
            i++;
            p.at<float>(i, 0) = grayImg.at<float>(r, c);

        }
    }
// I should have obtained the vector in p, so now I want to supply it to k-means: 
int K = 2;
    cv::kmeans(p, K, bestLabels,
        cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 1.0),
        3, cv::KMEANS_PP_CENTERS, centers);
// Since K=2, I want to obtain a binary image with this, so the same operation needs to be reversed (grayImg -> p , then bestLabels -> binaryImage)
}

但是我收到了错误:Unhandled exception at 0x00007FFD76406C51 (ntdll.dll) in myapp.exe

我是OpenCV的新手,所以我不确定如何使用这些功能。我找到了这段代码here。例如,为什么我们使用.at<float>,其他一些帖子说灰度图像像素存储为<char> s ??我越来越感到困惑,所以任何帮助都会受到赞赏:)

谢谢!

修改

感谢Miki,我找到了正确的方法。但最后一个问题是,如何查看cv::Mat1b result的内容?我试着像这样打印它们:

for (int r = 0; r < result.rows; ++r)
    {
        for (int c = 0; c < result.cols; ++c)
        {
            result(r, c) = static_cast<uchar>(centers(bestLabels(r*grayImg.cols + c)));
            if (result(r, c) != 0) {
                std::cout << "result = " << result(r, c) << " \n";
            }               
        }
    }

但它继续打印result=0,即使我特别要求它不要:)我如何访问这些值?

1 个答案:

答案 0 :(得分:9)

  1. 您不需要从Mat转换为InputArray,但您可以(而且应该)只传递一个Mat对象{{1}请求。有关详细说明,请参阅here

  2. kmeans接受一个I​​nputArray,它应该是一个需要浮点坐标的N维点数组。

  3. 使用InputArray个对象,您需要Mat才能访问该像素的值。但是,您可以使用img.at<type>(row, col) Mat_的模板版本来修复类型,这样您就可以像Mat一样访问该值。

  4. 所以最终的代码是:

    img(r,c)