中最頻繁出現的顏色比方說,我有如下形象:判斷一個圖像(OpenCV的&C++)
我正在尋找一種方法以編程方式確定紅色是最圖片中常見的顏色。
到目前爲止,我已經嘗試了一些方法,以各種不良的結果來實現這一點。我目前的做法是首先減少圖像中的顏色。
這是用下面的代碼完成:
Mat samples(src.rows * src.cols, 3, CV_32F);
for(int y = 0; y < src.rows; y++)
for(int x = 0; x < src.cols; x++)
for(int z = 0; z < 3; z++)
samples.at<float>(y + x * src.rows, z) = src.at<Vec3b>(y,x)[z];
int clusterCount = 16;
Mat labels;
int attempts = 2;
Mat centers;
kmeans(samples, clusterCount, labels, TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 10000, 0.0001), attempts, KMEANS_PP_CENTERS, centers);
Mat reduced(src.size(), src.type());
for(int y = 0; y < src.rows; y++)
for(int x = 0; x < src.cols; x++)
{
int cluster_idx = labels.at<int>(y + x * src.rows,0);
reduced.at<Vec3b>(y,x)[0] = centers.at<float>(cluster_idx, 0);
reduced.at<Vec3b>(y,x)[1] = centers.at<float>(cluster_idx, 1);
reduced.at<Vec3b>(y,x)[2] = centers.at<float>(cluster_idx, 2);
}
有一個與它一個惱人的問題,即它有一個問題與縮放留下了右側的部分,但我可以與現在一起生活。
接下來,我嘗試了一些方法,我想要繪製顏色,例如直方圖。
Mat image_hsv;
cvtColor(src, image_hsv, CV_BGR2HSV);
// Quanta Ratio
int scale = 10;
int hbins = 36, sbins = 25, vbins = 25;
int histSize[] = {hbins, sbins, vbins};
float hranges[] = { 0, 360 };
float sranges[] = { 0, 256 };
float vranges[] = { 0, 256 };
const float* ranges[] = { hranges, sranges, vranges };
MatND hist;
int channels[] = {0, 1, 2};
calcHist(&image_hsv, 1, channels, Mat(), // do not use mask
hist, 3, histSize, ranges,
true, // the histogram is uniform
false);
int maxVal = 0;
int hue = 0;
int saturation = 0;
int value = 0;
for(int h = 0; h < hbins; h++)
for(int s = 0; s < sbins; s++)
for(int v = 0; v < vbins; v++)
{
int binVal = hist.at<int>(h, s, v);
if(binVal > maxVal)
{
maxVal = binVal;
hue = h;
saturation = s;
value = v;
}
}
hue = hue * scale * scale; // angle 0 - 360
saturation = saturation * scale; // 0 - 255
value = value * scale; // 0 - 255
的問題是,對於這個圖像I得到以下值:
- 色調:240
- 飽和度:0
- 值:0
然而,我我期待的HSV值更接近這個:
- 色調:356
- 飽和度:94
- 值:58
希望有人能指出我哪裏錯了。
懶得分析你的代碼,但只是一個提示測試你正確處理你的圖像像素格式?我敢打賭,你得到RGB並將其作爲BGR處理,反之亦然,因爲色調240是藍色而不是紅色(我習慣於GDI/Canvas通常對某些像素格式的原始圖像數據的反轉順序)但S ,V設置爲零確實很奇怪。也請看看這個:[HSV直方圖](https://stackoverflow.com/a/29286584/2521214) – Spektre
只是好奇,如何計算顏色直方圖使用[calcHist](https://docs.opencv.org /2.4/modules/imgproc/doc/histograms.html#calchist)並找到高峯?當然,不是HSV值問題的答案。 calcHist將比kmeans快得多。 – dhanushka
@dhanushka速度取決於顏色直方圖的實現,數量等等......所以它可能也不一定比具有相同精度的k-means更快。但是,我也會使用直方圖,這就是爲什麼我建議在以前的評論中的鏈接,因爲有我的C++實現,即RGB - > HSV轉換,計算和渲染HSV直方圖(無openCV) – Spektre