提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
在上一章,我们介绍了什么是图像的灰度变换,以及灰度变换中的图像反转。图像变换的函数式可以表示如下: g ( x , y ) = F ( f ( x , y ) ) f ( x , y ) 是位于图像点 ( x , y ) 处的像素的值 g(x,y)=F(f(x,y))\quad f(x,y)是位于图像点(x,y)处的像素的值 g(x,y)=F(f(x,y))f(x,y)是位于图像点(x,y)处的像素的值这一章我们来讨论图像的对数变换。
对数变换原理
g ( x , y ) = c log ( 1 + f ( x , y ) ) g(x,y)=c\log_{}{(1+f(x,y))} g(x,y)=clog(1+f(x,y)) 其中 f ( x , y ) 是位于图像点 ( x , y ) 处的像素的值 g ( x , y ) 是变换后的像素值, c 是一个常数 其中\quad f(x,y)\quad 是位于图像点(x,y)处的像素的值g(x,y)是变换后的像素值,c是一个常数 其中f(x,y)是位于图像点(x,y)处的像素的值g(x,y)是变换后的像素值,c是一个常数
对数像素变换效果
上图中对数曲线的形状表明,灰度图像的对数变换有如下特点:
如果像素值为 0,则计算结果依旧为 0。
对数变换意在对图像进行增强(使图像变亮),但是对低像素值的增加幅度要大于高像素值。
对数变换虽然对低像素值和对高像素值的增加幅度不一致,但是不会改变原图像已有的灰度等级(简单一点,原图像中更亮的地方依旧更亮)。
从一定情况下说,对数变换降低了图像的对比度。
效果图绘制代码
import numpy as np
import matplotlib.pyplot as plt
def uniformArray(array):
# 计算数组的最小值和最大值
min = np.min(array)
max = np.max(array)
# 归一化处理并缩放到0到255
normArray = ((array - min) / (max - min)) * 255
return normArray
if __name__ == '__main__':
# 定义 x 的范围
x = np.arange(0, 255)
# 定义函数
P = x # log变换之前的像素值
PN = uniformArray(np.log(x+1)) # log变换之后的像素值
# 绘制图像
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(10, 10))
plt.plot(x, P, label='对数变换之前', color='blue')
plt.plot(x, PN, label='对数变换之后', color='red')
plt.xlabel('x')
plt.ylabel('y')
plt.title('对数变换:对图像的每个像素的值进行操作(取对数后进行归一化)')
plt.legend()
plt.grid(True)
plt.xlim(0, 255) # 设置 x 轴的范围
plt.ylim(0, 255) # 设置 y 轴的范围
plt.savefig('Image/tmp.png')
plt.show()
对数变换示例
示例代码
话不多说,我们直接看对数变换的示例和真实效果,下面实例取自 数字图像处理(冈萨雷斯)第四版(这个示例其实意在告诉你,当图像的对比度太大,导致图像失真的一种可行的处理方法)
import numpy as np
import matplotlib.pyplot as plt
import cv2 as cv
def uniformArray(array):
# 计算数组的最小值和最大值
min_val = np.min(array)
max_val = np.max(array)
# 归一化处理并缩放到0到255
normArray = ((array - min_val) / (max_val - min_val)) * 255
# 转换为整数类型
return normArray.astype(np.uint8)
if __name__ == '__main__':
# 读取灰度图像
imgGray = cv.imread('Image/Fig0102.tif', 0)
# 对图像进行对数变换并归一化
imgTransform = np.log1p(imgGray) # 使用 log1p 确保输入范围正确
imgTransform = uniformArray(imgTransform)
# 显示图像
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(10, 10))
plt.subplot(121)
plt.imshow(imgGray, cmap='gray')
plt.axis('off')
plt.title('Original Image')
plt.subplot(122)
plt.imshow(imgTransform, cmap='gray')
plt.axis('off')
plt.title('Transformed Image')
plt.tight_layout()
plt.savefig('Image/Fig0102.png', transparent=True)
plt.show()
示例效果图
上图是一个傅里叶频谱,一般频谱的值的取值范围为 0~106 ,如果想用图像的方式展示频谱,那就必须对频谱进行归一化处理,也就是将频谱的值压缩到 0 ~ 255,但是如果压缩就会使得频谱中低的值在图像上无法展示,如上图中的原图像。而对数变换恰好对低像素值的增强效果更好,如上图中的变换后的图像。