直方图均衡化在图像处理领域中运用非常广泛,而且非常简单易实现。
首先我们了解一下什么是图像的直方图:
设图像的灰度范围为[a,b],r为此灰度范围内的任一灰度级,p(r)为这幅图像中灰度级为r的像素出现的频率,可以看出p(r)是r的函数。该函数的图形称为这幅图像的直方图。
p(r)=灰度为r的像素数/图像上的总像素数
图像灰度级统计信息
图像灰度直方图
原灰度图 灰度直方图
可以很清楚地看出,灰度直方图抛弃了原灰度图像的空间位置信息,反映了某一像素值在灰度图中出现的频率或者概率信息。如上图所示,可以很清楚地看出0-100灰度值所出现的频率非常大,且越趋近于0概率越高;而灰度值大于200后,出现频率大大降低。由此可以判断出,该图像整体较暗,细节部分不够突出。
于是这里我们引入---直方图均衡化的方法,希望按照一定的变换公式,将原图映射到新图,使得新图在原图的基础上,直方图分布更加均匀,这样图像的明暗分布更加均匀,给人的视觉效果就是对比度好,细节清晰。
那么问题的关键是,如何确定这个变换公式呢?
均衡化方法中,使用直方图的累积分布函数作为变换公式:
其中,
实际上就是用某灰度级的累积概率来代替其原出现概率,得到映射后新的灰度值(累积概率乘以最大灰度值)。
举个例子来说:
rk代表原图的八个灰度级;nk代表每个灰度级出现的频数;Prk代表每个灰度级出现的概率;Sk代表累积概率;Ps代表新图中rk所对应的出现概率。
于是,很容易得到,例如:
原图rk=0,累积概率Sk=1/7,于是其对应的新图灰度值为1*1/7=1/7。
经过意义映射之后,可以发现,新图中灰度级为0的出现概率为0,于是在rk=0时Ps=0;新图中灰度级为1/7的出现概率为0.19,于是在rk=1/7时Ps=0.19···
以此类推,很容易换算出新图的灰度级。
了解了直方图均衡化的原理,那么编程实际上就是小菜一碟了。无论是使用Matlab还是OpenCV,直方图均衡化都很好实现。这里要提一点的就是Matlab相对来说更加地方便,对于直方图的获取与绘制,都有现成的函数可供调用,而OpenCV相对来说麻烦一点,需要自己写绘制函数。
另外,对输入进来的图像,首先要进行通道数的转换,比如说传入进来的是.jpg格式的图像,那么无论从外表上看它是不是一个灰度图像,读进来的都是三通道图像,所以,往往第一步是需要将多通道图像转换成单通道图像。
效果:
原图 均衡化后
核心函数(来源于网络,我是大自然的搬运工)
1.直方图均衡化
void MyEqualizeHist_color(IplImage* src, int color) { if (color == 1) {//多通道 IplImage* imgChannel[4] = { 0, 0, 0, 0 }; IplImage* dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3); int i; 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]);//BGRA 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); } else {//单通道 IplImage* dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); cvEqualizeHist(src, dst); cvNamedWindow("src", 1); cvShowImage("src", src); cvNamedWindow("Equalize", 1); cvShowImage("Equalize", dst); } }
2.绘制灰度直方图(单通道灰度图像)
IplImage* src = cvLoadImage("orange.JPG");//读取图像 IplImage* gray = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); cvCvtColor(src, gray, CV_BGR2GRAY);//彩色图像灰度化 CvHistogram *pcvHistogram = CreateGrayImageHist(&gray);//创建一个灰度直方图 int nHistImageWidth = 255; //0到255个灰度级 int nHistImageHeight = 200; //直方图图像高度 int nScale = 2; IplImage* pHistImage = CreateHisogramImage(nHistImageWidth, nScale,nHistImageHeight, pcvHistogram);//得到灰度直方图 cvNamedWindow("Hist", 1); cvShowImage("Hist", pHistImage); /**** FillWhite是一个填充函数,将pImage填充成白色 *****/ 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);//创建直方图 cvCalcHist(ppImage, 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的直方块大小 int nRealHeight = cvRound((fHistValue / fMaxHistValue) * nImageHeight); //要绘制的高度 cvRectangle(pHistImage, cvPoint(i * nScale, nImageHeight - 1), cvPoint((i + 1) * nScale - 1, nImageHeight - nRealHeight), cvScalar(i, 0, 0, 0), CV_FILLED ); } return pHistImage; }
相关推荐
通过以上步骤,我们不仅可以直观地观察到图像均衡化前后的效果差异,而且还可以深入理解直方图均衡化的实现原理。这种实践不仅有助于加深对图像处理技术的理解,还能够提高在实际项目中的应用能力。
本实验由北京交通大学计算机学院的阮秋琦教授指导,旨在让学生掌握C语言实现直方图均衡化的原理与方法。 直方图是描述图像中像素强度分布的一种统计图形,每个强度值对应的柱高表示该强度值出现的频次。在图像对比...
直方图均衡化是图像处理领域中一种非常重要的技术,主要用于改善图像的对比度,尤其在处理低对比度图像时效果显著。...通过深入理解直方图均衡化原理,并结合编程实践,我们可以有效地提升图像处理的性能和效果。
在图像处理领域,直方图均衡化是一种常用的增强...总之,这个压缩包提供的代码是理解直方图均衡化原理和实践C++编程的好材料。通过阅读和运行这段代码,你可以更好地掌握这一图像处理技术,并将其应用到自己的项目中。
本文详细介绍了彩色图像直方图均衡化的原理及其实现方法,并基于给定的C语言代码片段进行了具体的分析。通过理解这些原理和步骤,开发者可以在自己的项目中灵活运用直方图均衡化技术,提高图像处理的效率和效果。...
本篇文章将深入探讨直方图均衡化的原理、C++代码实现以及OpenCV库的应用。 直方图均衡化是通过对图像的像素值进行重新映射来改变其灰度级分布,从而达到扩大图像动态范围的目的。在灰度图像中,如果图像的像素值...
下面将详细阐述直方图均衡化的基本原理、MATLAB中的实现方法以及如何利用MATLAB进行图像处理实践。 ### 直方图均衡化的原理 直方图均衡化是一种非线性的点运算,通过调整图像像素值分布来增强图像的对比度。它的...
根据给定的文件信息,我们可以总结...通过以上内容,我们了解了直方图均衡化和规定化的原理及其在MATLAB中的具体实现方法。这些技术对于改善图像质量、提高图像对比度具有重要意义,在图像处理领域有着广泛的应用前景。
下面将详细阐述直方图均衡化的原理、步骤以及如何在VC6.0中进行实现。 直方图均衡化是一种统计方法,通过改变图像的灰度级分布,使得图像的整体亮度和对比度得到改善。在灰度图像中,直方图表示了每个灰度级出现的...
本主题主要关注“灰度直方图均衡化”及其在“图像去模糊”中的应用,这些概念将在MATLAB环境中进行阐述。 首先,我们要理解什么是直方图均衡化。在数字图像中,直方图表示像素强度分布,它展现了图像中不同灰度级...
下面,我们将深入探讨直方图均衡化的数学原理及其在OpenCV中的实现。 #### 原理概述 对于一幅灰度图像\(A(x,y)\),其灰度范围通常设定为\([0,L]\)。该图像的直方图表示为\(H_A(r)\),其中\(r\)是灰度级。图像\(A\)...
### 直方图均衡化原理及MATLAB实现 #### 实验背景 数字图像处理作为计算机视觉领域的基础之一,在模式识别、图像分析等多个方面发挥着重要作用。直方图均衡化是一种常用的图像增强技术,用于改善图像对比度,从而...
在这个主题中,我们将深入探讨直方图均衡化的概念、工作原理,以及如何在Visual Studio 2010环境下进行实现。 直方图是描述图像像素亮度分布的统计图形,它将图像中所有像素值的出现频率以条形图的形式展示出来。在...
在MATLAB中,有多种实现直方图均衡化的办法,以下介绍三种方法: 1. **第一种方法**: 这种方法首先读取图像,然后计算每个灰度级出现的频率,形成原图像的直方图。接着计算累积分布函数(CDF),即直方图的累计...
直方图均衡化是一种常用且有效的图像增强技术,其基本原理是通过增强图像的对比度来改善图像的视觉效果。这种技术属于数字图像处理领域中的空间域增强方法,主要通过对图像像素的直接操作,采用线性或非线性的变换来...
在VC++环境中实现直方图均衡化,可以帮助开发者深入理解图像处理原理,并提高编程技能。以下是对直方图均衡化及其在VC++中实现的详细解释: 直方图均衡化的基本概念: 直方图是描述图像中像素分布的统计图形,每个...
直方图均衡化的原理是基于概率论的,假设原始图像的灰度直方图分布是不均匀的,那么通过某种变换函数,将这个分布转换为一个更均匀的分布。这样,原本在暗部或亮部细节较少的图像,经过处理后,这些区域的细节可以...
"基于直方图均衡化的彩色图像增强在 Matlab 中的实现" MatLab 是一种功能强大的开发语言,广泛应用于图像处理、信号处理、数据分析等领域。本文档介绍了基于直方图均衡化的彩色图像增强技术在 Matlab 中的实现。 ...
下面将详细阐述直方图均衡的基本原理及其在MFC中的实现步骤。 直方图均衡化的核心思想是通过对图像的灰度级分布进行变换,使得新的图像具有更均匀的直方图分布。这种变换可以有效扩展图像的动态范围,从而提高整体...