# 直方图均衡化

s=T(r) 0≤r≤1

T(r)满足下列两个条件：

（1）T(r)在区间0≤r≤1中为单值且单调递增

（2）当0≤r≤1时,0≤T(r) ≤1

Pr(r)是r的概率密度函数，Ps(s)是s的概 率密度函数，Pr(r)和T(r)已知，且T-1(s) 满足上述条件(1)，所以有

nk是图像中灰度级为rk的像素个数.

n是图像中像素的总数.

sk称作直方图均衡化 将输入图像中灰度级为rk（横坐标）的像素映射 到输出图像中灰度级为sk （横坐标）的对应像素得到.

实现代码：

/******************************************************************************
*    作用:            灰度均衡函数
*    参数:
*        pixel        原始像素数组
*        tempPixel    保存变换后图像的像素数组
*        width        原始图像宽度
******************************************************************************/
void GrayEqualize(BYTE* pixel, BYTE* tempPixel, UINT width, UINT height)
{

// 灰度映射表
BYTE map[256];
long lCounts[256];

memset(lCounts, 0, sizeof(long) * 256);

// 计算各灰度值个数
for (UINT i = 0; i < width * height; i++)
{
int x = pixel[i * 4];
lCounts[x]++;
}

// 保存运算中的临时值
long lTemp;

for (int i = 0; i < 256; i++)
{
lTemp = 0;
for (int j = 0; j <= i; j++)
lTemp += lCounts[j];

map[i] = (BYTE)(lTemp * 255.0f / width / height);
}

// 变换后的值直接在映射表中查找
for (UINT i = 0; i < width * height; i++)
{
int x = pixel[i * 4];

tempPixel[i*4] = tempPixel[i*4+1] = tempPixel[i*4+2] = pixel[i * 4];
tempPixel[i*4+3] = 255;
}
}
View Code

opencv代码：

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int main( int argc, const char** argv )
{

if (img.empty()) //if unsuccessful, exit the program
{
cout << "Image cannot be loaded..!!" << endl;
return -1;
}

vector<Mat> channels;
Mat img_hist_equalized;

cvtColor(img, img_hist_equalized, CV_BGR2YCrCb); //change the color image from BGR to YCrCb format

split(img_hist_equalized,channels); //split the image into channels

equalizeHist(channels[0], channels[0]); //equalize histogram on the 1st channel (Y)

merge(channels,img_hist_equalized); //merge 3 channels including the modified 1st channel into one image

cvtColor(img_hist_equalized, img_hist_equalized, CV_YCrCb2BGR); //change the color image from YCrCb to BGR format (to display image properly)

//create windows
namedWindow("Original Image", CV_WINDOW_AUTOSIZE);
namedWindow("Histogram Equalized", CV_WINDOW_AUTOSIZE);

//show the image
imshow("Original Image", img);
imshow("Histogram Equalized", img_hist_equalized);

waitKey(0); //wait for key press

destroyAllWindows(); //destroy all open windows

return 0;
}
View Code

代码中使用的函数：

New OpenCV functions

• cvtColor(img, img_hist_equalized, CV_BGR2YCrCb)
This line converts the color space of BGR in 'img' to YCrCb color space and stores the resulting image in 'img_hist_equalized'.

In the above example, I am going to equalize the histogram of color images. In this scenario, I have to equalize the histogram of the intensity component only, not the color components. So, BGR format cannot be used because its all three planes represent color components blue, green and red. So, I have to convert the original BGR color space to YCrCb color space because its 1st plane represents the intensity of the image where as other planes represent the color components.

• void split(const Mat& m, vector<Mat>& mv )
This function splits each channel of the 'm' multi-channel array into separate channels and stores them in a vector, referenced by 'mv'.

Argument list
• const Mat& m - Input multi-channel array
•  vector<Mat>& mv - vector that stores the each channel of the input array

• equalizeHist(channels[0], channels[0]);
Here we are only interested in the 1st channel (Y) because it  represents the intensity information whereas other two channels (Cr and Cb) represent color components. So, we equalize the histogram of the 1st channel using OpenCV in-built function, 'equalizeHist(..)' and other two channels remain unchanged.

• void merge(const vector<Mat>& mv, OutputArray dst )
This function does the reverse operation of the split function. It takes the vector of channels and create a single multi-channel array.
Argument list
• const vector<Mat>& mv - vector that holds several channels. All channels should have same size and same depths
• OutputArray dst - stores the destination multi-channel array

• cvtColor(img_hist_equalized, img_hist_equalized, CV_YCrCb2BGR)
This line converts the image from YCrCb color space to BGR color space. It is essential to convert to BGR color space because 'imshow(..)' OpenCV function can only show images with that color space.

This is the end of the explanation of new OpenCV functions, found in the above sample code. If you are not familiar with other OpenCV functions, please refer to the previous lessons.

参考博客：http://opencv-srf.blogspot.jp/2013/08/histogram-equalization.html

posted on 2016-12-11 20:01  yoyo_sincerely  阅读(48924)  评论(0编辑  收藏  举报