图像处理:白化

转载自:https://blog.csdn.net/qq_38906523/article/details/79853984

我们从逐像素处理来开始讲诉图像预处理。我们将代表原始图像的二维矩阵标记为,其中的代表第行和第列的像素值,代表该像素点的灰度强度。逐像素处理返回的就是和尺寸大小一样包含的二维矩阵。

Whitening(白化处理)

一幅图像最终成像会受环境照明强度、物体反射、拍摄相机等多因素的影响。为了能获得图像中包含的那些不受外界影响的恒定信息,我们需要对图像进行白化处理。(图像白化(whitening)可用于对过度曝光或低曝光的图片进行处理,处理的方式就是改变图像的平均像素值为 0 ,改变图像的方差为单位方差 1。)一般为了去除这些因素的影响,我们将它的像素值转化成零均值和单位方差。所以我们首先计算原始灰度图像的像素平均值和方差值。 

接下来我们将使用和来对原始灰度图像的每个像素值进行转化: 

对于彩色图像,我们需要在三个通道分别计算和,然后根据公式(3)分别进行像素转化。 
当然这种简单的转换可能会妨碍之后的图像处理,因为这些去除的信息有可能就是我们接下来需要的。 
下面我们通过一段代码来展示一下白化处理的效果。


OpenCV 实现

用 OpenCV 的内置函数计算均值和方差,然后对遍历每个像素值并对每个像素做变换。这里需要注意的是变换后的像素值肯定是有一部分会是负值(小于均值的那部分),我们需要把变换后的像素值重新映射到 [0, 255] 的范围内。因为 OpenCV 中的 normalize 函数无法实现这种任意范围内的映射,我们需要自己去实现这类映射。我们需要找出变换后图像中的最小 min 和最大像素值 max, 假设需要映射的范围为 [a, b]。 该映射可用函数(b-a)*(xij-min)/(max-min) 实现。关键部分实现代码如下所示:
 

 void whitening() {
     Mat image = imread("test.jpg",IMREAD_GRAYSCALE);
 
     double mean, stddev;
     Mat temp_m, temp_sd;
     meanStdDev(image, temp_m, temp_sd);
     mean = temp_m.at<double>(0, 0)/255.0;
     stddev = temp_sd.at<double>(0, 0)/255.0;
     Mat temp_image( image.rows, image.cols, CV_64F);
     for (int i = 0; i < image.rows; i++)
         for (int j = 0; j < image.cols; j++) {
             double pixelVal = image.at<uchar>(i, j)/255.0;
             double temp = (pixelVal - mean) / stddev;
             temp_image.at<double>(i, j) = temp;
         }
 
     double max, min;
     minMaxLoc(temp_image, &min, &max);
     for (int i = 0; i < image.rows; i++)
         for (int j = 0; j < image.cols; j++) {
             double pixelVal = temp_image.at<double>(i, j);
             image.at<uchar>(i, j) = (uchar)round(255.0 * (pixelVal - min) / (max - min));
         }
 
     imshow("New Image", image);
    waitKey(0);
 }

结果

如下图所示,可以看到对左边过度曝光的图片经过白化处理后图片的曝光程度减弱了。再看图像直方图,白化变换似乎是对原来的直方图做了一个横向的拉伸,使得像素值的分布更加的均匀,而不是集中在一个有限的(高曝光的)范围内。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值