当前位置:   article > 正文

Retinex图像增强

retinex图像增强

Retinex是一种常用的建立在科学实验和科学分析基础上的图像增强方法。就跟Matlab是由Matrix和Laboratory合成的一样,Retinex也是由两个单词合成的一个词语,他们分别是retina 和cortex,即:视网膜和皮层。Land的retinex模式是建立在以下三个假设之上的:

真实世界是无颜色的,我们所感知的颜色是光与物质的相互作用的结果。我们见到的水是无色的,但是水膜—肥皂膜却是显现五彩缤纷,那是薄膜表面光干涉的结果。
每一颜色区域由给定波长的红、绿、蓝三原色构成的;
三原色决定了每个单位区域的颜色。
Retinex理论的基础理论是物体的颜色是由物体对长波(红色)、中波(绿色)、短波(蓝色)光线的反射能力来决定的,而不是由反射光强度的绝对值来决定的,物体的色彩不受光照非均匀性的影响,具有一致性,即retinex是以色感一致性(颜色恒常性)为基础的。不同于传统的线性、非线性的只能增强图像某一类特征的方法,Retinex可以在动态范围压缩、边缘增强和颜色恒常三个方面达到平衡,因此可以对各种不同类型的图像进行自适应的增强。


原理:

        

Retinex 理论的基本内容

物体的颜色是由物体对长波(红)、中波(绿)和短波(蓝)光线的反射能力决定的,而不是由反射光强度的绝对值决定的;
物体的色彩不受光照非均性的影响,具有一致性,
即Retinex理论是以色感一致性(颜色恒常性)为基础的。
如下图所示,观察者所看到的物体的图像S是由物体表面对入射光L反射得到的,反射率R由物体本身决定,不受入射光L变化。

基于Retinex的图像增强的目的就是从原始图像S中估计出光照L,从而分解出R,消除光照不均的影响,以改善图像的视觉效果,正如人类视觉系统那样。

在这里插入图片描述

Retinex理论,与降噪类似,该理论的关键就是合理地假设了图像的构成。如果将观察者看到的图像看成是一幅带有乘性噪声的图像,那么入射光的分量就是一种乘性的,相对均匀,且变换缓慢的噪声。Retinex算法所做的就是合理地估计图像中各个位置的噪声,并除去它。

在极端情况下,我们大可以认为整幅图像中的分量都是均匀的,那么最简单的估计照度L的方式就是在将图像变换到对数域后对整幅图像求均值。

                                                  Log[R(x,y)] = Log[S(x,y)]-Log[L(x,y)]; 

要求得R(x,y)只需得到L(x,y)即可,但是根据数学的理论,L(x,y)是不能够求得的,只能近似求出。我们用S(x,y)和一个高斯核的卷积来近似表示L(x,y)。所以R(x,y)可用下式表示:

                                                  Log(R(x,y))=(Log(S(x,y))-Log(S(x,y)*G(x,y))) 

