2016-09-21 2 views
2

제 질문에 깊이 빠져들기 전에이 포럼에서 다른 게시물을 읽었지만 내 문제는 아는 것이 좋습니다. 특히 here 게시물은 "어떻게해야합니까?"라는 질문에 대답합니다. k- 수단으로, 나는 그것을 사용해야한다는 것을 이미 알고있는 반면, 나의 구현이 효과가없는 이유를 알고 싶습니다.OpenCV : k- 수단을 사용하여 이미지의 분할을 얻을 수 없습니다.

k- 평균 알고리즘을 사용하여 입력 이미지의 픽셀을 색상에 따라 클러스터로 나누고 싶습니다. 그런 다음 이러한 작업을 완료 한 후에는 각 픽셀에 할당 된 클러스터의 중심 색을 유지해야합니다. 계산의 끝에서, 나는 단순히 검은 이미지를 얻을,

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

어쨌든 다음 OpenCV의 예와 웹 검색 다른 물건을 참조로 촬영 , 나는 다음과 같은 코드를 설계했습니다. 이유를 알고 계십니까? I 알고리즘의 끝에서

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

같은 결과 행렬을 초기화하는 경우 이상하게, 어떤 분할없이 정확하게 입력 화상을 표시한다. 특히

, I는 두 의심 :

1)이 매트릭스 의 각 행에있는 화소의 RGB 값을 마련하여 정확가 그것을 수행 한 방식 조정할

? 거기에 루프없이 그것을 할 수있는 방법이 있습니까?

2) k-means 함수가 작동을 마친 후 정확히 센터의 내용은 무엇입니까? 그것은 3 열 매트릭스, 그것은 클러스터의 센터의 RGB 값을 포함합니까?

지원해 주셔서 감사합니다.

+0

[다음과 같은 공식이있을 수 있습니다. BGR 값이 주어진 전체 색상을 결정합니까? (OpenCV 및 C++)] (http://stackoverflow.com/questions/34734379/is-there-a-formula-to-determine-overall-color-given-bgr-values-opencv-and-c) – Miki

+0

감사합니다 대답. 제게 문제의 해결 방법을 알려 주신 포스트는 저에게 코드를 보여줌으로써 이루어졌습니다. 어쨌든, 가능하다면 다음 번에 같은 오류를 범하기가 거의 확실하기 때문에 내가 어디에서 잘못되었는지 알기를 바랍니다. 내 두 가지 의문에 대한 답변을 가질 수 있습니까? 지원을 주셔서 감사 드리며 너무 많은 것을 부탁 드려 죄송합니다. 나는이 게시물을 복제의 고전적인 사례로 취급하지 않기를 바랍니다 :) – ubisum

+0

1) 예, 정확하지만 값은 부동이어야합니다. 내 게시물에서 루프없이 수행하는 방법을 볼 수 있습니다. 2) 예, BGR의 클러스터 센터 값을 float로 변환하려면 uchar로 변환해야합니다. 나는 지금 이것을 더 깊이 볼 수는 없지만 내 포스트는 충분히 분명해야한다. – Miki

답변

0

-THE 아래에서 OpenCV 프로그램

이미지 내의 특정 픽셀 값에 대한 사용자 선호하는 컬러를 할당 전기 - ScanImageAndReduceC()가 OpenCV의 사전에 정의 된 방법은 이미지의 모든 픽셀을 검사하는 것이다

- I.atuchar>(10, 10) = 255; 화상 여기서

특정 픽셀 값에 액세스하는 데 사용되는 코드이며 0

매트 & ScanImageAndReduceC (매트 & I) {

//에만 문자 유형 행렬을 CV_Assert (I 동의합니다.깊이() == 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; 

}

------- 메인 프로그램 -------

diff = ScanImageAndReduceC(diff); 

namedWindow("Difference", WINDOW_AUTOSIZE);// Create a window for display. 
imshow("Difference", diff);     // Show our image inside it. 

waitKey(0);           // Wait for a keystroke in the window 
return 0; 

}

관련 문제