空间滤波基础
-
图像的平滑、锐化都是利用掩模操作来完成的. 通过掩模操作实现一种领域运算, 待处理像素点的结果由领域的图像像素以及相应的与领域有相同维数的
子图像得到. 这些子图像被称为滤波器、掩模、核、模板或窗口; -
掩模运算的数学含义是卷积(或互相关)运算;
-
掩模子图像中的值是系数值, 而不是灰度值;
空间平滑滤波器
用途: 用于模糊处理和减少噪声.
-
典型的随机噪声由灰度级的急剧变化组成;
-
平滑处理降低了图像的"尖锐"变化;
-
“负面效应”: 图像边缘模糊化; (图像边缘也由灰度级的急剧变化组成)
平滑线性滤波器
用包含在滤波掩模领域内的像素的平均灰度值去代替每个像素点的值. 又叫: 均值滤波器
-
模板尺寸对过滤器效果的影响: 模板尺寸越大, 图像越模糊, 细节丢失越多;
-
平滑空域滤波的缺点和问题: 如果图像处理的目的是去除噪音, 那么, 平滑滤波在去除噪音的同时也钝化了图像的边和尖锐的细节.
统计排序滤波器
一种非线性滤波器《 它的响应基于图像滤波器包围的图像区域中像素的排序, 然后由统计排序结果决定的值代替中心像素的值. 最常见的是中值滤波器.
中值滤波器
-
算法: 先将掩模内欲求的像素及其邻域内的像素值排序(升序或降序), 确定出中值, 并将中值赋予该像素点.
-
主要功能: 使拥有不同灰度的点看起来更接近于它的临近值.
-
主要用途: 去除"椒盐"噪声
最大值滤波器
最小值滤波器
空间锐化滤波器
-
锐化处理的目的: 是突出图像中的细节或者增强被模糊了的细节.
-
锐化处理可以用空间微分来完成. 微分算子的响应强度与图像在该点的突变程度相关, 图像微分增强了边缘和其他突变(如噪声)而消弱了灰度变化缓慢的区域.
基于二阶微分的图像增强——拉普拉斯算子
基于一阶微分的图像增强——梯度算子
- Roberts交叉梯度算子
- Prewitt梯度算子
- Sobel梯度算子
微分算子小结
混合空间增强
import cv2
import numpy as np
if __name__ == '__main__':
img = cv2.imread('../pic/Fig0304(a)(breast_digital_Xray).tif', 0)
"""
由于Canny只能处理灰度图, 所以将读取的图像转成灰度图.
用高斯平滑处理原图像降噪.
调用Canny函数, 指定最大和最小阈值, 其中apertureSize默认为3
"""
img = cv2.GaussianBlur(img, (3, 3), 0)
canny = cv2.Canny(img, 50, 150)
cv2.imshow('origin', img)
cv2.imshow('Canny', canny)
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2
import numpy as np
if __name__ == '__main__':
img = cv2.imread('../pic/Fig0304(a)(breast_digital_Xray).tif')
gray_lap = cv2.Laplacian(img, cv2.CV_16S, ksize=3)
dst = cv2.convertScaleAbs(gray_lap) # 转回uint8
cv2.imshow('origin', img)
cv2.imshow('laplacian', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
from builtins import range, Exception
import numpy as np
import cv2
import matplotlib.pyplot as plt
def max_min_blur(image, ksize=3, mode=1):
"""
:param image: 原始图像
:param ksize: 卷积核大小
:param mode: 最大值: 1 或 最小值 0
:return:
"""
img = image.copy()
rows, cols, channels = img.shape
if channels == 3:
img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
padding = (ksize - 1) // 2
new_img = cv2.copyMakeBorder(img, padding, padding, padding, padding, cv2.BORDER_CONSTANT, value=255)
for i in range(rows):
for j in range(cols):
roi_img = new_img[i:i+ksize, j:j+ksize].copy()
min_val, max_val, min_index, max_index = cv2.minMaxLoc(roi_img)
if mode == 1:
img[i, j] = max_val
elif mode == 0:
img[i, j] = min_val
else:
raise Exception('please Select a mode: max(1) or min(0)')
return img
if __name__ == '__main__':
# 读取图片
img = cv2.imread('../pic/Fig0335(a)(ckt_board_saltpep_prob_pt05).tif')
result = max_min_blur(img, 2, 0)
# 显示图形
titles = ['Source Image', 'Blur Image']
images = [img, result]
for i in range(2):
plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
from builtins import range
import cv2
import numpy as np
import matplotlib.pyplot as plt
if __name__ == '__main__':
# 读取图片
img = cv2.imread('../pic/Fig0335(a)(ckt_board_saltpep_prob_pt05).tif')
# result = cv2.blur(img, (3, 3))
result = cv2.boxFilter(img, -1, (2, 2), normalize=1)
# 显示图形
titles = ['Source Image', 'Blur Image']
images = [img, result]
for i in range(2):
plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
from builtins import range
import cv2
import numpy as np
import matplotlib.pyplot as plt
if __name__ == '__main__':
# 读取图片
img = cv2.imread('../pic/Fig0335(a)(ckt_board_saltpep_prob_pt05).tif')
result = cv2.medianBlur(img, 3)
# 显示图形
titles = ['Source Image', 'Blur Image']
images = [img, result]
for i in range(2):
plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()