2016-11-28 60 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

相关问题