- 任务
- 1.领域平均法介绍、原理
- 2.RGB和HSI颜色模型相互转换
- 3.代码实现
- 4.结果
任务
分别在RGB和HSI颜色模型上使用领域平均法平滑彩色图像
1.领域平均法介绍、原理领域平均法常用于图像的平滑预处理,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的平均值(或加权平均值)
所采用的窗口大小一般为3×3、5×5、7×7…….
实际运用中,根据条纹走向采用灵活的窗口大小,往往可得到比较理想的结果
python opencv中可通过调用cv2.blur()函数实现
dst = cv2.blur(src, (kernel_size, kernel_size))
- RGB颜色模型下,需将三通道分别进行领域平均,再合并。
- HSI颜色模型下,需将I通道进行领域平均,H、S通道不变,再合并。
原理参考《数字图像处理》冈萨雷斯第四版第六章
代码参考博客
https://blog.csdn.net/weixin_38283159/article/details/78697586
def BGR2HSI(bgr_img): ''' BGR转换HSI颜色模型 :param bgr_img: :return: ''' bgr=bgr_img.copy() B,G,R=cv2.split(bgr/255.0) hsi_img=bgr.copy()/255.0 H,S,I=cv2.split(hsi_img) h,w=B.shape for i in range(h): for j in range(w): bgr_min=min(B[i,j],G[i,j],R[i,j]) bgr_sum=B[i,j]+G[i,j]+R[i,j] I[i,j]=bgr_sum/3 S[i,j]=1-3*bgr_min/bgr_sum cov=(R[i,j]-G[i,j])+(R[i,j]-B[i,j]) var=2*np.sqrt((R[i,j]-G[i,j])**2+(R[i,j]-B[i,j])*(G[i,j]-B[i,j])**2) theta=np.arccos(cov/var) if G[i,j]>=B[i,j]: H[i,j]=theta/(2*np.pi) else: H[i,j]=(2*np.pi-theta)/(2*np.pi) hsi_img[:,:,0]=H hsi_img[:,:,1]=S hsi_img[:,:,2]=I return hsi_img
def HSI2BGR(hsi_img): ''' HSI转换BGR颜色模型 :param hsi_img: :return: ''' hsi=hsi_img.copy() H,S,I=cv2.split(hsi) bgr_img=hsi_img.copy() B,G,R=cv2.split(bgr_img) h,w=B.shape for i in range(h): for j in range(w): if S[i,j]<1e-6: R[i,j]=I[i,j] G[i,j]=I[i,j] B[i,j]=I[i,j] else: H[i,j]*=360 if H[i,j]>0 and H[i,j]<=120: B[i,j]=(1-S[i,j])*I[i,j] sigma=(H[i,j]-60)*np.pi/180 temp=np.tan(sigma)/np.sqrt(3) G[i,j]=(1.5+1.5*temp)*I[i,j]-(0.5+1.5*temp)*B[i,j] R[i,j]=3*I[i,j]-G[i,j]-B[i,j] elif H[i,j]>120 and H[i,j]<=240: R[i,j]=(1-S[i,j])*I[i,j] sigma=(H[i,j]-180)*np.pi/180 temp=np.tan(sigma)/np.sqrt(3) B[i,j]=(1.5+1.5*temp)*I[i,j]-(0.5+1.5*temp)*R[i,j] G[i,j]=3*I[i,j]-R[i,j]-B[i,j] elif H[i,j]>240 and H[i,j]<=360: G[i,j]=(1-S[i,j])*I[i,j] sigma=(H[i,j]-300)*np.pi/180 temp=np.tan(sigma)/np.sqrt(3) R[i,j]=(1.5+1.5*temp)*I[i,j]-(0.5+1.5*temp)*G[i,j] B[i,j]=3*I[i,j]-G[i,j]-R[i,j] bgr_img[:,:,0]=B bgr_img[:,:,1]=G bgr_img[:,:,2]=R return bgr_img3.代码实现
import cv2 import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl mpl.rcParams['font.sans-serif'] = ["SimHei"] mpl.rcParams["axes.unicode_minus"] = False def gasuss_noise(image, mean=0, var=0.001): ''' 添加高斯噪声 image:原始图像 mean : 均值 var : 方差,越大,噪声越大 ''' image = np.array(image/255, dtype=float)#将原始图像的像素值进行归一化,除以255使得像素值在0-1之间 noise = np.random.normal(mean, var ** 0.5, image.shape)#创建一个均值为mean,方差为var呈高斯分布的图像矩阵 out = image + noise#将噪声和原始图像进行相加得到加噪后的图像 if out.min() < 0: low_clip = -1. else: low_clip = 0. out = np.clip(out, low_clip, 1.0)#clip函数将元素的大小限制在了low_clip和1之间了,小于的用low_clip代替,大于1的用1代替 out = np.uint8(out*255)#解除归一化,乘以255将加噪后的图像的像素值恢复 #cv.imshow("gasuss", out) noise = noise*255 return [noise,out] def BGR2HSI(bgr_img): ''' BGR转换HSI颜色模型 :param bgr_img: :return: ''' bgr=bgr_img.copy() B,G,R=cv2.split(bgr/255.0) hsi_img=bgr.copy()/255.0 H,S,I=cv2.split(hsi_img) h,w=B.shape for i in range(h): for j in range(w): bgr_min=min(B[i,j],G[i,j],R[i,j]) bgr_sum=B[i,j]+G[i,j]+R[i,j] I[i,j]=bgr_sum/3 S[i,j]=1-3*bgr_min/bgr_sum cov=(R[i,j]-G[i,j])+(R[i,j]-B[i,j]) var=2*np.sqrt((R[i,j]-G[i,j])**2+(R[i,j]-B[i,j])*(G[i,j]-B[i,j])**2) theta=np.arccos(cov/var) if G[i,j]>=B[i,j]: H[i,j]=theta/(2*np.pi) else: H[i,j]=(2*np.pi-theta)/(2*np.pi) hsi_img[:,:,0]=H hsi_img[:,:,1]=S hsi_img[:,:,2]=I return hsi_img def HSI2BGR(hsi_img): ''' HSI转换BGR颜色模型 :param hsi_img: :return: ''' hsi=hsi_img.copy() H,S,I=cv2.split(hsi) bgr_img=hsi_img.copy() B,G,R=cv2.split(bgr_img) h,w=B.shape for i in range(h): for j in range(w): if S[i,j]<1e-6: R[i,j]=I[i,j] G[i,j]=I[i,j] B[i,j]=I[i,j] else: H[i,j]*=360 if H[i,j]>0 and H[i,j]<=120: B[i,j]=(1-S[i,j])*I[i,j] sigma=(H[i,j]-60)*np.pi/180 temp=np.tan(sigma)/np.sqrt(3) G[i,j]=(1.5+1.5*temp)*I[i,j]-(0.5+1.5*temp)*B[i,j] R[i,j]=3*I[i,j]-G[i,j]-B[i,j] elif H[i,j]>120 and H[i,j]<=240: R[i,j]=(1-S[i,j])*I[i,j] sigma=(H[i,j]-180)*np.pi/180 temp=np.tan(sigma)/np.sqrt(3) B[i,j]=(1.5+1.5*temp)*I[i,j]-(0.5+1.5*temp)*R[i,j] G[i,j]=3*I[i,j]-R[i,j]-B[i,j] elif H[i,j]>240 and H[i,j]<=360: G[i,j]=(1-S[i,j])*I[i,j] sigma=(H[i,j]-300)*np.pi/180 temp=np.tan(sigma)/np.sqrt(3) R[i,j]=(1.5+1.5*temp)*I[i,j]-(0.5+1.5*temp)*G[i,j] B[i,j]=3*I[i,j]-G[i,j]-R[i,j] bgr_img[:,:,0]=B bgr_img[:,:,1]=G bgr_img[:,:,2]=R return bgr_img if __name__ == '__main__': #读取图片,添加高斯噪声,转换HSI src=cv2.imread('1.png') [noise,img]=gasuss_noise(src) hsi_img=BGR2HSI(img) #拆分通道 B = img[:, :, 0] G = img[:, :, 1] R = img[:, :, 2] H = hsi_img[:, :, 0] S = hsi_img[:, :, 1] I = hsi_img[:, :, 2] plt.figure(1) plt.subplot(231), plt.imshow(B), plt.title('B') plt.subplot(232), plt.imshow(G), plt.title('G') plt.subplot(233), plt.imshow(R), plt.title('R') plt.subplot(234), plt.imshow(H), plt.title('H') plt.subplot(235), plt.imshow(S), plt.title('S') plt.subplot(236), plt.imshow(I), plt.title('I') B_blur = cv2.blur(B, (3, 3)) G_blur = cv2.blur(G, (3, 3)) R_blur = cv2.blur(R, (3, 3)) img_new = cv2.merge([B_blur, G_blur, R_blur]) # 通道合并 I_blur = cv2.blur(I, (3, 3)) hsi_new = cv2.merge([H, S, I_blur])# 通道合并后转换位BGR显示 hsi_new_img = HSI2BGR(hsi_new) cf = img_new - hsi_new_img plt.figure(2) plt.subplot(231), plt.imshow(img_new), plt.title('RGB模型下均值滤波'), plt.ylabel('k=3') plt.subplot(232), plt.imshow(hsi_new_img), plt.title('HSI模型下均值滤波') plt.subplot(233), plt.imshow(cf), plt.title('作差') # 均值滤波核变大后的效果 B_blur = cv2.blur(B, (12, 12)) G_blur = cv2.blur(G, (12, 12)) R_blur = cv2.blur(R, (12, 12)) img_new = cv2.merge([B_blur, G_blur, R_blur]) # 通道合并 I_blur = cv2.blur(I, (12, 12)) hsi_new = cv2.merge([H, S, I_blur]) # 通道合并后转换位BGR显示 hsi_new_img = HSI2BGR(hsi_new) cf = img_new - hsi_new_img plt.subplot(234), plt.imshow(img_new), plt.ylabel('k=12') plt.subplot(235), plt.imshow(hsi_new_img) plt.subplot(236), plt.imshow(cf) plt.show()4.结果
图像在RGB、HSI颜色模型下各通道拆分
改变核大小时平滑效果对比
从RGB、HSI颜色模型下作差图,我们可以看到两种平滑法存在的差别;
从k=3、k=12对比来看,平滑的差别无法看出明显差别,教材上一般认为核越大差别越大。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)