2016-11-28 67 views
1

我想一個MATLAB代碼翻譯成C++ OpenCV的,它的閾值的RGB圖像:紅色值>閾值1和紅/綠>閾值2和紅色/藍色>閾值3如何高效地使用opencv在RGB圖像中執行復雜閾值?

的MATLAB代碼是:

bw=(im(:,:,1)>=red_th&(im(:,:,1)./im(:,:,2))>=red_green_th&(im(:,:,1)./im(:,:,3))>=red_blue_th); 

其中im(:,:,1), im(:,:,2)im(:,:,3)分別是r,g,b值。

我發現matlab代碼與使用「for cols and for rows」循環所有像素相比非常高效。因此,我想在opencv中找到類似的有效方法,而不是循環使用cols和rows。

我看了一些關於cv::threshold and inRange的信息,但是看起來他們不能滿足我的要求。

回答

2

不能直接與thresholdinRange做到這一點,但你可以很容易地將它轉換爲OpenCV的第一剖開的3個通道,然後用矩陣表示:

Mat im = ... 
vector<Mat> planes; 
split(im, planes); // B, G, R planes 

Mat bw = (planes[2] >= red_th) & 
     (planes[2]/planes[1] >= red_green_th) & 
     (planes[2]/planes[0] >= red_blue_th); 

由於Matlab的通常工作於雙打,你最好轉換OpenCV的矩陣翻番(除非它們已經如此):

Mat im = ... 
vector<Mat> planes; 
split(im, planes); // B, G, R planes 

for(size_t i=0; i<planes.size(); ++i) { 
    planes[i].convertTo(planes[i], CV_64F); 
} 

Mat bw = (planes[2] >= red_th) & 
     (planes[2]/planes[1] >= red_green_th) & 
     (planes[2]/planes[0] >= red_blue_th); 

也可以爲環,它可以是,如果你在工作的指針非常快的(我假設你im我s的CV_8UC3):

Mat3b im = ... 
Mat1b bw(im.rows, im.cols, uchar(0)); 

int rows = im.rows; 
int cols = im.cols; 
if(im.isContinuous()) { 
    cols = rows * cols; 
    rows = 1; 
} 

for(int r=0; r<rows; ++r) { 
    Vec3b* ptr_im = im.ptr<Vec3b>(r); 
    uchar* ptr_bw = bw.ptr<uchar>(r) 
    for(int c=0; c<cols; ++c) { 
     const Vec3b& bgr = ptr_im[c]; 

     // Take care of division by 0 

     ptr_bw[c] = (bgr[2] >= red_th) && 
        (bgr[2]/bgr[1] >= red_green_th) && 
        (bgr[2]/bgr[0] >= red_blue_th); 
    } 
} 
+0

它的工作原理。非常感謝! –

+0

很高興幫助; D – Miki

+0

可能您對該類型有一些問題。 Matlab中的矩陣通常是double類型的,而在OpenCV中它們可能是'uchar'類型。如果這是一個問題整數除法,你需要將OpenCV矩陣轉換爲前兩倍 – Miki

相關問題