2016-01-13 77 views
4

我有一个图像分成不同的区域相似,但其中一个有不同的亮度,我必须找出哪些区域有不同的亮度。不同亮度的区域

我在我的C++程序中使用OpenCV库。我将我的图像从RGB转换为HSV空间颜色。然后我测量了每个地区的全球平均值,但似乎并没有我想象的那么强劲。

下面的图像示出了示例:

任何建议?

+0

全球平均?这是什么 ? –

+0

通过提供一系列最小和最大HSV值进行全局阈值处理将是一个更好的选择,请访问此页面,其中有一个程序,它为H,S&V的所有值创建控制窗口并给出结果颜色,颜色与您所需的颜色 – udit043

+0

我的意思是平均在每个地区 – user5780012

回答

4

对不起,答案是使用Matlab,但方法应该很容易在C++中实现。

估计亮度通道和在0和1之间的归一化,则可以使用灰色通道,从HSV饱和信道,或者任何可以代表亮度:

L = mat2gray(mean(image, 3)); 

Luminance Channel

应用中值滤波器,以除去噪声和图像的黑色文物:

L_blur = medfilt2(L, [10 10]); 

Median Filter

使用Otsu的Thresholding计算阈值并应用于图像。这将有可能分裂的直方图两个部分分离明亮,较暗的区域:

output = uint8(repmat(mask, [1 1 3])) .* image; 

mask = L_blur > graythresh(L_blur); 

Binary Mask

然后,使用一个简单的元素方式乘法使用生成的二进制掩码来分割图像

Final Output

就是这样。

3

这是@Eliezer的great answer的OpenCV中的端口,仅用于完整性。

#include <opencv2/opencv.hpp> 
using namespace cv; 

int main() 
{ 
    Mat3b img = imread("path_to_image"); 

    // Estimate Luminance Channel 

    Mat1b L(img.rows, img.cols, uchar(0)); 
    for (int r = 0; r < img.rows; ++r) 
    { 
     for (int c = 0; c < img.cols; ++c) 
     { 
      Vec3b v = img(r,c); 
      L(r, c) = saturate_cast<uchar>((float(v[0]) + float(v[1]) + float(v[2]))/3.f); 
     } 
    } 

    // Apply a Median Filter 
    Mat1b L_blur; 
    medianBlur(L, L_blur, 11); 

    // Use OTSU threshold 
    Mat1b mask; 
    threshold(L_blur, mask, 0, 255, THRESH_BINARY | THRESH_OTSU); 

    // Segment image 
    Mat3b output(img.rows, img.cols, Vec3b(0,0,0)); 
    img.copyTo(output, mask); 


    imshow("Result", output); 
    waitKey(); 

    return 0; 
} 

结果:

enter image description here