数字图像处理之直⽅图均衡化
直⽅图均衡化
是图像处理领域中利⽤图像直⽅图对对⽐度进⾏调整的⽅法。
直⽅图均衡化要达到的效果:
基本思想:把原始图的直⽅图变换为均匀分布的形式,这样就增加了像素灰度值的动态范围,从⽽达到增强图像整体对⽐度的效果使⽤的⽅法是灰度级变换:s = T(r)
原理:
s=T(r) 0≤r≤1
T(r)满⾜下列两个条件:
(1)T(r)在区间0≤r≤1中为单值且单调递增
(2)当0≤r≤1时,0≤T(r) ≤1
条件(1)保证原图各灰度级在变换后仍保持从⿊到⽩(或从⽩到⿊)的排列次序
条件(2)保证变换前后灰度值动态范围的⼀致性
Pr(r)是r的概率密度函数,Ps(s)是s的概率密度函数,Pr(r)和T(r)已知,且T-1(s) 满⾜上述条件(1),所以有
已知⼀种重要的变换函数:
喷绘纹身
关于上限的定积分的导数就是该上限的积分值(莱布尼茨准则)
对于离散值:
其中r k 是第k个灰度级,k = 0,1,2,…,L-1.
n k是图像中灰度级为r k的像素个数.
n是图像中像素的总数.
已知变换函数的离散形式为:
sk称作直⽅图均衡化将输⼊图像中灰度级为rk(横坐标)的像素映射到输出图像中灰度级为sk (横坐标)的对应像素得到.实现代码:
/******************************************************************************
* 作⽤: 灰度均衡函数
* 参数:
考妣电影
* pixel 原始像素数组
* tempPixel 保存变换后图像的像素数组
* width 原始图像宽度
******************************************************************************/
void GrayEqualize(BYTE* pixel, BYTE* tempPixel, UINT width, UINT height)
{
// 灰度映射表
BYTE map[256];
long lCounts[256];
memt(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 )
{
Mat img = imread("MyPic.JPG", CV_LOAD_IMAGE_COLOR); //open and read the image
if (pty()) //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政史地
return0;
}
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 ud becau its all three planes reprent color components blue, green and red. So, I have to convert the original BGR color space to YCrCb color space becau its 1st plane reprents
the intensity of the image where as other planes reprent the color components.
void split(const Mat& m, vector<Mat>& mv )
This function splits each channel of the 'm' multi-channel array into parate 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) becau it reprents the intensity information whereas other two channels (Cr and Cb) reprent 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 rever 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 veral 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 esntial to convert to BGR color space becau '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, plea refer to the previous lessons.
参考博客:opencv-srf.blogspot.jp/2013/08/histogram-equalization.html