废话不多说,代码如下:
/*
假设我们读的都是8位的灰度图像
*/
#include <stdio.h>
#include <stdlib.h>
#include <cv.h>
#include <highgui.h>
/***************************************
bool generateHist(double* pdHist, int n)
功能:生成图像的灰度直方图
参数:IplImage* image: 要计算直方图的图片
double* pdHist: 输出的灰度直方图数组
int n: 灰度直方图的灰度级数
返回值:true 成功,false 失败
****************************************/
bool generateHist(IplImage* image, double* pdHist, int n)
{
if ((n <= 0) || (n > 256))
{
return false;
}
double divider = 256.0/(double)n;
int width = image->width;
int height = image->height;
int i = 0;
int j = 0;
unsigned char* data = (unsigned char*)(image->imageData);
unsigned char pixelByte;
double square = width * height;
memset(pdHist, 0, n*sizeof(double));
//统计灰度级中每个像素在整幅图像中的个数
for (i=0; i<height; i++)
{
for (j=0; j<height; j++)
{
pixelByte = data[i * image->widthStep + j];
pdHist[(int)(pixelByte/divider)]++;
}
}
for(i=0; i<n; i++)
{
pdHist[i] = pdHist[i]/square;
}
return true;
}
/**************************************
bool histEq(IplImage* image)
功能:图像的灰度直方图均衡化
参数:IplImage* image 要进行灰度直方图均衡化的图像指针
返回值:true 成功,false 失败
***************************************/
bool histEq(IplImage* image, IplImage* output)
{
if (image == NULL || output == NULL) return false;
if (image->depth != 8 || output->depth != 8) return false;
if (cvGetSize(image).height != cvGetSize(output).height ||
cvGetSize(image).width != cvGetSize(output).width)
return false;
if (image->nChannels != 1 || output->nChannels != 1) return false;
unsigned char pixelByte; //存储当前像素的灰度值
int target; //存储当前像素的目标值
double pdHist[256]; //存储灰度直方图
double temp; //存储累加的直方图概率数据
int i=0, j=0, k=0;
unsigned char* data = (unsigned char*)(image->imageData);
unsigned char* tData = (unsigned char*)(output->imageData);
if (!generateHist(image, pdHist, 256))
{
return false;
}
for (i=0; i<image->height; i++)
{
for (j=0; j<image->width; j++)
{
temp = 0;
pixelByte = data[i * image->widthStep + j];
for (k=0; k<pixelByte; k++)
{
temp += *(pdHist+k);
}
target = 255 * temp;
if (target < 0) target = 0;
if (target > 255) target = 255;
//写入目标图像
tData[i * image->widthStep + j] = target;
}
}
return true;
}
int main(int argc, char** argv)
{
IplImage* srcImage = cvLoadImage("D:\\OpenCV\\opencv\\sources\\samples\\c\\airplane.jpg", 0);
if (srcImage == NULL) return 1;
cvNamedWindow("sourceImage");
cvShowImage("sourceImage", srcImage);
IplImage* bImage = cvCreateImage(cvGetSize(srcImage), 8, 1);
if (srcImage == NULL) return 2;
if (histEq(srcImage, bImage))
{
cvNamedWindow("histEqImage");
cvShowImage("histEqImage", bImage);
}else{
printf("failed operation\n");
}
cvWaitKey(0);
cvReleaseImage(&srcImage);
cvReleaseImage(&bImage);
cvDestroyWindow("sourceImage");
cvDestroyWindow("histEqImage");
return 0;
}
然后直接上运行结果: