《数字图像处理》第三章 灰度变换与空间滤波学习笔记(3.1-3.2)反转、对数、幂律、分段线性等变换
请注意:笔记内容片面粗浅,请读者批判着阅读!
3.1 背景知识:空间域处理基础
核心概念解析
-
空间域定义
空间域指图像平面本身,其处理直接作用于像素矩阵(区别于频率域的变换处理)。
数学表达式:
g ( x , y ) = T [ f ( x , y ) ] g(x,y) = T[f(x,y)] g(x,y)=T[f(x,y)]
其中 f ( x , y ) f(x,y) f(x,y)为输入图像, T T T为作用于点 ( x , y ) (x,y) (x,y)邻域的算子。 -
处理类型分类
- 灰度变换(点操作):仅依赖单个像素值的映射(如对比度拉伸)
- 空间滤波(邻域操作):基于像素邻域的加权计算(如锐化、模糊)
-
邻域处理机制
以3×3邻域为例,通过滑动窗口遍历整幅图像,边界处理策略包括:零填充、镜像填充或截断操作。
3.2 灰度变换函数实践
3.2.1 图像反转变换(Image Negatives)
理论说明
- 公式:
s = L − 1 − r s = L-1 - r s=L−1−r
其中 L L L为最大灰度值(8-bit图像 L = 256 L=256 L=256) - 应用场景:增强暗区细节(如X光片中的微小病变)
Python实现
import cv2
import matplotlib.pyplot as plt
from pylab import mpl
# 设置显示中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
# 设置正常显示符号
mpl.rcParams["axes.unicode_minus"] = False
# 读取图像并反转
img = cv2.imread(r"D:\software\opencv\opencv\sources\samples\data\lena.jpg", 0)
img_neg = 255 - img
# 显示对比
plt.figure(figsize=(10,5))
plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title('原始图片')
plt.subplot(122), plt.imshow(img_neg, cmap='gray'), plt.title('反转变换')
plt.show()
3.2.2 对数变换(Log Transformations)
- 数学表达式:
s = c ⋅ log ( 1 + r ) s = c \cdot \log(1 + r) s=c⋅log(1+r) - 核心作用:
扩展暗区动态范围,压缩亮区信息(适用于高动态范围图像显示)
import numpy as np
import cv2
def log_transform(img, c=1):
img_normalized = img / 255.0 # 归一化到[0,1]
s = c * np.log(1 + img_normalized)
return np.uint8(s * 255)
img1 = cv2.imread(r"log.png", 0)
# 应用对数变换
img_log = log_transform(img1, c=50)
cv2.imshow('Log Transform', img_log)
cv2.waitKey(0)
3.2.3 幂律(伽马)变换(Gamma Correction)
- 数学表达式:
s = c ⋅ r γ s = c \cdot r^\gamma s=c⋅rγ - 变换效果:
γ值范围 处理效果 γ<1 增强暗区对比度 γ>1 增强亮区对比度 γ=1 线性不变
import cv2
import matplotlib.pyplot as plt
import numpy as np
def gamma_correction(img, gamma=1.0, c=1):
table = c * (np.arange(256) / 255.0) ** gamma * 255
table = np.clip(table, 0, 255).astype('uint8')
return cv2.LUT(img, table)
img1 = cv2.imread(r"fly.png", 0)
# 不同gamma值对比
# gammas = [0.4, 0.6, 1.5]
gammas = [2, 3, 4]
results = [gamma_correction(img1, g) for g in gammas]
plt.figure(figsize=(15, 5))
for i in range(3):
plt.subplot(1, 3, i + 1)
plt.imshow(results[i], cmap='gray')
plt.title(f'γ={gammas[i]}')
plt.show()
3.2.4 分段线性变换
- 对比度拉伸:
扩展特定灰度区间,数学表达式为三阶段线性映射。
import cv2
import numpy as np
def contrast_stretching(img, r1=50, r2=200, s1=0, s2=255):
lut = np.zeros(256, dtype=np.uint8)
# 暗部压缩到0
lut[0:r1] = np.linspace(0, s1, r1)
# 中间区域拉伸到全范围
lut[r1:r2] = np.linspace(s1, s2, r2 - r1)
# 亮部压缩到255
lut[r2:] = np.linspace(s2, 255, 256 - r2)
return cv2.LUT(img, lut)
img1 = cv2.imread(r"f.png", 0)
img_stretched = contrast_stretching(img1)
cv2.imshow('Contrast Stretched', img_stretched)
cv2.waitKey(0)
- 灰度级分层:
方法类型 处理效果 阈值法 突出特定灰度区域 区域保留法 背景抑制与目标增强
关键公式对比表
变换类型 | 数学表达式 | 动态范围控制能力 | 计算复杂度 | 应用场景 | OpenCV核心函数 |
---|---|---|---|---|---|
反转变换 | s = L − 1 − r s = L-1 - r s=L−1−r | 线性全局调整 | O(1) | 暗区细节增强(X光、显微图像) | cv2.bitwise_not |
对数变换 | s = c log ( 1 + r ) s = c\log(1+r) s=clog(1+r) | 非线性压缩亮区 | O(n) | 高动态范围压缩(频谱显示) | cv2.normalize + np.log |
幂律变换 | s = c r γ s = cr^\gamma s=crγ | 可调节非线性特性 | O(n) | 显示校正/对比度增强(MRI、CT) | cv2.LUT 查表法 |
分段线性变换 | 多段线性组合 | 局部精确控制 | O(n) | ROI增强(卫星图像、医学ROI) | cv2.LUT 自定义映射表 |
技术原理拓展
-
直方图修正理论
通过概率密度函数调整实现灰度重分布,满足:
p s ( s ) = p r ( r ) ∣ d r d s ∣ p_s(s) = p_r(r) \left| \frac{dr}{ds} \right| ps(s)=pr(r) dsdr -
空间滤波数学基础
离散卷积公式:
( f ∗ h ) ( x , y ) = ∑ i = − a a ∑ j = − b b f ( x − i , y − j ) h ( i , j ) (f \ast h)(x,y) = \sum_{i=-a}^a \sum_{j=-b}^b f(x-i,y-j)h(i,j) (f∗h)(x,y)=i=−a∑aj=−b∑bf(x−i,y−j)h(i,j)
应用场景推荐
- 工业检测:幂律变换增强产品表面划痕
- 卫星遥感:分段线性变换分离植被与水体
- 摄影后期:对数变换恢复过曝天空细节