您的位置:首页 > 编程语言 > C语言/C++

直方图均衡化原理和编码实现(C/C++)

2013-03-20 16:02 190 查看
原理:

直方图均衡化是通过灰度变换将一幅图像转换为另一幅具有均衡直方图,即在每个灰度级上都具有相同的象素点数的过程。

对图像 ,灰度范围为 ,其图像的直方图为 ,图像A的总像素点数为:



归一化:

概率密度函数为:



概率分布函数为:



设变换:



为斜率有限的非减连续可微函数,它将输入图像 转换为输出图像 。

输入图像的直方图为 与输出图像的直方图为 之间的关系可由如下过程导出



根据直方图的含义,经过灰度变换后对应的小面积元相等



解得:



其中:



所以,当 的分子分母只差一个比例常数时, 就恒定。即,



所以:



其中



为了使s的取值范围为[0, L] :

C = L

由此得,使直方图均衡化的灰度变换函数是概率分布函数。

在离散情况下



其中



为图像中总像素个数。

编码实现(OpenCV):

1. 计算图像直方图,并归一化

2. 计算变换函数 s=T(r)

3. 根据 s=T(r) 计算新的灰度值s

源码下载地址:http://download.csdn.net/detail/tommark/4654676

OpenCV源码:

/**********************************************************/

// 说明:直方图参考例程

// 作者:Mark

// 时间:6.4.2011

/**********************************************************/

#include<cv.h>

#include<highgui.h>

#include"histogram.h"

#defineDEPTH 256

int main(void)

{

IplImage *src = cvLoadImage("D:\\picture\\素材\\9.jpg", CV_LOAD_IMAGE_GRAYSCALE);

IplImage *dst = cvCloneImage(src);

// 显示原始图片

cvNamedWindow("src");

cvShowImage("src", src);

// 原始图像直方图

IplImage *srcHistImg = cvCreateImage(cvSize(256, 200), 8, 3);

cvSet(srcHistImg, CV_RGB(255, 255, 255));

plotHist1D(src, srcHistImg, CV_RGB(100, 100, 100)); // 画直方图

cvNamedWindow("srcHist");

cvShowImage("srcHist", srcHistImg);

// 1.计算直方图

int bins = DEPTH;

int sizes[] = {bins};

CvHistogram* hist = cvCreateHist(1, sizes, CV_HIST_ARRAY);

cvCalcHist(&dst, hist);

cvNormalizeHist(hist, 1); //归一化

// 2.计算变换函数s=T(r)

doubleval = 0.0;

uchar T[DEPTH] = {0};

for(int index = 0; index < DEPTH; index++)

{

val += cvQueryHistValue_1D(hist, index);

T[index] = (uchar)(val*255);

}

// 3.灰度变换

uchar* pPixelLine = NULL;

for(int x = 0; x < dst->height; x++) //列

{

pPixelLine = (uchar *)(dst->imageData + x*dst->widthStep);

for(int y = 0; y < dst->width; y++) //行

{

pPixelLine[y] = T[pPixelLine[y]];

}

}

// 显示直方图均衡化后图像

cvNamedWindow("dst");

cvShowImage("dst", dst);

// 直方图均衡化后图像的直方图

IplImage *dstHistImg = cvCreateImage(cvSize(256, 200), 8, 3);

cvSet(dstHistImg, CV_RGB(255, 255, 255));

plotHist1D(dst, dstHistImg, CV_RGB(100, 100, 100)); // 画直方图

cvNamedWindow("dstHist");

cvShowImage("dstHist", dstHistImg);

cvWaitKey(0);

cvReleaseImage(&src);

cvReleaseImage(&dst);

cvReleaseImage(&srcHistImg);

cvReleaseImage(&dstHistImg);

cvReleaseHist(&hist);

cvDestroyAllWindows();

return 0;

}

原始图片: 直方图:





直方图均衡化后结果: 直方图:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: