2015-03-01 13 views
6

Tôi muốn tìm màu chủ đạo trên hình ảnh. Đối với điều này, tôi biết rằng tôi nên sử dụng biểu đồ hình ảnh. Nhưng tôi không chắc chắn về định dạng hình ảnh. Bạn nên sử dụng hình ảnh rgb, hsv hoặc xám nào?Tìm màu chủ đạo trên hình ảnh

Sau khi biểu đồ được tính toán, tôi nên tìm giá trị tối đa trên biểu đồ. Đối với điều này, tôi có nên tìm giá trị binVal tối đa bên dưới cho hình ảnh hsv không? Tại sao hình ảnh kết quả của tôi chỉ chứa màu đen?

float binVal = hist.at<float>(h, s);

EDIT:

Tôi đã thử đoạn code dưới đây. Tôi vẽ biểu đồ h-s. Và hình ảnh kết quả của tôi ở đây. Tôi không tìm thấy gì sau ngưỡng nhị phân. Có lẽ tôi tìm thấy giá trị biểu đồ tối đa không chính xác.

enter image description here enter image description here

cvtColor(src, hsv, CV_BGR2HSV); 

// Quantize the hue to 30 levels 
// and the saturation to 32 levels 
int hbins = 20, sbins = 22; 
int histSize[] = {hbins, sbins}; 
// hue varies from 0 to 179, see cvtColor 
float hranges[] = { 0, 180 }; 
// saturation varies from 0 (black-gray-white) to 
// 255 (pure spectrum color) 
float sranges[] = { 0, 256 }; 
const float* ranges[] = { hranges, sranges }; 
MatND hist; 
// we compute the histogram from the 0-th and 1-st channels 
int channels[] = {0, 1}; 

calcHist(&hsv, 1, channels, Mat(), // do not use mask 
     hist, 2, histSize, ranges, 
     true, // the histogram is uniform 
     false); 
double maxVal=0; 
minMaxLoc(hist, 0, &maxVal, 0, 0); 

int scale = 10; 
Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3); 
int maxIntensity = -100; 
for(int h = 0; h < hbins; h++) { 
    for(int s = 0; s < sbins; s++) 
    { 
     float binVal = hist.at<float>(h, s); 
     int intensity = cvRound(binVal*255/maxVal); 
     rectangle(histImg, Point(h*scale, s*scale), 
        Point((h+1)*scale - 1, (s+1)*scale - 1), 
        Scalar::all(intensity), 
        CV_FILLED); 
     if(intensity > maxIntensity) 
      maxIntensity = intensity; 
    } 
} 
std::cout << "max Intensity " << maxVal << std::endl; 
Mat dst; 
cv::threshold(src, dst, maxIntensity, 255, cv::THRESH_BINARY); 

namedWindow("Dest", 1); 
imshow("Dest", dst); 
namedWindow("Source", 1); 
imshow("Source", src); 

namedWindow("H-S Histogram", 1); 
imshow("H-S Histogram", histImg); 

Trả lời

5

Giải pháp

  • Tìm HS histogram
  • Tìm giá trị đỉnh H (sử dụng chức năng minmaxLoc)
  • Tách hình ảnh 3 kênh (h, s, v)
  • Áp dụng cho ngưỡng.
  • Tạo hình ảnh bằng cách hợp nhất 3 kênh
+3

Bạn có phiền khi đăng một số mã không? cảm ơn –

3

Dưới đây là một số gợi ý để giúp bạn bắt đầu.

  • Tất cả 3 kênh trong RGB đóng góp vào màu sắc, vì vậy bạn phải tìm ra nơi ba biểu đồ khác nhau ở mức tối đa. (Hoặc tổng của họ là tối đa, hoặc bất cứ điều gì.)
  • HSV có tất cả thông tin về màu sắc (tốt, Huế) trong một kênh, vì vậy bạn chỉ phải xem xét một biểu đồ.
  • Grayscale ném đi tất cả thông tin màu sắc, vì vậy khá là vô ích khi tìm kiếm màu sắc .

Thử chuyển đổi thành HSV, sau đó tính toán biểu đồ trên kênh H.

Như bạn nói, bạn muốn tìm giá trị lớn nhất trong biểu đồ. Nhưng:

  • Bạn có thể muốn xem xét một loạt các giá trị thay vì chỉ một, nói từ 20-40 thay vì chỉ 30. Hãy thử các kích thước phạm vi khác nhau.
  • Hãy nhớ rằng Hue là hình tròn, do đó, H=0H=360 giống nhau.
  • Thử vẽ biểu đồ theo sau:
    http://docs.opencv.org/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html
    để xem kết quả của bạn có hợp lý không.
  • Nếu bạn đang sử dụng một dải Hues và bạn tìm thấy phạm vi tối đa, bạn có thể chỉ sử dụng giữa phạm vi đó làm màu chủ đạo hoặc bạn có thể tìm thấy trung bình của các màu trong phạm vi đó và dùng nó.

    Hãy thử mọi thứ. Chơi.

8

Hoặc bạn có thể thử phương thức k-means. Calculate k clusters với k ~ 2..5 và lấy trọng tâm của nhóm lớn nhất làm màu chiếm ưu thế của bạn.

Các python docu của OpenCV có illustrated example mà được màu sắc chủ đạo (s) khá tốt:

+0

Tôi nên tìm diện tích màu lớn nhất rất nhanh và hình ảnh của tôi rất lớn. Phương pháp này có hiệu quả cho tác vụ này không? – zumma

+0

hmm, cảm ơn lời khuyên của bạn. Tôi không sử dụng nó. – zumma

+0

Không, rất có thể chậm hơn so với một biểu đồ đơn giản (phiên bản chính xác thậm chí là NP-hoàn thành). Nhưng vì nhiệm vụ này thực hiện giảm kích thước mạnh từ các pixel 'N' xuống chỉ một màu, bạn có thể không lấy tất cả các pixel vào tài khoản, tức là mẫu phụ ảnh đầu tiên (độc lập với phương pháp bạn sử dụng để xác định sau đó). – mbschenkel

Các vấn đề liên quan