目录
邻域平均法平滑彩色图像
用5*5的核平滑lena图片。
第一种方式:对RGB分量操作
第二种方式:对HSV空间的V分量即亮度分量操作
第二种方式由于只平滑了亮度分量,而每个像素的色调和饱和度不受影响,因此像素的颜色没有变化,两种方法的差别会随着核的增大变得明显。
结果:
HSV分量:
平滑结果(5*5的核):
平滑结果(9*9的核):
平滑结果(11*11的核):
平滑结果(25*25的核):
代码:
import cv2 # cv2是BGR而不是RGB
import numpy as np # 这个库用于随机生成和矩阵运算
import matplotlib.pyplot as plt
def tran(img, k_size):
h, w, c = img.shape
copy = cv2.copyMakeBorder(img, *[k_size // 2] * 4, borderType=cv2.BORDER_DEFAULT) # 补零
out = img.copy()
for k in range(c):
for i in range(h):
for j in range(w):
out[i,j,k] = np.sum(copy[i:i+k_size,j:j+k_size,k]) / (k_size ** 2)
return out.astype(np.uint8)
def tran_V(img, k_size):
h, w = img.shape
copy = cv2.copyMakeBorder(img, *[k_size // 2] * 4, borderType=cv2.BORDER_DEFAULT) # 补零
out = img.copy()
for i in range(h):
for j in range(w):
out[i,j] = np.sum(copy[i:i+k_size,j:j+k_size]) / (k_size ** 2)
return out.astype(np.uint8)
if __name__ == '__main__':
plt.rcParams['font.sans-serif'] = ['FangSong'] # 使标题能用中文字体
plt.rcParams['axes.unicode_minus'] = False
img = cv2.imread(r'D:\pictures\Fig0638(a)(lenna_RGB).tif')
HSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #转换到HSV空间
H,S,V = HSV[:,:,0], HSV[:,:,1], HSV[:,:,2]
"""画图:HSV分量"""
plt.figure(1)
plt.subplot(1,3,1)
plt.imshow(H,cmap='gray')
plt.xticks([])
plt.yticks([])
plt.title('H')
plt.subplot(1,3,2)
plt.imshow(S,cmap='gray')
plt.xticks([])
plt.yticks([])
plt.title('S')
plt.subplot(1,3,3)
plt.imshow(V,cmap='gray')
plt.xticks([])
plt.yticks([])
plt.title('V')
plt.show()
"""画图:平滑后结果"""
plt.figure(2)
plt.subplot(1,3,1)
plt.imshow(img[:,:,::-1])
plt.title('原图')
plt.xticks([])
plt.yticks([])
out = tran(img,5) #RGB分量处理后结果
out = out[:,:,::-1] # BGR -> RGB
plt.subplot(1,3,2)
plt.imshow(out)
plt.title('分别平滑RGB')
plt.xticks([])
plt.yticks([])
V_trans = tran_V(V,5) #V通道处理结果
HSV_out = cv2.merge([H,S,V_trans])
HSV_out = cv2.cvtColor(HSV_out,cv2.COLOR_HSV2RGB) # HSV -> RGB
plt.subplot(1,3,3)
plt.imshow(HSV_out)
plt.title('平滑HSV的亮度分量')
plt.xticks([])
plt.yticks([])
plt.show()