首页 文章

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

提问于
浏览
0

我正在尝试使用带有HSV图像的cv :: InRange() . 因为色调值是循环的,所以我需要处理最小/最大值,其中最小色调可能大于最大色调值 . 到目前为止,我使用以下代码来计算范围掩码:

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函数还是重写算法?

1 回答

  • 1

    你总是可以重写算法,这对函数 inRange 来说并不复杂 .

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

    • 使用 cv::split 切割图像的通道 {hchan,schan,vchan}

    • 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)

    但我个人认为这是一个过冲(并且比重写算法效率低) .

相关问题