提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
在上一章,我们介绍了什么是图像的灰度变换,以及灰度变换中的图像反转。图像变换的函数式可以表示如下: 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)处的像素的值这一章我们来讨论图像的伽马变换(幂律变换)。
1. 伽马变换原理
伽马变换(幂律变换),顾名思义就是对像素值进行幂运算,公式如下: g ( x , y ) = c f ( x , y ) γ g(x,y)=cf(x,y)^\gamma g(x,y)=cf(x,y)γ 其中 f ( x , y ) 是位于图像点 ( x , y ) 处的像素的值 , g ( x , y ) 是变换后的像素值, c , γ 是常数 其中\quad f(x,y)\quad 是位于图像点(x,y)处的像素的值,\quad g(x,y)是变换后的像素值,c, \gamma是常数 其中f(x,y)是位于图像点(x,y)处的像素的值,g(x,y)是变换后的像素值,c,γ是常数
1.1 伽马像素变换效果
上图是
γ
\gamma
γ取不同值
F
(
f
(
x
,
y
)
)
F(f(x,y))
F(f(x,y))的伽马变换曲线,我们可以从伽马变换曲线可以看出伽马变换有如下特点:
当
γ \gamma γ小于1时伽马变换意在对图像进行增强(使图像变亮),并降低图像的对比度,增强的效果与对换变换类似,只是曲线变化细节不同
当
γ \gamma γ等于1时,噶玛变换进行的是恒等变换
当
γ \gamma γ大于1时,噶玛变换将会使图像整体变暗,并且会增大图像的对比度(中间级别的像素降低的比两边多)
1.2 效果绘制代码
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)
# 绘制图像
gammas = [0.04, 0.1, 0.2, 0.4, 0.67, 1.0, 1.5, 2.5, 5.0, 10.0, 25.0]
labels = ["gamma = 0.04", "gamma = 0.1", "gamma = 0.2", "gamma = 0.4", "gamma = 0.67", "gamma = 1.0",
"gamma = 1.5", "gamma = 2.5", "gamma = 5.0", "gamma = 10.0", "gamma = 25.0"]
colors = ["lightgreen", "green", "greenyellow", "lightblue", "blue", "darkblue", "yellow", "orange", "pink", "red",
"gray"]
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['font.size'] = 15
plt.figure(figsize=(10, 10))
plt.xlabel('f(x,y)')
plt.ylabel('g(x,y)')
plt.title('伽马变换')
plt.grid(True)
plt.xlim(0, 255) # 设置 x 轴的范围
plt.ylim(0, 255) # 设置 y 轴的范围
for i in range(len(gammas)):
y = uniformArray(np.power(x, gammas[i]))
plt.plot(x, y, label=labels[i], color=colors[i])
plt.legend()
plt.savefig("image/tmp.png")
plt.show()
2. 噶玛变换示例
话不多说,我们直接看对数变换的示例和真实效果,下面实例取自 数字图像处理(冈萨雷斯)第四版
2.1 示例一
下面的示例是处理一个人的上胸椎骨折脱位的核磁共振图像(MRI),这个示例中图像有个明显的特征,就是图像偏暗(其实就是告诉你图像偏暗可以考虑的一种处理方式)。
2.1.1 示例代码
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from pylab import *
def applyGamma(img, gamma: float):
# 先将图像进行归一化处理
normalizedImg = img / 255.0
# 应用gamma变换
gammaImg = np.power(normalizedImg, gamma)
# 将像素值恢复到 [0, 255] 的范围
dst = np.uint8(gammaImg * 255)
return dst
if __name__ == '__main__':
# 读取灰度图像
imgGray = cv.imread('Image/Fig0303.tif', 0)
imgGamma1 = applyGamma(imgGray, 0.6)
imgGamma2 = applyGamma(imgGray, 0.4)
imgGamma3 = applyGamma(imgGray, 0.3)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(7, 9))
titleList = ["Original Image", "gamma=0.6", "gamma=0.4", "gamma=0.3"]
imageList = [imgGray, imgGamma1, imgGamma2, imgGamma3]
for i in range(4):
plt.subplot(2, 2, i + 1), plt.title(titleList[i]), plt.axis('off')
plt.imshow(imageList[i], vmin=0, vmax=255, cmap='gray')
plt.tight_layout()
plt.savefig("Image/tmp.png")
plt.show()
2.1.2 示例效果
上图中的原图,我们可以看到骨折的裂缝,但是很明显的效果偏暗,因此通过伽马变换扩展图像的灰度级,并且使用不同的 γ ( γ = 0.6 , γ = 0.4 , γ = 0.3 ) \gamma(\gamma=0.6,\gamma=0.4,\gamma=0.3) γ(γ=0.6,γ=0.4,γ=0.3) 值扩展灰度级来进行比较,从上图中我们可以看出:
- γ \gamma γ=0.6时,图像明显变亮,而且图像的对比度有所降低,但是效果貌似更好
- γ \gamma γ=0.4时,图像进一步变亮,图像的对比度进一步降低,而且背景中出现了更多的细节(小黑点),但是整个图像的增强效果貌似更好
- γ \gamma γ=0.3时,图像的亮度有些过了,甚至给人一种苍白的感觉,而且图像的对比度太低了
2.2 示例二
下面的示例是处理一张航拍图,这个示例中图像有个明显的特征,就是图像偏亮,显得有些苍白(其实就是告诉你图像偏亮可以考虑的一种处理方式)。
2.2.1 示例代码
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from pylab import *
def applyGamma(img, gamma: float):
# 先将图像进行归一化处理
normalizedImg = img / 255.0
# 应用gamma变换
gammaImg = np.power(normalizedImg, gamma)
# 将像素值恢复到 [0, 255] 的范围
dst = np.uint8(gammaImg * 255)
return dst
if __name__ == '__main__':
# 读取灰度图像
imgGray = cv.imread('Image/Fig0304.tif', 0)
imgGamma1 = applyGamma(imgGray, 3.0)
imgGamma2 = applyGamma(imgGray, 4.0)
imgGamma3 = applyGamma(imgGray, 5.0)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(7, 7))
titleList = ["Original Image", "gamma=3.0", "gamma=4.0", "gamma=5.0"]
imageList = [imgGray, imgGamma1, imgGamma2, imgGamma3]
for i in range(4):
plt.subplot(2, 2, i + 1), plt.title(titleList[i]), plt.axis('off')
plt.imshow(imageList[i], vmin=0, vmax=255, cmap='gray')
plt.tight_layout()
plt.savefig("Image/tmp.png")
plt.show()
2.2.2 示例效果
感觉这个效果图都不用分析,因为图像增强效果太明显了,整体变暗,但是对比度增加,效果更加清晰。