直方图均衡化算法原理与实现
来源:互联网 发布:从事数据分析看什么书 编辑:程序博客网 时间:2024/05/21 02:34
工作后,对原来学习的一些基本图像处理算法有了一些新的认识,比如Canny 算法,直方图均衡化算法等,今天就来说说直方图均衡化算法。
直方图均衡化原理
我们知道提高图像对比度的变换函数
f(x) 在0<=x<=L−1 上单调递增(不要求严格单调递增),其中L表示灰度级(L=256)f(x) 的范围是[0,L−1]
我们知道当图像直方图完全均匀分布的时候,此时图像的熵是最大的(随机变量每个值的概率都相同时,概率最大),图像对比度是最大的。所以,理想情况下,图像经过变换函数
那问题来了?怎样的变换函数具有如此神奇的功能呢?[1]P74中给出了答案。
在图像处理中,有一个重要的函数,能够满足上面的条件:
英文原版中P145中的表述为:
其中
分布函数的两个性质:1.单调不减 2.值域为[0,1],我们可以知道f(x)满足条件1和2
有人可能会有这个疑问?图像是离散的,为什么可以用连续的来表示呢?从数学角度来看,离散是连续的一种特例(图像就是一个很好的例子)。
下面我们证明变换后的直方图是均匀的。
由概率论知识,变换后的概率密度:
由变上限函数求导法则可知
反函数的导数等于原函数导数的倒数,所以
所以
看到了吧,变换后的概率密度函数是一个均匀分布,对于图像来说,就是每个灰度级概率都是相等的,达到了我们的目的。
下面我们需要将这个变换函数转换为图像中的表达,图像中,我们可以知道,可以使用求和代替积分,差分代替微分,所以上述的变换函数就是:
其中
直方图均衡化算法实现
根据上面的推导,算法实现如下:
//不支持OpenCV的ROIvoid GetHistogram(const Mat &image, int *histogram){ memset(histogram, 0, 256 * sizeof(int)); //计算直方图 int pixelCount = image.cols*image.rows; uchar *imageData = image.data; for (int i = 0; i <= pixelCount - 1; ++i) { int gray = imageData[i]; histogram[gray]++; }}void EqualizeHistogram(const Mat &srcImage, Mat &dstImage){ CV_Assert(srcImage.type() == CV_8UC1); dstImage.create(srcImage.size(), srcImage.type()); // 计算直方图 int histogram[256]; GetHistogram(srcImage, histogram); // 计算分布函数(也就是变换函数f(x)) int numberOfPixel = srcImage.rows*srcImage.cols; int LUT[256]; LUT[0] = 1.0*histogram[0] / numberOfPixel*255; int sum = histogram[0]; for (int i = 1; i <= 255; ++i) { sum += histogram[i]; LUT[i] = 1.0*sum / numberOfPixel * 255; } // 灰度变换 uchar *dataOfSrc = srcImage.data; uchar *dataOfDst = dstImage.data; for (int i = 0; i <= numberOfPixel - 1; ++i) dataOfDst[i] = LUT[dataOfSrc[i]];}
原图
测试结果:
从直方图均衡化算法中,可以看出,看似简单的几个算法步骤,背后蕴藏了很多数学理论知识,计算机视觉很多算法的背后都是强大的数学,这大概就是数学的魅力吧。
2016-9-3 10:41:39
参考文献
- 《数字图像处理》第3版,冈萨雷斯
非常感谢您的阅读,如果您觉得这篇文章对您有帮助,欢迎扫码进行赞赏。
- 直方图均衡化算法原理与实现
- 直方图均衡化算法原理与实现
- 直方图均衡化原理与实现
- 直方图均衡化算法原理详解
- 直方图均衡化原理及实现
- 直方图均衡化原理
- 直方图均衡化原理
- 直方图均衡化原理
- 直方图均衡化原理
- 直方图均衡化原理
- 直方图均衡化原理
- 直方图均衡化原理
- 直方图均衡化原理
- 直方图均衡化原理
- 直方图均衡化原理
- 直方图均衡化原理
- 直方图均衡化原理
- 直方图均衡化原理
- MySQL存储过程
- 端到端深度学习在自动驾驶汽车上的应用
- javascript中浮点数相加的一些细节
- c3p0数据库连接池的使用详解
- iOS7新技术:如何使用Multipeer Connectivity
- 直方图均衡化算法原理与实现
- 【NOIP】普及组 2014 问题求解
- Android开发环境搭建
- Java学习笔记之对象传值和引用总结
- 字符串的全排列问题
- Redis探索之旅(1)- Redis初识
- 判断字符串中的括号是否匹配
- POJ 3041 Asteroids(二分图匹配)
- BZOJ 1002 轮状病毒(生成树计数+高精度)