本文转自:http://blog.csdn.net/hitwengqi/article/details/6897291
我们可以对图像做点事情尝试扩大其动态范围,对这个操作最常用的技术是直方图均衡化,可以将比较淡的图像变换为比较深的图像(即增强图像的亮度及对比度)。直方图均衡化后面潜在的数学原理是一个分布(输入的亮度直方图)被映射到另一个分布(一个更宽,理想统一的亮度值分布),映射函数是一个累积分布函数。对于连续分布,结果将是准确的均衡化。在cvEqualizeHist中,原始图像及目标图像必须是单通道,大小相同的8位图像,对于彩色图像,必须先将每个通道分开,再分别进行直方图均衡化处理,然后将通道合并形成新的图像。
----------------------------------------------------------------------------------------------
Split |
Split |
Merge |
Merge |
EqualizeHist
灰度图象直方图均衡化
void cvEqualizeHist( const CvArr* src, CvArr* dst);
src
输入的 8-比特 单信道图像
dst
输出的图像与输入图像大小与数据类型相同
函数 cvEqualizeHist 采用如下法则对输入图像进行直方图均衡化:
1.
2.
3.
4.
该方法归一化图像亮度和增强对比度。
EqualizeHist::EqualizeHist()
{
for (int i = 0; i<256; i++)
{
pixelArr[i] = 0;
sumPixelArr[i] = 0;
}
pixelMax = 0;
pixelMin = 256;
}
EqualizeHist::~EqualizeHist()
{
}
void EqualizeHist::process(Mat src, Mat& dst)
{
for (int i = 0; i<256; i++)
{
pixelArr[i] = 0;
sumPixelArr[i] = 0;
}
pixelMax = 0;
pixelMin = 256;
int width = src.cols;
int height = src.rows;
dst.create(Size(width,height),src.type());
for (int i = 0; i< height; i++)
{
for (int j = 0; j< width; j++)
{
pixelArr[src.at<uchar>(i,j)] += 1;
pixelMax = pixelMax>src.at<uchar>(i,j)?pixelMax:src.at<uchar>(i,j);
pixelMin = pixelMin<src.at<uchar>(i,j)?pixelMin:src.at<uchar>(i,j);
}
}
for (int i = 0; i< 256; i++)
{
pixelArr[i] /= width*height;
for (int j = 0; j<= i; j++)
{
sumPixelArr[i] += pixelArr[j];
}
}
for (int i = 0; i<height; i++)
{
for (int j = 0; j<width; j++)
{
int temp11 = src.at<uchar>(i,j);
float temp1 = sumPixelArr[temp11]*(pixelMax-pixelMin)+(pixelMin);
dst.at<uchar>(i,j) = temp1;
}
}
}
#include <highgui.h>
#include <cv.h>
int main(int argc, char** argv)
{
int i;
IplImage* src = cvLoadImage( argv[1], 1 );
IplImage* imgChannel[4] = { 0, 0, 0, 0 };
IplImage* dst = cvCreateImage( cvGetSize( src ), IPL_DEPTH_8U, 3 );
if( src )
{
for( i = 0; i < src -> nChannels; i++ )
{
imgChannel[i] = cvCreateImage( cvGetSize( src ), IPL_DEPTH_8U, 1 ); //要求单通道图像才能直方图均衡化
}
//通道分离
cvSplit( src, imgChannel[0], imgChannel[1], imgChannel[2], imgChannel[3] );
for( i = 0; i < dst -> nChannels; i++ )
{
//直方图均衡化,原始图像和目标图像必须是单通道
cvEqualizeHist( imgChannel[i], imgChannel[i] );
}
//通道组合
cvMerge( imgChannel[0], imgChannel[1], imgChannel[2], imgChannel[3], dst );
cvNamedWindow( "src", 1 );
cvShowImage( "src", src );
cvNamedWindow( "Equalize", 1 );
cvShowImage( "Equalize", dst );
cvWaitKey(0);
//释放资源
for( i = 0; i < src -> nChannels; i++ )
{
if( imgChannel[i] )
{
cvReleaseImage( &imgChannel[i] );
//imgChannel[i] = 0;
}
}
cvReleaseImage( &dst );
}
return 0;
}
source image
EqualizeHist image
由此看出,图像的亮度及对比度明显增强,画面感更强。