图像处理之直方图均衡化

来源:互联网 发布:卫龙辣条淘宝旗舰店 编辑:程序博客网 时间:2024/04/26 09:19

前几天买了一本书《数字图像处理》,准备按照这本书开始学习。

数学原理

这次我们以一个单通道的灰度图像来解释什么是直方图均衡化。

灰度直方图

要解释什么是直方图均衡化,首先要解释下灰度直方图。我们很容易知道一张灰度图像是分灰度级
的,灰度级用通俗的话来说就是颜色深度,我们通常听说的8位图像和16位图像等,就是将灰度分为2^8次方即256个灰度级和2^16个灰度级。
在这里我们以3位图像为例,一个3位灰度图像有8灰度级,整张图片的每个点的像素值都在这个闭区间里(灰度是整数)。那么我们用统计的思想很容易联想到什么是灰度直方图,就是:一种统计每个灰度值出现在整张图片中的次数的之直方图。
0 2 5 6
1 2 4 5
1 3 3 0
那么我们可以得到这样一个灰度概率p(i),i表示灰度级,p表示概率:
p(0)=2/12=0.167
p(1)=2/12=0.167
以此类推p(2)=0.167,p(3)=0.167,p(4)=0.083,p(5)=0.167,p(6)=0.083,p(7)=0。我们得到这个表格。
这里写图片描述

直方图均衡化

假设源图像为A,直方图均衡化后的目标图像为B,那么对于B中新的灰度值Sk有:
这里写图片描述
其中Sk是均衡化后的新图像的灰度值,L表示源图像的灰度级(上面的例子中L=8),k表示在源图像
中的灰度值,nj表示源图像第j个灰度值出现的个数,MN表示源图像像素的总个数。
以上面的数据为例,新的图像B中B(1,2)(第一行第二列)的灰度值为:
S(1,2)=(8-1)/(3*4)*(2+2+2)=3.5=3 (这里要求离得最近的值,比如3.4=3,3.6=4)
那么新的图像可以是这样:
1 3 6 7
2 3 5 5
2 5 5 1
这就是经过均衡化后的直方图。

直方图均衡化作用

可以提升图像的对比度,注意:当图像灰度值扩展到了全部灰度级时,效果只是个线性变换,视觉上
变化不大。

程序实现

/********************************************功能:灰度图片对直方图均衡化后的效果展示*************************************/#include <opencv2\opencv.hpp>#include <opencv2\highgui\highgui.hpp>#include <iostream>using namespace std;using namespace cv;int main(){    Mat imageBuf = imread("lena.jpg");    if (imageBuf.empty()){        cout << "image read error!";    }    Mat imageGray(imageBuf.rows, imageBuf.cols, CV_8UC1);    cvtColor(imageBuf, imageGray, CV_BGR2GRAY);//获得灰度图像    namedWindow("sourceImage", WINDOW_NORMAL);    imshow("sourceImage", imageGray);    imwrite("imageGray.jpg", imageGray);    float p[256];//灰度级    float n = imageGray.rows*imageGray.cols;//像素总个数    for (int i = 0; i < 256; i++){        p[i] = 0.0;    }    for (int i = 0; i < imageGray.rows; i++){        for (int j = 0; j < imageGray.cols; j++){            p[imageGray.at<uchar>(i, j)] = p[imageGray.at<uchar>(i, j)] + 1;//统计每个灰度级包含多少个像素        }    }    for (int i = 0; i < 256; i++){        p[i] = p[i] / n;//每种灰度级的概率    }    for (int i = 0; i < imageGray.rows; i++){        for (int j = 0; j < imageGray.cols; j++){            int gray = imageGray.at<uchar>(i, j);            float gray_new = 0;            for (int k = 0; k < gray; k++){                gray_new += p[k];            }            gray_new = gray_new * 256 -1;            if ((gray_new - int(gray_new)) > 0.5)                gray_new = int(gray_new);            else                gray_new = int(gray_new) + 1;            imageGray.at<uchar>(i, j) = uchar(gray_new);        }    }    namedWindow("resultImage", WINDOW_NORMAL);    imshow("resultImage", imageGray);    imwrite("grayResult.jpg", imageGray);    waitKey(0);    return 0;}

效果展示

源图像

直方图均衡化结果

可以看到,直方图均衡化确实提高了图像的对比度

0 0
原创粉丝点击