使用OpenCV检测颜色的最有效方法

Most efficient method to detect color using OpenCV?

本文关键字:有效 方法 颜色 OpenCV 检测 使用      更新时间:2023-10-16

我使用在图像中心附近的某个地方设置了一个感兴趣的区域

Mat frame;
//frame has been initialized as a frame from a camera input
Rect roi= cvRect(frame.cols*.45, frame.rows*.45, 10, 8);
image_roi= frame(roi);
//I stoped here not knowing what to do next

我使用的是相机,在任何时候,当我抓取一帧时,ROI都会在30%到100%之间,填充我想要的颜色,在这种情况下是红色。如果红色出现在我的当前帧中,最有效的方法是什么?

解决方案:

image_roi= frame(roi);// a frame from my camera as a cv::Mat
cvtColor(image_roi, image_roi, CV_BGR2HSV);
thrs= new Mat(image_roi.rows, image_roi.cols, CV_8UC1);//allocate space for new img
inRange(image_roi, Scalar(0,100,100), Scalar(12,255,255), *thrs);//do hsv thresholding for red
for(int i= 0; i < thrs->rows; i++)//sum up
{
    for(int j=0; j < thrs->cols; j++)
    {
        sum= sum+ thrs->data[(thrs->rows)* i + j];
    }
}
if(sum> 100)//my application only cares about red
    cout<<"Red"<<endl;
else
    cout<<"White"<<endl;
sum=0;

我假设您只想知道ROI中红色的百分比。如果不正确,请澄清。

我会扫描ROI,并将每个像素转换为更好的颜色空间进行颜色比较,例如YCbCr或HSV。然后,我会计算色调在红色色调的某个增量内的像素数(通常在色轮上为0度)。你可能需要处理一些边缘情况,即亮度或饱和度太低,人类无法认为它们是红色的,尽管从技术上讲它们是红色,这取决于你想要实现的目标。

此解决方案不仅应解决红色问题,还应解决任何颜色分布:

  1. 获取ROI的颜色直方图,二维色调和饱和度直方图(按照这里的示例)
  2. 使用calcBackProject将直方图投影回完整图像。您将获得较大的像素值,这些值表示直方图的模式附近的颜色(在本例中为红色)
  3. 对结果设置阈值,以获得更匹配分布的像素(在本例中,为"最佳红色")

例如,该解决方案可用于获得一个简单但功能非常强大的皮肤检测器