“红色”颜色检测尚未开始。以下代码应该检测输入图像中的红色条,并返回一个在相应位置显示白条的蒙版图像。
inputRGBimage中“红色”条的相应HSV值为:H = 177,S = 252,V = 244
cv::Mat findColor(cv::Mat inputRGBimage) {
cv::Mat imageHSV(inputRGBimage.rows, inputRGBimage.cols, CV_8UC3);
cv::Mat imgThreshold(inputRGBimage.rows, inputRGBimage.cols, CV_8UC1);
// convert input-image to HSV-image
cvtColor(inputRGBimage, imageHSV, cv::COLOR_BGR2HSV);
// for red: (H < 14)
// cv::inRange(imageHSV, cv::Scalar(0, 53, 185, 0), cv::Scalar(14, 255, 255, 0), imgThreshold);
// or (H > 165) (...closing HSV-circle)
cv::inRange(imageHSV, cv::Scalar(165, 53, 185, 0), cv::Scalar(180, 255, 255, 0), imgThreshold);
return imgThreshold;
}
下面的两张图显示了inputRGBimage(顶部)和返回的imgThreshold(底部)。正如您所看到的,面具未显示预期颜色为“红色”的白色条,但在“蓝色”条上显示了一些未知原因。为什么????
cv :: inRange代码行(即H> 120)的以下更改再次说明颜色检测实际上没有按预期运行:
// or (H > 120) (...closing HSV-circle)
cv::inRange(imageHSV, cv::Scalar(120, 53, 185, 0), cv::Scalar(180, 255, 255, 0), imgThreshold);
作为第三个例子:(H> 100):
// or (H > 100) (...closing HSV-circle)
cv::inRange(imageHSV, cv::Scalar(100, 53, 185, 0), cv::Scalar(180, 255, 255, 0), imgThreshold);
为什么我的3个代码示例中的颜色意外顺序(将H值从165降低到100)显示掩码顺序为“blue-&gt; violet-&gt; red-&gt; orange”而不是实际预期HSV车轮粗略顺序为“红色 - >紫色 - >蓝色 - >绿色 - >黄色 - >橙色”?????
OpenCV中的HSV范围: 0 <= H <= 180, 0&lt; = S&lt; = 255, 0 <= V <= 255,(不完全像上面的图示 - 但是OpenCV HSV颜色的颜色顺序应该相同 - 或者不是???)
答案 0 :(得分:2)
确保图像使用通道顺序B,G,R。此外,对于红色,您需要检查两个值范围,一个围绕H=0
,另一个围绕H=180
。你可以尝试这个功能:
cv::Mat findColor(const cv::Mat & inputBGRimage, int rng=15)
{
// Make sure that your input image uses the channel order B, G, R (check not implemented).
cv::Mat input = inputBGRimage.clone();
cv::Mat imageHSV;//(input.rows, input.cols, CV_8UC3);
cv::Mat imgThreshold, imgThreshold0, imgThreshold1;//(input.rows, input.cols, CV_8UC1);
assert( ! input.empty() );
// convert input-image to HSV-image
cv::cvtColor( input, imageHSV, cv::COLOR_BGR2HSV );
// In the HSV-color space the color 'red' is located around the H-value 0 and also around the
// H-value 180. That is why you need to threshold your image twice and the combine the results.
cv::inRange(imageHSV, cv::Scalar( 0, 53, 185, 0), cv::Scalar(rng, 255, 255, 0), imgThreshold0);
if ( rng > 0 )
{
cv::inRange(imageHSV, cv::Scalar(180-rng, 53, 185, 0), cv::Scalar(180, 255, 255, 0), imgThreshold1);
cv::bitwise_or( imgThreshold0, imgThreshold1, imgThreshold );
}
else
{
imgThreshold = imgThreshold0;
}
return imgThreshold;
}
祝你好运! :)