Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在C++;OpenCV?_C++_Opencv - Fatal编程技术网

C++ 如何在C++;OpenCV?

C++ 如何在C++;OpenCV?,c++,opencv,C++,Opencv,我想对灰度图像的强度值应用k均值聚类。我对如何将像素表示成向量感到困惑。所以如果我的图像是hxw像素,那么我的向量应该是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

我想对灰度图像的强度值应用k均值聚类。我对如何将像素表示成向量感到困惑。所以如果我的图像是
hxw
像素,那么我的向量应该是
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)
}
但是它一直在打印
result=0
,尽管我特别要求它不要:)我如何访问这些值

  • 您不需要从
    Mat
    转换到
    InputArray
    ,但是您可以(并且应该)只传递一个
    Mat
    对象,其中请求了
    InputArray
    。有关详细说明,请参阅

  • 接受一个输入数组,该数组应该是一个具有浮点坐标的N维点数组

  • 对于
    Mat
    对象,您需要
    img.at(row,col)
    来访问像素值。但是,您可以使用
    Mat
    这是一个模板版本的
    Mat
    来修复类型,因此您可以像
    img(r,c)
    一样访问值

  • 因此,最终代码将是:

    #include <opencv2\opencv.hpp>
    using namespace cv;
    
    
    int main()
    {
        Mat1b grayImg = imread("path_to_image", IMREAD_GRAYSCALE);
    
        Mat1f data(grayImg.rows*grayImg.cols, 1);
        for (int r = 0; r < grayImg.rows; r++)
        {
            for (int c = 0; c < grayImg.cols; c++)
            {
                data(r*grayImg.cols + c) = float(grayImg(r, c));
    
            }
        }
    
        // Or, equivalently
        //Mat1f data;
        //grayImg.convertTo(data, CV_32F);
        //data = data.reshape(1, 1).t();
    
    
        // I should have obtained the vector in p, so now I want to supply it to k-means: 
        int K = 8;
        Mat1i bestLabels(data.size(), 0); // integer matrix of labels
        Mat1f centers;                    // float matrix of centers
        cv::kmeans(data, K, bestLabels,
            cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 1.0),
            3, cv::KMEANS_PP_CENTERS, centers);
    
    
        // Show results
        Mat1b result(grayImg.rows, grayImg.cols);
        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)));
            }
        }
    
        imshow("Image", grayImg);
        imshow("Result", result);
        waitKey();
    
        return 0;
    }
    
    #包括
    使用名称空间cv;
    int main()
    {
    Mat1b grayImg=imread(“路径到图像”,imread\U灰度);
    Mat1f数据(grayImg.rows*grayImg.cols,1);
    对于(int r=0;r
    您不需要将Mat转换为InputArray。InputArray只是一个接受cv::Mat和std::vector的包装类。所以只要通过一个垫子,它接受一个输入,你就会没事了。关于这个错误。。。让我检查一下,你能把完整的代码贴出来吗?这里有很多遗漏的变量…@Miki,我省略了前面的部分,很抱歉。现在它应该有所有相关的代码。我确信输入是正确的,我绘制了灰色img,它看起来和预期的一样。其他3个变量初始化为
    cv::Mat
    。感谢您提供的信息,InputArray是不必要的。所以我可以用一个
    cv::Mat
    大小
    [H*W x 1]
    (或转置),对吗?贴出答案,它应该能回答你所有的问题。让我知道。非常感谢你!这很有效。不过,我有两个问题。1.您如何决定使用
    Mat1b
    Mat1f
    等中的哪一个?我的第二个问题是,如何打印
    结果的像素?因为我怀疑它们可能有值1或2,而我想将它们转换为0和1。我想补充一下我在问题中尝试过的东西,我真的非常感谢你最后的帮助。再次感谢!您可能还对我的新问题感兴趣:)1)根据文档。读取代码更容易,并且当类型不正确时,代码中会出现干净的错误。使用at()访问Mat时,您必须知道类型。结果中的值已经是簇中心的灰度值,因此在[0255]中。您可以使用imshow查看结果图像。如果希望图像带有标签,则需要创建Mat1i,并将bestLabels中的值放入其中。
    
    #include <opencv2\opencv.hpp>
    using namespace cv;
    
    
    int main()
    {
        Mat1b grayImg = imread("path_to_image", IMREAD_GRAYSCALE);
    
        Mat1f data(grayImg.rows*grayImg.cols, 1);
        for (int r = 0; r < grayImg.rows; r++)
        {
            for (int c = 0; c < grayImg.cols; c++)
            {
                data(r*grayImg.cols + c) = float(grayImg(r, c));
    
            }
        }
    
        // Or, equivalently
        //Mat1f data;
        //grayImg.convertTo(data, CV_32F);
        //data = data.reshape(1, 1).t();
    
    
        // I should have obtained the vector in p, so now I want to supply it to k-means: 
        int K = 8;
        Mat1i bestLabels(data.size(), 0); // integer matrix of labels
        Mat1f centers;                    // float matrix of centers
        cv::kmeans(data, K, bestLabels,
            cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 1.0),
            3, cv::KMEANS_PP_CENTERS, centers);
    
    
        // Show results
        Mat1b result(grayImg.rows, grayImg.cols);
        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)));
            }
        }
    
        imshow("Image", grayImg);
        imshow("Result", result);
        waitKey();
    
        return 0;
    }