HSV 中的高效范围,具有循环色调范围



我正在尝试将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 函数还是重写算法?

您可以随时重写算法,这对于函数inRange来说并不复杂。

另一种解决方案可能是在min[0]<=max[0]时简单地使用 inRange,否则执行以下操作:

  1. 使用cv::split切开图像{hchan,schan,vchan}通道

  2. inRange应用于三个通道并获得掩码H,掩膜S,掩模V

    • inRange(hchan,max[0],min[0],maskH)
    • inRange(schan,min[1],max[1],maskS)
    • inRange(vchan,min[2],max[2],maskV)
  3. 像这样重新组合三个面具

    • bitwise_and(maskS,maskV,rangeMask)
    • bitwise_not(maskH,maskH)
    • bitwise_and(maskH,rangeMask)

但我个人认为这是一种超调(而且效率也低于重写算法)。

最新更新