我正在使用C++,但python中的回答也很好。使用cvtColor轉換單個BGR顏色並使用結果從圖像中提取該顏色
我需要將已知的BGR顏色轉換爲HSV才能使用cv :: inRange方法,該方法允許您提取圖像的某個部分。我已經有了能夠估計我需要的BGR顏色的代碼,所以我認爲我應該能夠猜測它的範圍。
所以我推薦這個鏈接:Convert a single color with cvtColor這似乎工作轉換BGR HSV,雖然我仍然有一些奇怪的輸出,我會稍後解釋。
反正這裏是我的代碼:
//store BGR values and convert BGR to HSV
cv::Mat3f hairColor(cv::Vec3f(averageBlue, averageGreen, averageRed));
cv::Mat3f finalHSV;
cv::cvtColor(hairColor, finalHSV, CV_BGR2HSV);
//change values to be valid with the cv::inRange function (find this part odd)
finalHSV.ptr<float>(0)[0] /= 2;
finalHSV.ptr<float>(0)[1] *= 255;
//store hsv values as integers
int averageHue = finalHSV.ptr<float>(0)[0];
int averageSat = finalHSV.ptr<float>(0)[1];
int averageValue = finalHSV.ptr<float>(0)[2];
//try to appromimate ranges. I'm trying to mess wtih these values but can't calibrate it whatsoever
int hueMin = averageHue - 20; int hueMax = averageHue + 100;
int saturationMin = averageSat - 20; int saturationMax = averageSat + 20;
int valueMin = averageValue - 50; int valueMax = averageValue + 50;
//bw is the output array for my mask.
cv::inRange(hsv, cv::Scalar(hueMin, saturationMin, valueMin), cv::Scalar(hueMax, saturationMax, valueMax), bw);
因此,這裏是簡單的例子:我的代碼確定近似BGR顏色我想具有值[126,105,98]。轉換爲HSV的初始形式給出[225,0.22,126],這似乎奇怪地是不正確的如何opencv存儲hsv(如色相是0-179我認爲),所以我做了2次轉換得到[112,56,126],我認爲應該是正確的?
無論如何,當我嘗試在我的inRange函數中修改數值時,我無法真正獲得任何好的提取,我傾向於只是得到一個黑色屏幕(我測試了我的面具的工作原理,並且這樣做的問題應該是提供的代碼)。
有沒有更好的方法去完成這項任務?
好吧我有這部分轉換和工作在c + +,但它似乎沒有得到我想要提取一貫的確切顏色。使用cvInRange真的是唯一的方法來提取特定的顏色,如果是的話,什麼是提供良好範圍的最佳方式? – Eango
是的,爲了提取顏色,它正是你想要使用的。如果你想要一致地提取顏色,這取決於你的應用程序是什麼以及你的意思是一致的。例如,對於許多應用程序來說,一個穩健可靠的方法是使用該顏色在圖像中找到一個區域,找到該區域中顏色的平均值和標準偏差,然後用'inRange()'以下限平均值 - n * stddev'和上限'mean + n * stddev'其中'n'讓我們選擇您想要偏離特定顏色的標準偏差。 –
真棒只是做了一個區域的標準偏差提示,似乎改善了很多我的圖像。感謝您的幫助:) – Eango