我试图将cv :: InRange()与HSV图像一起使用。因为色调值是循环的,所以我需要处理最小/最大值,其中最小色调可能大于最大色调值。到目前为止,我使用以下代码来计算范围掩码:
cv::Mat InRangeMask(const cv::Mat &hsv, cv::Scalar min, cv::Scalar max)
{
cv::Mat rangeMask;
if(min[0]<=max[0])
{
cv::inRange(hsv, min, max, rangeMask);
}
else
{
cv::Mat rangeMask2;
cv::Scalar min1(0, min[1], min[2]);
cv::Scalar max1(min[0], max[1], max[2]);
cv::Scalar min2(max[0], min[1], min[2]);
cv::Scalar max2(179, max[1], max[2]);
cv::inRange(hsv, min1, max1, rangeMask);
cv::inRange(hsv, min2, max2, rangeMask2);
rangeMask |= rangeMask2;
}
return rangeMask;
}
但是这个解决方案在else情况下需要两倍的时间(在优化发布中)。我认为可以有更高效的代码来反转范围或以某种方式反转图像。但由于我使用完整的hsv系列而不仅仅是色调通道,我还没有找到更好的解决方案。
用于计算hsv范围内像素的更有效实现是什么?我确定有人已经有一个很好的解决方案来解决这个问题。使用openCV函数还是重写算法?
答案 0 :(得分:1)
您始终可以重写算法,这对于函数inRange
来说并不复杂。
另一种解决方案可能是在inRange
时使用min[0]<=max[0]
,否则请执行以下操作:
使用{hchan,schan,vchan}
cv::split
个频道
将inRange
应用于三个频道并获取maskH,maskS,maskV
inRange(hchan,max[0],min[0],maskH)
inRange(schan,min[1],max[1],maskS)
inRange(vchan,min[2],max[2],maskV)
重新组合这三个面具
bitwise_and(maskS,maskV,rangeMask)
bitwise_not(maskH,maskH)
bitwise_and(maskH,rangeMask)
但我个人认为这是一个过冲(并且比重写算法效率低)。