数字图像处理 第三章 源程序
在学习数字图像处理时,书上介绍的都是理论,有时候光看理论有点儿枯燥,那就动手实现一下呗,自己以前也没有用过opencv,也是边学边练吧
源图像在本书官网下载 http://www.imageprocessingplace.com/DIP-3E/dip3e_book_images_downloads.htm
第三章
图3.4 图像反转
这个比较简单,实现了一下图像裁剪和图像反转
源程序
import cv2 import numpy as np img = cv2.imread("1.tif",0) ''' edges = cv2.Canny(img,50,150) cv2.imshow('img',img)#这一行显示错误,可能是因为路径有英文 #放狗屁,图像名称弄错了 cv2.imshow('edges',edges)''' #裁剪图像 m,n = np.shape(img) model = np.zeros((m,n)) model[int(m/4):int(3*m/4),int(n/4):int(3*n/4) ] = 1 img_cut = np.multiply(img,model) cv2.imshow('img_cut',img_cut.astype(np.uint8))#img_cut.astype(np.uint8)变换类型,保证图像正常显示 cv2.imshow('img',img) #cv2.imwrite('1_cut.tif',img_cut) #反转图像 img_reversion = 255-img cv2.imshow('img_reversion',img_reversion) #print(np.max(img)) cv2.waitKey(0) cv2.destroyAllWindows()
结果
注意
图像路径必须为英文
图3.8幂律变换
源程序
import cv2 import numpy as np img = cv2.imread("1.tif",0) cv2.imshow("img",img) #幂律变换,c = 1,r = 0.6,注意变换前需要将灰度变换到0—1,这样才能经过点(1,1),和图像中的(L-1,L-1)对应 img_max = np.max(img) img_0_1 = img/img_max #r = 0.6 r_0_6 = img_0_1**0.6 r_0_6 = r_0_6*img_max int_r_0_6 = r_0_6.astype(np.uint8)#把格式由浮点型转化为整型才能显示正确 cv2.imshow("r = 0.6",int_r_0_6) cv2.imwrite("r0.6.tif",int_r_0_6) #r = 0.4 r_0_4 = img_0_1**0.4 r_0_4 = r_0_4*img_max int_r_0_4 = r_0_4.astype(np.uint8)#把格式由浮点型转化为整型才能显示正确 cv2.imshow("r = 0.4",int_r_0_4) cv2.imwrite("r0.4.tif",int_r_0_4) #r = 0.3 r_0_3 = img_0_1**0.3 r_0_3 = r_0_3*img_max int_r_0_3 = r_0_3.astype(np.uint8)#把格式由浮点型转化为整型才能显示正确 cv2.imshow("r = 0.3",int_r_0_3) cv2.imwrite("r0.3.tif",int_r_0_3) cv2.waitKey(0) cv2.destroyAllWindows()
结果
注意
1、进行幂律变换前需要将灰度变换到0-1的范围内,
2、计算后的像素矩阵是浮点型,将其转化为整型才能正常显示
图3.20直方图均衡
源程序
#例3.5 import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread("1.tif",0) L = np.max(img)+1 #计算灰度范围 rk = np.arange(L) m,n = np.shape(img) #统计每个灰度级的个数 nk = np.zeros(L) for i in range(m): for j in range(n): nk[img[i,j]] += 1 pk = nk/(m*n) #3.3-7 f1 = plt.figure(1) plt.plot(rk,pk) #plt.show() sk = np.zeros(L) #计算变换后的灰度 for i in range(L): #3.3-8 for j in range(i): sk[i] += (L-1)*pk[j] f2 = plt.figure(2) plt.plot(rk,sk) #plt.show() #进行灰度变换 img_trans = np.zeros((m,n)) for i in range(m): for j in range(n): img_trans[i,j] = sk[img[i,j]] int_img_trans = img_trans.astype(np.uint8)#把格式由浮点型转化为整型才能显示正确 cv2.imshow("img",img) cv2.imshow("img_trans",int_img_trans) #统计变换后每个灰度级的个数 nk_trans = np.zeros(L) for i in range(m): for j in range(n): nk_trans[int_img_trans[i,j]] += 1 pk_trans = nk_trans/(m*n) #3.3-7 f3 = plt.figure(3) plt.plot(rk,pk_trans) plt.show() cv2.waitKey(0) cv2.destroyAllWindows()
结果
图3.20 局部直方图均衡
详见:https://www.cnblogs.com/jingxin-gewu/p/13341815.html
注意
1、numpy计算的结果为浮点型,图像中的是整型,要注意类型的转换
2、想办法改进灰度计算的算法
3、由于整个图像进行局部直方图均衡计算量太大,可以考虑将其裁剪到四分之一或九分之一再计算
图3.33平滑滤波
源代码
#例3.13 #模糊图像 图3.33 import cv2 import numpy as np img = cv2.imread("1.tif",0) m,n = np.shape(img) #填充 model = 9 #模板的尺寸 img_fill = np.zeros((int(m+(model-1)*2),int(n+(model-1)*2)),dtype=int) model_fill = int((model-1)/2) img_fill[model_fill:int(m+model_fill),model_fill:int(n+model_fill)] = img #注意,应该写道m+1 #int_img_fill = img_fill.astype(np.uint8) img_trans = np.zeros((m,n),dtype=int) for i in range(m): for j in range(n): img_temp = np.zeros((model,model),dtype=int) img_temp[:,:] = img_fill[i:i+model,j:j+model] img_trans[i,j] = np.sum(img_temp)/(model*model) #阈值处理 threshold_percent = 65 threshold = np.max(img)*threshold_percent/100 img_trans_thres = np.zeros((m,n)) for i in range(m): for j in range(n): if img_trans[i,j]<threshold: img_trans_thres[i,j] = 0 else: img_trans_thres[i,j] = 1 print("end") cv2.imshow("img",img) cv2.imshow("img_trsns",img_trans.astype(np.uint8)) cv2.imshow("img_trans_thres",img_trans_thres) cv2.waitKey(0) cv2.destroyAllWindows()
结果
总结
滤波效果与模板大小,阈值这两个关键因素密切相关
图3.35 中值滤波器
源程序
#例3.14,图3.35 import numpy as np import cv2 img = cv2.imread('2.tif',0) m,n = np.shape(img) #填充图像 img_fill = np.zeros((m+2,n+2),int) img_fill[1:m+1,1:n+1] = img img_temp = np.zeros((3,3),int) img_trans = np.zeros((m,n),int) for i in range(m): for j in range(n): img_temp = np.ravel(img_fill[i:i+3,j:j+3]) #散开 img_trans[i,j] = np.median(img_temp) #求中值 cv2.imshow("img",img) cv2.imshow("img_trans",img_trans.astype(np.uint8)) cv2.waitKey(0) cv2.destroyAllWindows()
结果
------------恢复内容结束------------