簡體   English   中英

OpenCV:無法使用k-means進行圖像分割

[英]OpenCV: can't get segmentation of image using k-means

在深入探討我的問題之前,我希望您知道我已經閱讀了該論壇上的其他帖子,但是沒有人認為我的問題與眾不同。 特別是, 這里的帖子回答了“如何做到這一點”的問題。 使用k-means,雖然我已經知道必須使用它,並且我想知道為什么我的實現無法正常工作。

我想使用k-means算法將輸入圖像的像素根據其顏色分為幾類。 然后,完成此任務后,我希望每個像素都具有分配給它的群集中心的顏色。 以OpenCV示例和網上檢索的其他內容為參考,我設計了以下代碼:

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>

using namespace std;
using namespace cv;


int main( int argc, char** argv )
{

    Mat src = imread( argv[1], 1 );

    // reshape matrix
    Mat resized(src.rows*src.cols, 3, CV_8U);
    int row_counter = 0;

    for(int i = 0; i<src.rows; i++)
    {
        for(int j = 0; j<src.cols; j++)
        {
            Vec3b channels = src.at<Vec3b>(i,j);
            resized.at<char>(row_counter,0) = channels(0);
            resized.at<char>(row_counter,1) = channels(1);
            resized.at<char>(row_counter,2) = channels(2);

            row_counter++;
        }
    }

    //cout << src << endl;

    // change data type
    resized.convertTo(resized, CV_32F);

    // determine termination criteria and number of clusters
    TermCriteria criteria(TermCriteria::COUNT + TermCriteria::EPS, 10, 1.0);
    int K = 8;

    // apply k-means
    Mat labels, centers;
    double compactness = kmeans(resized, K, labels, criteria, 10, KMEANS_RANDOM_CENTERS, centers);

    // change data type in centers
    centers.convertTo(centers, CV_8U);

    // create output matrix
    Mat result = Mat::zeros(src.rows, src.cols, CV_8UC3);

    row_counter = 0;
    int matrix_row_counter = 0;
    while(row_counter < result.rows)
    {
        for(int z = 0; z<result.cols; z++)
        {
            int index = labels.at<char>(row_counter+z, 0);
            //cout << index << endl;
            Vec3b center_channels(centers.at<char>(index,0),centers.at<char>(index,1), centers.at<char>(index,2));
            result.at<Vec3b>(matrix_row_counter, z) = center_channels;
        }

        row_counter += result.cols;
        matrix_row_counter++;
    }

    cout << "Labels " << labels.rows << " " << labels.cols << endl;
    //cvtColor( src, gray, CV_BGR2GRAY );
    //gray.convertTo(gray, CV_32F);

    imshow("Result", result);
    waitKey(0);


    return 0;
}

無論如何,在計算結束時,我只會得到一張黑色圖像。 你知道為什么嗎? 奇怪的是,如果我將結果矩陣初始化為

Mat result(src.size(), src.type())

在算法結束時,它將准確顯示輸入圖像,而不會進行任何分割。

特別是,我有兩個疑問:

1)將像素的RGB值放置在按照我的方法調整大小的矩陣的每一行上是否正確? 有沒有辦法做到這一點而沒有循環?

2)在k均值函數完成工作之后, 中心的確切內容是什么? 它是一個3列的矩陣,它是否包含聚類中心的RGB值?

感謝你的支持。

Mat& ScanImageAndReduceC(Mat& I) {

// accept only char type matrices CV_Assert(I.depth() == CV_8U);

// accept only char type matrices CV_Assert(I.depth() == CV_8U);
 int channels = I.channels(); int nRows = I.rows; int nCols = I.cols * channels; if (I.isContinuous()) { nCols *= nRows; nRows = 1; } int i, j; uchar* p; for (i = 0; i < nRows; ++i) { p = I.ptr<uchar>(i); for (j = 0; j < nCols; ++j) { I.at<uchar>(10, 10) = 255; } } return I; 

}

-------主程序-----

  差異= ScanImageAndReduceC(diff);\n\n namedWindow(“ Difference”,WINDOW_AUTOSIZE); //創建一個顯示窗口。\n imshow(“ Difference”,diff);  //在其中顯示我們的圖像。\n\n waitKey(0);  //等待窗口中的擊鍵\n 返回0;\n

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM