2014-02-07 4 views
1

나는이 게시물과 비슷한 것을하려고합니다 : Getting dominant colour value from HSV HistogramOpenCV Core.MinMaxLocResult는 무엇을 반환합니까?

나는 이미지가 있고 그것으로부터 지배적 인 색조 (색조)를 추출하고 싶습니다. 나는 히스토그램을 계산하고 minMaxLoc에서 maxValue를 얻었습니다. 그러나 Core.MinMaxLocResult에서 검색하는 숫자는 전혀 의미가 없습니다. 나는 806924와 1067036 같은 것을 얻고있다. 색조의 예상 값이 0과 180 사이가 아니어야합니까?

히스토그램은 정규화되어 있습니까? 어떻게 그렇게? "equalizeHist"및 "normalize"와 같은 메서드를 보았지만이 메서드를 사용하는 방법과 사용 방법을 실제로 알지 못합니다.

또한 가장 현명한 "색조"번호를 얻은 후이를 어떻게 실제 색조 (예 : "녹색이 이미지에서 가장 많이 나오는 색")로 변환합니까? 표준 색조 범위가 있습니까? 0-10은 빨간색, 10-20은 보라색 등입니까?

업데이트 : 여기 내 코드입니다 :

private void processImage(String imgFilename) { 
      channels = new MatOfInt[] { new MatOfInt(0), new MatOfInt(1), 
      new MatOfInt(2) }; 
    histSize = new MatOfInt(histSizeNum); 
    hRanges = new MatOfFloat(0f, 180f); // hue varies from 0 to 179 
    // use openCV stuff to convert from RGB to HLS space 
    Mat src = Highgui.imread(imgFilename); 
    Mat hls = new Mat();// destination color space 
    Imgproc.cvtColor(src, hls, Imgproc.COLOR_RGB2HLS); 
    Core.split(hls, hlsChannels); 
    Mat hue = hlsChannels.get(0); 
    Mat lum = hlsChannels.get(1); 
    Mat sat = hlsChannels.get(2); 
    // we compute the histogram from the 0-th channel for hue 
    Imgproc.calcHist(Arrays.asList(hls), channels[0], new Mat(), hist, 
      histSize, hRanges); 

    Core.normalize(hist, hist, 0,2, Core.NORM_MINMAX, -1, new Mat()); 

    Core.MinMaxLocResult result = Core.minMaxLoc(hist); 
    // max value should contain the most-recurring Hue value. 
    double mostOccurringHue = result.maxVal; 
    double leastOccurringHue = result.minVal; 
    //double mostOccurringHue = result.maxLoc.x; 
    //double leastOccurringHue = result.minLoc.x; 

    // print out for sanity checking 
    System.out.println("MAX HUE = " + Double.toString(mostOccurringHue) +"\n"); 
    System.out.println("MIN HUE = " + Double.toString(leastOccurringHue) +"\n"); 

답변

0

히스토그램 및 정규화를 계산하는 openCV의 ibuilt 메서드를 사용하는 대신, 색조 채널에 대해서만 막대 그래프를 만들 때 내 코드를 작성했습니다. 내 코드 좀 봐.

int main() 
{ 

    Mat input = imread("jan31/class4Jan31.jpg",1); 
    Mat hsv_input; 
    int h_bins = 5; 
    Mat hist_input = Mat::zeros(1, h_bins, CV_32FC1); 
    int h_range = 179; 
    int totalNumberPixels = 0; 

    cvtColor(input, hsv_input, CV_RGB2HSV); 
    Mat hsv_channels[3]; 

    split(hsv_input, hsv_channels); 

    for (int i=0; i<hsv_channels[0].rows; i++) 
    { 
     for (int j=0; j<hsv_channels[0].cols; j++) 
     {    
      if((int)hsv_channels[1].at<uchar>(i,j)>10 && (int)hsv_channels[1].at<uchar>(i,j)>100) 
      {    
       totalNumberPixels++; 
       int pixel_value = (int)hsv_channels[0].at<uchar>(i,j); 
       int corresponding_bin = (pixel_value * h_bins)/h_range;     
       hist_input.at<float>(0, corresponding_bin) = (hist_input.at<float>(0, corresponding_bin) + 1);     
      }                      
     } 
    } 

    cout<<"\n total pixels: "<<totalNumberPixels; 

    for(int i=0; i<hist_input.rows; i++) 
    { 
     for (int j=0; j<hist_input.cols; j++) 
     { 
      float pixel = hist_input.at<float>(i,j); 
      hist_input.at<float>(i,j) = pixel/totalNumberPixels; 

      pixel = hist_input.at<float>(i,j); 
      cout<<"\n Pixel: "<<pixel; 
     } 
    } 

    cv::waitKey(0); 
    return 0; 
} 
+0

고마워요. 필자는이 개념을 코드에서 테스트했으며 사용자보다 몇 가지 빈을 사용하여 적절한 색상을 식별 할 수있었습니다. 그러나 이것은 단 한 번만 나를 위해 일했습니다. 그 후, 중첩 된 for 루프는 성능이 매우 좋지 않습니다. 내 전체 응용 프로그램이 느려졌 고 힙/할당 문제가 발생합니다.안드로이드에서이 모든 작업을하고 있기 때문에 아마도 같은 문제가 발생하지 않았을 것입니다. 내장 된 openCV 히스토그램 계산은 내부적으로 더 효율적이라고 생각합니다. – KAB

+0

나는 그런 문제에 직면하지 않았다. 그리고 나에게는 단지 4 밀리 초 밖에 걸리지 않습니다. 두 번째로, openCv의 inbuilt calcHist()보다 더 나은 제어 기능을 가지고 있습니다.이 경우에는 채도와 V 채널에 대해 일부 thrshold를 설정하여 흰색과 검은 색 픽셀을 제거 할 수 있으므로 히스토그램 계산에 특정 픽셀 만 사용할 수 있습니다. 게다가, 당신이 bin의 수를 늘렸다 고 언급했듯이, calcHist()도 빈 수가 증가함에 따라 매우 느리지 만 그것을 사용하기를 원한다면, 시도해 볼 수있다. 그걸 써... – skm

0

당신이 코드의 일부를 게시 할 경우 그것은 좋은 것입니다. 당신은에 의해 히스토그램을 정상화 할 수 있습니다 당신은 자신 녹색 이미지의 H-구성 요소의 픽셀 값 확인하는 경우

normalize(hist_input, hist_input, 0, 2, NORM_MINMAX, -1, Mat()); 

녹색의 범위를 얻을 예측하기 위해서는 좋은 것입니다. 나를 위해, 그것은 53-65 세 거짓말이었다.

1

내가 언급 한 링크에 게시 된 답변을 다시 확인하는 것이 좋습니다. 다음 점에 대해서 생각해보십시오 :

- 색조 채널에서만 작업해야하므로 지배적 인 색상 값을 찾고 있습니다.

- 귀하의 hranges는 0-180이어야합니다.

-dims는 히스토그램 값만 필요하기 때문에 1 (2가 아님)이어야합니다.

==> 그 후 maxValLoc은 포인트가 x와 y 좌표로 구성되는 "포인트"형식으로 최대 값을 갖는 저장소를 알려줍니다. 예를 들어

:

double minVal; double maxVal; Point minLoc; Point maxLoc; 
minMaxLoc(hist_image, &minVal, &maxVal, &minLoc, &maxLoc, Mat()); 

는 이제 "MAXVAL는"최대 값과 "maxLoc.y"& "maxLoc.x"당신에게 것을 포함하는 점의 행 안부 값을 알려줍니다이 포함됩니다 최대 값.

+0

코드로 내 소식을 업데이트했습니다. 확인해 주시겠습니까? 나는 모든 제안을 고려해 봤지만 "mostOccurringHue"변수에 대해서는 여전히 유효한 색상 (0에서 180 사이)을 얻지 못하고 있습니다. 나는 정상화와 함께 노력했다. – KAB

+0

직접 색조 막대 그래프를 만드는 코드로 다른 답변을 올렸습니다 ... pls는 그것에 대해 살펴 봅니다 – skm