由于R是对数域的输出,要转换为数字图像,必须将他们量化为[0,255]的数字图像范畴,所以要进行线性量化,于是就有了:(G和b)为经验参数

 再通过Simplest Color Balance方式,他把数据按照一定的百分比去除最小和最大的部分,然后中间的部分重新线性量化到0和255之间,因为如果直接对MSR处理的结果进行量化,得到的图像往往整体偏灰度,这是由于原始的彩色值经过log处理后的数据范围就比较小了,这样各通道之间的差异也很小,而之后的线性量化比log曲线要平滑很多,因此整体就丧失了彩色。 

        为此,研究者又开发出一种称之为带色彩恢复的多尺度视网膜增强算法(MSRCR,Multi-Scale Retinex with Color Restoration) ,具体讨论的过程详见 <A Multiscale Retinex for Bridging the Gap Between Color Images and the Human Observation of Scenes>这篇论文,但是论文里为了这个又引入了太多的可调参数,增加了算法的复杂性,不利于自动化实现。

    直接从量化的方式上入手,引入了均值和均方差的概念,再加上一个控制图像动态的参数来实现无色偏的调节过程,简要描述如下。

    (1)分别计算出 Log[R(x,y)]中R/G/B各通道数据的均值Mean和均方差Var(注意是均方差)。

    (2)利用类似下述公式计算各通道的Min和Max值。

            Min = Mean - Dynamic * Var;  

            Max = Mean + Dynamic * Var;
    (3)  对Log[R(x,y)]的每一个值Value,进行线性映射: 

           R(x,y) = ( Value - Min ) / (Max - Min) * (255-0) ,同时要注意增加一个溢出判断,即:

           if (R(x,y) > 255)  R(x,y) =255; else if (R(x,y) < 0) R(x,y)=0;

 

  1. import cv2
  2. import numpy as np
  3. import math
  4. def replaceZeroes(data):
  5. min_nonzero = min(data[np.nonzero(data)])
  6. data[data == 0] = min_nonzero
  7. return data
  8. def simple_color_balance(input_img, s1, s2):
  9. h, w = input_img.shape[:2]
  10. out_img = np.zeros([h, w])
  11. sort_img = input_img.copy()
  12. one_dim_array = sort_img.flatten() # 转化为一维数组
  13. sort_array = sorted(one_dim_array) # 对一维数组按升序排序
  14. per1 = int((h * w) * s1 / 100)
  15. minvalue = sort_array[per1]
  16. per2 = int((h * w) * s2 / 100)
  17. maxvalue = sort_array[(h * w) - 1 - per2]
  18. # 实施简单白平衡算法
  19. if (maxvalue <= minvalue):
  20. for i in range(h):
  21. for j in range(w):
  22. out_img[i, j] = maxvalue
  23. else:
  24. scale = 255.0 / (maxvalue - minvalue)
  25. for m in range(h):
  26. for n in range(w):
  27. if (input_img[m, n] < minvalue):
  28. out_img[m, n] = 0
  29. elif (input_img[m, n] > maxvalue):
  30. out_img[m, n] = 255
  31. else:
  32. out_img[m, n] = scale * (input_img[m, n] - minvalue) # 映射中间段的图像像素
  33. out_img = cv2.convertScaleAbs(out_img)
  34. return out_img
  35. def MSRCR(img, scales, s1, s2):
  36. h, w = img.shape[:2]
  37. # print(h, w)
  38. scles_size = len(scales)
  39. img = np.array(img, dtype=np.float64)
  40. # print(img)
  41. log_R = np.zeros((h, w), dtype=np.float64)
  42. img_sum = np.add(img[:,:,0],img[:,:,1],img[:,:,2])
  43. # print(img_sum)
  44. # print("11111111111111111111111111111111")
  45. img_sum = replaceZeroes(img_sum)
  46. # print(img_sum)
  47. gray_img = []
  48. for j in range(3):
  49. img[:, :, j] = replaceZeroes(img[:, :, j])
  50. for i in range(0, scles_size):
  51. L_blur = cv2.GaussianBlur(img[:, :, j], (scales[i], scales[i]), 0)
  52. L_blur = replaceZeroes(L_blur)
  53. dst_img = cv2.log(img[:, :, j])
  54. dst_Lblur = cv2.log(L_blur)
  55. # dst_ixl = cv2.multiply(dst_img, dst_Lblur)
  56. log_R += cv2.subtract(dst_img, dst_Lblur)
  57. # print(i)
  58. # print(scles_size)
  59. MSR = log_R / 3.0
  60. '''
  61. img_sum_log = np.zeros((h, w))
  62. for i in range(0, h):
  63. for k in range(0, w):
  64. img_sum_log[i,k] = 125.0*math.log(img[i,k,j]) - math.log(img_sum[i,k])
  65. MSRCR = MSR * (img_sum_log[:, :])
  66. print(img_sum)
  67. # x = cv2.log(img_sum)
  68. '''
  69. MSRCR = MSR * (cv2.log(125.0 * img[:, :, j]) - cv2.log(img_sum))
  70. gray = simple_color_balance(MSRCR, s1, s2)
  71. gray_img.append(gray)
  72. return gray_img
  73. if __name__ == '__main__':
  74. scales = [15, 101, 301]
  75. s1, s2 = 2,3
  76. src_img = cv2.imread('4.jpg')
  77. src_img = cv2.cvtColor(src_img, cv2.COLOR_BGR2RGB)
  78. cv2.imshow('img', src_img)
  79. MSRCR_Out = MSRCR(src_img, scales, s1, s2)
  80. result = cv2.merge([MSRCR_Out[0], MSRCR_Out[1], MSRCR_Out[2]])
  81. cv2.imshow('MSR_result', result)
  82. cv2.waitKey(0)
  83. cv2.destroyAllWindows()


————————————————
版权声明:本文为CSDN博主「SongpingWang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

致谢:
https://blog.csdn.net/wsp_1138886114/article/details/83096109

带色彩恢复的多尺度视网膜增强算法(MSRCR)的原理、实现及应用。 - Imageshop - 博客园 (cnblogs.com)

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/287633
推荐阅读
相关标签
  

闽ICP备14008679号