数字图像处理(18): 图像灰度变换——线性灰度变换 和 非线性灰度变换(对数变换 与 伽马变换)

迷南。 2022-02-05 04:19 2047阅读 0赞

20190702121722457.png_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly94aW9uZ3lpbWluZy5ibG9nLmNzZG4ubmV0_size_16_color_FFFFFF_t_70

目录

1 灰度变换简介

2 线性灰度变换—图像反转

3 非线性灰度变换

3.1 对数变换

3.2 伽马变换

参考资料


1 灰度变换简介

灰度变换是图像增强的一种重要手段,用于改善图像显示效果,属于空间域处理方法,它可以使图像动态范围加大,使图像对比度扩展,图像更加清晰,特征更加明显。灰度变换其实质就是按一定的规则修改图像每一个像素的灰度,从而改变图像的灰度范围。常见的灰度变换图像反转,对数变换和伽马变换等。其具体分类如下图所示:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3phaXNodWl5aWZhbmd4eW0_size_16_color_FFFFFF_t_70


2 线性灰度变换—图像反转

灰度线性变换最常见的就是图像反转,在灰度图像灰度级范围\[0,L-1\]中,其反转的公式如下所示:

s=L-1-r

其中,r表示原始图像的灰度级,s表示变换后的灰度级。

下图所示为图像反转的例子,原图像是数字乳房X射线照片,其中显示有一小块病变,通过图像反转就很容易看到病变区域。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3phaXNodWl5aWZhbmd4eW0_size_16_color_FFFFFF_t_70 1

代码如下所示:

  1. # -*- coding: utf-8 -*-
  2. import cv2
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. #读取原始图像
  6. img = cv2.imread('zxp.jpg')
  7. #图像灰度转换
  8. grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  9. #获取图像高度和宽度
  10. height = grayImage.shape[0]
  11. width = grayImage.shape[1]
  12. #创建一幅图像
  13. result = np.zeros((height, width), np.uint8)
  14. #图像灰度反色变换 s=255-r
  15. for i in range(height):
  16. for j in range(width):
  17. gray = 255 - grayImage[i,j]
  18. result[i,j] = np.uint8(gray)
  19. #显示图像
  20. cv2.imshow("Gray Image", grayImage)
  21. cv2.imshow("Result", result)
  22. #等待显示
  23. cv2.waitKey(0)
  24. cv2.destroyAllWindows()

运行结果如下图所示:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3phaXNodWl5aWZhbmd4eW0_size_16_color_FFFFFF_t_70 2


3 非线性灰度变换

3.1 对数变换

图像灰度对数变换一般表示如下所示:

s=c\\log (1+r)

其中,r表示原始图像的灰度级,s表示变换后的灰度级,c为常数。

假设r\\ge 0,下图所示的对数曲线的形状表明,改变换将输入中范围较窄的低灰度值映射为输出中较宽范围的灰度值。相反的,对高的输入灰度值也是如此。我们使用这种类型的变换来扩展图像中暗像素的值,同时压缩更高灰度级的值。反对数变换的作用与此相反。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3phaXNodWl5aWZhbmd4eW0_size_16_color_FFFFFF_t_70 3

代码如下所示:

  1. # -*- coding: utf-8 -*-
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. import cv2
  5. #绘制曲线
  6. def log_plot(c):
  7. x = np.arange(0, 256, 0.01)
  8. y = c * np.log(1 + x)
  9. plt.plot(x, y, 'r', linewidth=1)
  10. plt.rcParams['font.sans-serif']=['SimHei'] #正常显示中文标签
  11. plt.title(u'对数变换函数')
  12. plt.xlim(0, 255), plt.ylim(0, 255)
  13. plt.show()
  14. #对数变换
  15. def log(c, img):
  16. output = c * np.log(1.0 + img)
  17. output = np.uint8(output + 0.5)
  18. return output
  19. #读取原始图像
  20. img = cv2.imread('test8.bmp')
  21. #绘制对数变换曲线
  22. log_plot(42)
  23. #图像灰度对数变换
  24. output = log(42, img)
  25. #显示图像
  26. cv2.imshow('Input', img)
  27. cv2.imshow('Output', output)
  28. cv2.waitKey(0)
  29. cv2.destroyAllWindows()

运行结果如下图所示:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3phaXNodWl5aWZhbmd4eW0_size_16_color_FFFFFF_t_70 4

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3phaXNodWl5aWZhbmd4eW0_size_16_color_FFFFFF_t_70 5


3.2 伽马变换

伽玛变换又称为 指数变换幂次变换,是另一种常用的灰度非线性变换。图像灰度的伽玛变换一般表示如下所示:

s=c\{​\{r\}^\{\\gamma \}\}

其中,r表示原始图像的灰度级,s表示变换后的灰度级,c\\gamma正常数

1)当\\gamma>1时,会拉伸图像中灰度级较高的区域,压缩灰度级较低的部分;

2)当\\gamma<1时,会拉伸图像中灰度级较低的区域,压缩灰度级较高的部分;

3)当\\gamma=1时,该灰度变换是线性的,此时通过线性方式改变原图像。

如下图所示,不同\\gamma值的变换曲线:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3phaXNodWl5aWZhbmd4eW0_size_16_color_FFFFFF_t_70 6

下图所示为图像伽马变换的例子:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3phaXNodWl5aWZhbmd4eW0_size_16_color_FFFFFF_t_70 7

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3phaXNodWl5aWZhbmd4eW0_size_16_color_FFFFFF_t_70 8

代码如下所示:

  1. # -*- coding: utf-8 -*-
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. import cv2
  5. #绘制曲线
  6. def gamma_plot(c, v):
  7. x = np.arange(0, 256, 0.01)
  8. y = c*x**v
  9. plt.plot(x, y, 'r', linewidth=1)
  10. plt.rcParams['font.sans-serif']=['SimHei'] #正常显示中文标签
  11. plt.title(u'伽马变换函数')
  12. plt.xlim([0, 255]), plt.ylim([0, 255])
  13. plt.show()
  14. #伽玛变换
  15. def gamma(img, c, v):
  16. lut = np.zeros(256, dtype=np.float32)
  17. for i in range(256):
  18. lut[i] = c * i ** v
  19. output_img = cv2.LUT(img, lut) #像素灰度值的映射
  20. output_img = np.uint8(output_img+0.5)
  21. return output_img
  22. #读取原始图像
  23. img = cv2.imread('test9.bmp')
  24. #绘制伽玛变换曲线
  25. gamma_plot(0.00000005, 4.0)
  26. #图像灰度伽玛变换
  27. output = gamma(img, 0.00000005, 4.0)
  28. #显示图像
  29. cv2.imshow('Imput', img)
  30. cv2.imshow('Output', output)
  31. cv2.waitKey(0)
  32. cv2.destroyAllWindows()

运行结果如下图所示:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3phaXNodWl5aWZhbmd4eW0_size_16_color_FFFFFF_t_70 9

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3phaXNodWl5aWZhbmd4eW0_size_16_color_FFFFFF_t_70 10


参考资料

[1] https://blog.csdn.net/Eastmount/article/details/88858696

[2] https://blog.csdn.net/Eastmount/article/details/88929290

[3] 冈萨雷斯. 数字图像处理(第三版)

发表评论

表情:
评论列表 (有 0 条评论,2047人围观)

还没有评论,来说两句吧...

相关阅读