数字图像处理 第三章 源程序

在学习数字图像处理时,书上介绍的都是理论,有时候光看理论有点儿枯燥,那就动手实现一下呗,自己以前也没有用过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()

 结果

------------恢复内容结束------------

原文地址:https://www.cnblogs.com/jingxin-gewu/p/13300395.html