2014-02-21 50 views
0

我试图使用cv :: InRange()与HSV图像。因为色调值是循环的,所以我需要处理最小/最大值,其中最小色调可能大于最大色调值。到目前为止,我用下面的代码来计算范围掩码:HSV中的循环色调范围的高效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; 
} 

但是这种解决方案需要两次在其他情况下,时间(与优化版本)。我认为可以有更高效的代码来反转范围或以某种方式反转图像。但由于我使用的是全高清晰度范围,而不仅仅是色调通道,我还没有找到更好的解决方案。

在hsv范围内计算像素会更有效吗?我相信有人已经有这个问题的一个很好的解决方案。使用openCV函数或重写算法?

回答

1

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

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

  1. 使用cv::split

  2. 适用inRange三个渠道,并得到maskH缝通道图像的{hchan,schan,vchan} ,maskS,maskV

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

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