基于直方图的图像增强算法(HE、CLAHE、Retinex)之(一)

http://blog.csdn.net/baimafujinji/article/details/50614332

直方图是图像色彩统计特征的抽象表述。基于直方图可以实现很多有趣的算法。例如,图像增强中利用直方图来调整图像的对比度、有人利用直方图来进行大规模无损数据隐藏、还有人利用梯度直方图HOG来构建图像特征进而实现目标检测。本节我们就来讨论重要的直方图均衡化算法,说它重要是因为以此为基础后续又衍生出了许多实用而有趣的算法。

Histogram equalization

如果一幅图像的像素灰度值在一个过于有限的范围内聚集,那么图像的程序效果即会很糟糕,直接观感就是对比度很弱。下图来自维基百科,第一幅图的直方图分布非常不均衡。如果把直方图均匀地延展到整个分布域内,则图像的效果显得好了很多。

Matlab中提供了现成的函数“histeq()”来实现图像的直方图均衡。但为了演示说明算法的原理,下面我将在Matlab中自行编码实现图像的直方图均衡。通过代码来演示这个算法显然更加直观,更加易懂。当然,其实我还不得不感叹,如果仅仅是作为图像算法研究之用,Matlab确实非常好用。

首先读入图像,并将其转化为灰度图。然后提取图像的长和宽。

[plain] view plain copy

  1. image = imread('Unequalized_Hawkes_Bay_NZ.jpg');  
  2. Img = rgb2gray(image);  
  3. [height,width]=size(image);  

然后绘制一下原始图像的直方图。

[plain] view plain copy

  1. [counts1, x] = imhist(Img,256);  
  2. counts2 = counts1/height/width;  
  3. stem(x, counts2);  

统计每个灰度的像素值累计数目。

[plain] view plain copy

  1. NumPixel = zeros(1,256);%统计各灰度数目,共256个灰度级  
  2. for i = 1:height  
  3.     for j = 1: width  
  4.     %对应灰度值像素点数量增加一  
  5.     %因为NumPixel的下标是从1开始,但是图像像素的取值范围是0~255,所以用NumPixel(Img(i,j) + 1)  
  6.     NumPixel(Img(i,j) + 1) = NumPixel(Img(i,j) + 1) + 1;  
  7.     end  
  8. end  

然后将频数值算为频率

[plain] view plain copy

  1. ProbPixel = zeros(1,256);  
  2. for i = 1:256  
  3.     ProbPixel(i) = NumPixel(i) / (height * width * 1.0);  
  4. end  

再用函数cumsum来计算cdf,并将频率(取值范围是0.0~1.0)映射到0~255的无符号整数。

[plain] view plain copy

  1. CumuPixel = cumsum(ProbPixel);  
  2. CumuPixel = uint8(255 .* CumuPixel + 0.5);  

直方图均衡。赋值语句右端,Img(i,j)被用来作为CumuPixel的索引。比如Img(i,j) = 120,则从CumuPixel中取出第120个值作为Img(i,j) 的新像素值。

[plain] view plain copy

  1. for i = 1:height  
  2.     for j = 1: width  
  3.         Img(i,j) = CumuPixel(Img(i,j));  
  4.     end  
  5. end  

最后显示新图像的直方图。

[plain] view plain copy

  1. imshow(Img);  
  2. [counts1, x] = imhist(Img,256);  
  3. counts2 = counts1/height/width;  
  4. stem(x, counts2);  

当然,上述讨论的是灰度图像的直方图均衡。对于彩色图像而言,你可能会想到分别对R、G、B三个分量来做处理,这也确实是一种方法。但有些时候,这样做很有可能导致结果图像色彩失真。因此有人建议将RGB空间转换为HSV之后,对V分量进行直方图均衡处理以保存图像色彩不失真。下面我们来做一些对比实验。待处理图像是标准的图像处理测试用图couple图,如下所示。

首先,我们分别处理R、G、B三个分量,为了简便我们直接使用matlab中的函数histeq()。

[plain] view plain copy

  1. a = imread('couple.tiff');  
  2. R = a(:,:,1);  
  3. G = a(:,:,2);  
  4. B = a(:,:,3);  
  5. R = histeq(R, 256);  
  6. G = histeq(G, 256);  
  7. B = histeq(B, 256);  
  8. a(:,:,1) = R;  
  9. a(:,:,2) = G;  
  10. a(:,:,3) = B;  
  11. imshow(a)  

下面的代码使用了另外一种方式,即将色彩空间转换到HSV后,对V通道进行处理。由于代码基本与前面介绍的一致,这里我们不再做过多解释了。

