2014-02-21 44 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)

但是我個人認爲這是一個過沖(也比重寫算法效率低)。