直方图是像素数统计图,如设一张灰度图或一个通道,值是0~255。直方图如果按255个区分的话,统计出来的就是值为为0的有几个像素数,值为1的有机个像素数,这样的一张表。那么均衡化的意思就是,这样表要均衡,不至于值为0的有上万个像数,值为1的只有1 个。直方图均衡化是图像处理领域中利用图像直方图对对比度进行调整的方法。这种方法通常用来增加许多图像的局部对比度,尤其是当图像的有用数据的对比度相当接近的时候。通过这种方法,亮度可以更好地在直方图上分布。这样就可以用于增强局部的对比度而不影响整体的对比度,直方图均衡化通过有效地扩展常用的亮度来实现这种功能。
#include <opencv2/opencv.hpp>
#include <opencv2/legacy/compat.hpp>
void FillWhite(IplImage *pImage)
{
cvRectangle(pImage, cvPoint(0, 0), cvPoint(pImage->width, pImage->height), CV_RGB(255, 255, 255), CV_FILLED);
}
/// 创建灰度图像的直方图//
CvHistogram* CreateGrayImageHist(IplImage **ppImage)
{
int nHistSize = 256;
float fRange[] = {0, 255}; //直方图的范围
float *pfRanges[] = {fRange};
CvHistogram *pcvHistogram = cvCreateHist(1, &nHistSize, CV_HIST_ARRAY, pfRanges,1); /函数 cvCreateHist 创建一个指定尺寸的直方图,并且返回创建的直//方图的指针
cvCalcHist(ppImage, pcvHistogram,0,0); //用来计算一张或多张单通道图像的直方图,pcvHistogram是先前创建的空的直方图,ppImage是输入图像
return pcvHistogram;
}
根据直方图创建直方图图像
IplImage* CreateHisogramImage(int nImageWidth, int nScale, int nImageHeight, CvHistogram *pcvHistogram)
{
IplImage *pHistImage = cvCreateImage(cvSize(nImageWidth * nScale, nImageHeight), IPL_DEPTH_8U, 1);
FillWhite(pHistImage);
//统计直方图中的最大直方块
float fMaxHistValue = 0;
cvGetMinMaxHistValue(pcvHistogram, NULL, &fMaxHistValue, NULL, NULL); //发现最大直方快和最小直方快以及他们的位置,此处是发现最大直方快的高度。
//分别将每个直方块的值绘制到图中
int i;
for(i = 0; i < nImageWidth; i++)
{
float fHistValue = cvQueryHistValue_1D(pcvHistogram, i); //像素为i的直方块大小(像素为i的概率)
int nRealHeight = cvRound((fHistValue / fMaxHistValue) * nImageHeight); //要绘制的高度 ;cvRound:对一个double型的数进行四舍五入,并返回一个整型///数!
cvRectangle(pHistImage, //通过对角线上的两个顶点绘制简单、指定粗细或者带填充的矩形
cvPoint(i * nScale, nImageHeight-1 ),
cvPoint((i + 1) * nScale - 1, nImageHeight - nRealHeight),
CV_RGB(10, 70, 20)
);
}
return pHistImage;
}
int main( int argc, char** argv )
{
// 从文件中加载原图
IplImage *pSrcImage = cvLoadImage("d://aaa.jpg", CV_LOAD_IMAGE_UNCHANGED);
IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
IplImage *pGrayEqualizeImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
// 原图转化为灰度图
cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);
// 直方图图像数据
int nHistImageWidth = 255;
int nHistImageHeight = 150;
int nScale = 2;
// 灰度直方图及直方图图像
CvHistogram *pcvHistogram = CreateGrayImageHist(&pGrayImage); //生成灰度直方图
IplImage *pHistImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogram); //由直方图生成灰度直方图图像
// 均衡化
cvEqualizeHist(pGrayImage, pGrayEqualizeImage);
// 均衡化后的灰度直方图及直方图图像
CvHistogram *pcvHistogramEqualize = CreateGrayImageHist(&pGrayEqualizeImage); //生成均衡化的灰度直方图
IplImage *pHistEqualizeImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogramEqualize);//生成均衡化的灰度直方图图像
/显示图片代码///
cvNamedWindow( "原图", 1 );
cvShowImage("原图",pSrcImage);
cvNamedWindow( "灰度图", 1 );
cvShowImage("灰度图",pGrayImage);
cvNamedWindow( "直方图均衡化", 1 );
cvShowImage("直方图均衡化",pGrayEqualizeImage);
cvNamedWindow( "原图的直方图", 1 );
cvShowImage("原图的直方图",pHistImage);
cvNamedWindow( "均衡化之后的直方图", 1 );
cvShowImage("均衡化之后的直方图",pHistEqualizeImage);
cvWaitKey(0);
/// //回收资源代码///
cvReleaseImage(&pSrcImage);
cvReleaseImage(&pGrayImage);
cvReleaseImage(&pGrayEqualizeImage);
cvReleaseImage(&pHistImage);
cvReleaseImage(&pHistEqualizeImage);
cvDestroyWindow("原图");
cvDestroyWindow("灰度图");
cvDestroyWindow("直方图均衡化");
cvDestroyWindow("原图的直方图");
cvDestroyWindow("均衡化之后的直方图");
return 0;
}