[plain] view plain copy

  1. Img = imread('couple.tiff');  
  2. hsvImg = rgb2hsv(Img);  
  3. V=hsvImg(:,:,3);  
  4. [height,width]=size(V);  
  5. V = uint8(V*255);  
  6. NumPixel = zeros(1,256);  
  7. for i = 1:height  
  8.     for j = 1: width  
  9.     NumPixel(V(i,j) + 1) = NumPixel(V(i,j) + 1) + 1;  
  10.     end  
  11. end  
  12. ProbPixel = zeros(1,256);  
  13. for i = 1:256  
  14.     ProbPixel(i) = NumPixel(i) / (height * width * 1.0);  
  15. end  
  16. CumuPixel = cumsum(ProbPixel);  
  17. CumuPixel = uint8(255 .* CumuPixel + 0.5);  
  18. for i = 1:height  
  19.     for j = 1: width  
  20.         V(i,j) = CumuPixel(V(i,j));  
  21.     end  
  22. end  
  23. V = im2double(V);  
  24. hsvImg(:,:,3) = V;  
  25. outputImg = hsv2rgb(hsvImg);  
  26. imshow(outputImg);  

最后,来对比一下不同方法对彩色图像的处理效果。下面的左图是采用R、G、B三分量分别处理得到的结果。右图是对HSV空间下V通道处理之结果。显然,右图的效果更理想,而左图则出现了一定的色彩失真。事实上,对彩色图像进行直方图均衡是图像处理研究领域一个看似简单,但是一直有人在研究的话题。我们所说的对HSV空间中V分量进行处理的方法也是比较基本的策略。很多相关的研究文章都提出了更进一步的、适应性更强的彩色图像直方图均衡化算法。有兴趣的读者可以参阅相关文献以了解更多。

分别处理R、G、B三个分量之结果                                            转换到HSV空间后处理V分量

这是本系列文章的第一篇,在下一篇文章中我们将要讨论CLAHE算法,也就是限制对比度的自适应直方图均衡算法。

如果你是图像处理的同道中人,欢迎加入图像处理学习群(529549320)。为保证本群质量,入群前请先阅读群规(即本博客置顶文章http://blog.csdn.NET/baimafujinji/article/details/50570976),并在博客置顶帖中留言,否则将不予入群,请不要做无谓的尝试。Cheers~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏儿童编程

《动物魔法学校》儿童学编程Scratch之“外观”部分

导读:本文通过一个案例《动物魔法学校》来学习Scratch语言的“外观”部分。之后通过一系列其他功能的综合运用对作品功能进行了扩展。

18740
来自专栏Ken的杂谈

【系统设置】CentOS 修改机器名

17530
来自专栏儿童编程

什么样的人生才是有意义的人生——没有标准的标准答案

【导读】其实我们可以跳出这个小圈圈去更加科客观地看一下这个世界。在夜晚的时候我们仰望天空,浩瀚的宇宙中整个地球只是一粒浮尘,何况地球上一个小小的人类?在漫长的历...

1.7K50
来自专栏儿童编程

我不是算命先生,却对占卜有了疑惑——如何论证“占卜前提”的正确与否

事出有因,我对《周易》感兴趣了很多年。只是觉得特别有趣,断断续续学习了一些皮毛。这几天又偶然接触到了《梅花易数》,觉得很是精彩,将五行八卦天干地支都串联了起来。...

14010
来自专栏儿童编程

儿童创造力教育与编程教育的碰撞——MIT雷斯尼克教授最新理论梗概

儿童编程教育已经在我国各一线二线城市疯狂出现,颇有“烂大街”的趋势。我们不禁要问很多很多问题:

21870
来自专栏儿童编程

一张图理清《梅花易数》梗概

学《易经》的目的不一定是为了卜卦,但是了解卜卦绝对能够让你更好地了解易学。今天用一张思维导图对《梅花易数》的主要内容进行概括,希望能够给学友们提供帮助。

30940
来自专栏儿童编程

声音功能让儿童编程更有创造性

导读:Scratch中声音功能非常强大,除了常规的音效,你甚至可以模拟各种乐器的各个发音、设置节拍、休止……如果你愿意,甚至可以用它创作一个交响乐。我们可以引导...

13540
来自专栏FSociety

SQL中GROUP BY用法示例

GROUP BY我们可以先从字面上来理解,GROUP表示分组,BY后面写字段名,就表示根据哪个字段进行分组,如果有用Excel比较多的话,GROUP BY比较类...

5.1K20
来自专栏haifeiWu与他朋友们的专栏

复杂业务下向Mysql导入30万条数据代码优化的踩坑记录

从毕业到现在第一次接触到超过30万条数据导入MySQL的场景(有点low),就是在顺丰公司接入我司EMM产品时需要将AD中的员工数据导入MySQL中,因此楼主负...

26840
来自专栏儿童编程

天干地支五行八卦的对应关系

18890

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励