我正在尝试使用 OpenCV 对视频流中的红色像素进行阈值处理。我有其他颜色工作得很好,但红色会带来问题,因为它环绕色相轴(即 HSV(0, 255, 255) 和 HSV(179, 255, 255) 都是红色的)。我现在使用的技术不太理想。基本上:
cvInRangeS(src, cvScalar(0, 135, 135), cvScalar(20, 255, 255), dstA);
cvInRangeS(src, cvScalar(159, 135, 135), cvScalar(179, 255, 255), dstB);
cvOr(dstA, dstB, dst);
这是次优的,因为与简单的蓝色情况相比,它需要在代码中为红色(潜在错误)分支、分配两个额外图像和两个额外操作:
cvInRangeS(src, cvScalar(100, 135, 135), cvScalar(140, 255, 255), dst);
我想到的更好的选择是“旋转”图像的颜色,使目标色调为 90 度。例如。
int rotation = 90 - 179; // 179 = red
cvAddS(src, cvScalar(rotation, 0, 0), dst1);
cvInRangeS(dst1, cvScalar(70, 135, 135), cvScalar(110, 255, 255), dst);
这使我可以类似地对待所有颜色。
但是,当cvAddS
色调值低于 0 时,该操作不会将色调值回绕回 180,因此您会丢失数据。我看着将图像转换为,CvMat
以便我可以从中减去,然后使用模数将负值包装回范围的顶部,但CvMat
似乎不支持模数。当然,我可以遍历每个像素,但我担心这会很慢。
我已经阅读了许多教程和代码示例,但它们似乎都方便地只查看不环绕色调光谱的范围,或者使用更丑陋的解决方案(例如,cvInRangeS
通过迭代每个像素并执行与颜色表进行手动比较)。
那么,解决这个问题的常用方法是什么?最好的方法是什么?各自的取舍是什么?迭代像素是否比使用内置 CV 函数慢得多?