您的位置:首页 > 运维架构

opencv直方图均衡化

2012-02-14 16:22 204 查看
这个是自己的第一个blog,写一个opencv实现的灰度直方图均衡化,测试通过

转载请注明作者和出处,谢谢!

//////////////////////////////////////////////////////////////////////////
//project_name:gray image process:hist
//time:2012-02-14
//author:hellmonky
//////////////////////////////////////////////////////////////////////////
#include <opencv2/opencv.hpp>
#include<iostream>
#include <math.h>

using namespace std;
using namespace cv;

int main(int argc, char **argv)
{
IplImage* src=cvLoadImage(argv[1],CV_LOAD_IMAGE_GRAYSCALE);
//"C:\\Users\\hellmonky\\Desktop\\LeastSquaresMethod\\Debug\\1.bmp"
int width=src->width;
int height=src->height;
int sum = width*height;

int step=src->widthStep;
uchar* data=(uchar *)src->imageData;
int hist[256]={0};
int CalHist[256] = {0};
int CH[256] = {0};
int max1 = 0;
int max2=0;

//////////////////////////////////////////////////////////////////////////
//计算输入图像的灰度分布
//////////////////////////////////////////////////////////////////////////
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
hist[data[i*step+j]]++;
}
}
for(int i=0;i<256;i++)
{
if(hist[i]>max1)
{
max1=hist[i];
}
}
for (int i=0;i<256;i++)
{
for (int j=0;j<=i;j++)
{
CalHist[i] += (int)(255* (float)hist[j]/sum );
}
}
IplImage* dst1=cvCreateImage(cvSize(400,300),8,1);
cvSet(dst1,cvScalarAll(255),0);
double bin_width=(double)dst1->width/256;//建立比例因子
double bin_unith=(double)dst1->height/max1;
for(int i=0;i<256;i++)
{
CvPoint p0=cvPoint(i*bin_width,dst1->height);
CvPoint p1=cvPoint((i+1)*bin_width,dst1->height-hist[i]*bin_unith);
cvRectangle(dst1,p0,p1,cvScalar(1),-1,8,0);
}

//////////////////////////////////////////////////////////////////////////
//对原始图像进行重新计算
//////////////////////////////////////////////////////////////////////////
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
data[i*step+j] = CalHist[data[i*step+j]];
}
}

//////////////////////////////////////////////////////////////////////////
//计算变换以后的图像的灰度分布
//////////////////////////////////////////////////////////////////////////
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
CH[data[i*step+j]]++;
}
}
for(int i=0;i<256;i++)
{
if(CH[i]>max2)
{
max2=CH[i];
}
}
IplImage* you=cvCreateImage(cvSize(400,300),8,1);
cvSet(you,cvScalarAll(255),0);
double binwidth=(double)you->width/256;//建立比例因子
double binunith=(double)you->height/max2;
for(int i=0;i<256;i++)
{
CvPoint p0=cvPoint(i*binwidth,you->height);
CvPoint p1=cvPoint((i+1)*binwidth,you->height-CH[i]*binunith);
cvRectangle(you,p0,p1,cvScalar(1),-1,8,0);
}

cvShowImage("原始图像灰度分布",dst1);
cvSaveImage("原始图像灰度分布.bmp",dst1);

cvShowImage("直方图均衡化图像",src);
cvSaveImage("直方图均衡化图像.bmp",src);

cvShowImage("均衡化后直方图",you);
cvSaveImage("均衡化后直方图.bmp",you);

waitKey(0);
cvDestroyWindow("原始图像灰度分布");
cvDestroyWindow("直方图均衡化图像");
cvDestroyWindow("均衡化后直方图");
return 0;
}


原始灰度图像:



对应的直方图:



直方图均衡化以后的图像:



对应的直方图:



从两幅图像的直方图可以看出,直方图均衡化以后基本上对整个灰度范围都有一个覆盖,最理想的直方图均衡化以后的直方图效果应该是很均匀的灰度分布,即图像呈一条直线。

以上内容均为个人参考书籍,网络和自己实践理解得来,如有不对,请个位留言,谢谢支持!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息