- 首先导入库和图片,图片根据自己的路径修改
import numpy as np
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
# read img1 and img2
img1 = cv2.imread(r'material\b.png')
img2 = cv2.imread(r'material\a.png')
img3 = cv2.imread(r'material\c.png')
# print(img1.shape,img2.shape,'\n',img1)
1、边界填充
1. 边缘复制填充:直接复制图像边缘像素至指定的像素大小:aaaa|abcd|dddd
2. 边缘反射填充:边缘按照图像像素值进行对称复制:dcba|abcd|dcba
3. 边缘101复制填充:边缘按照图像像素进行复制,但不复制边缘值:dcb|abcd|cba
4. 边缘包装填充:边缘按照源图像像素值顺序填充:cdefgh|abcdefgh|abcdefg
5. 常数复制填充:选择某一常数像素值在边缘进行复制
cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=bord函数详讲:
参数1:要操作的图像;
参数2:上方填充像素量;
参数3:下方填充像素量;
参数4:左方填充像素量;
参数5:右方填充像素量;
参数6:borderType=填充方式:cv2.BORDER_REPLICATE:边缘复制填充;cv2.BORDER_REFLECT:边缘反射填充;cv2.BORDER_REFLECT_101:边缘101复制填充;cv2.BORDER_WRAP:边缘包装填充;cv2.BORDER_CONSTANT,value=1:以像素1进行常数复制填充。
img = cv2.imread(r"material\a.png")
top_size,bottom_size,left_size,right_size = (50,50,50,50)
rep = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_REPLICATE)
re = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_REFLECT)
re101 = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_WRAP)
con = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_CONSTANT,value=244)
显示结果:
plt.subplot(2,3,1),plt.imshow(img,'gray'),plt.title('ORIGINAL') # plt.subplot建立子图,参数为行,列,第几个图
plt.subplot(2,3,2),plt.imshow(rep,'gray'),plt.title('rep')
plt.subplot(2,3,3),plt.imshow(re,'gray'),plt.title('re')
plt.subplot(2,3,4),plt.imshow(re101,'gray'),plt.title('re101')
plt.subplot(2,3,5),plt.imshow(wrap,'gray'),plt.title('wrap')
plt.subplot(2,3,6),plt.imshow(con,'gray'),plt.title('con')
plt.show()
2、数值计算
opencv读取的图像以numpy的uint8的array的形式储存,因此可以按照array的计算方式计算:
- 一般相加要求维度和shape相同才可以,
- 根据numpy的广播机制,不同维度也可相加:维度不同,但是后源维度相同可运算,其它维度相同只有一个维度不同且一方为1可运算。
- 最大为255(白),最小为0(黑),计算后不在这区间将取其与255的余数。例如,256为1。
img0 = img1+105 # 这个img0的每一位都会加105,超过255时会溢出,溢出后为与255的余数
img00 = cv2.add(img1,105) # 这个img1的第一维度都会加105,超过255会溢出,溢出后为255
plt.subplot(1,2,1),plt.imshow(img0)
plt.subplot(1,2,2),plt.imshow(img00)
print(img1.shape,img2.shape) # 两图的shape不同,无法计算
print(img1[:2,:2],'\n',img0[:2,:2],'\n',img00[:2,:2])
cv2.resize()函数:
1. 图像shape的变化:cv2.resize(img,(x,y)):将img图像的shape变为高为y,宽为x
2. cv2.resize(img,(0,0),fx=,fy=),当x,y为0时,若设置fx,fy表示将原图像按照fx,fy进行倍数变化
img5 = img3+img1
plt.subplot(1,3,1),plt.imshow(img1),plt.title('IMG1')
plt.subplot(1,3,2),plt.imshow(img3),plt.title('IMG2')
plt.subplot(1,3,3),plt.imshow(img5),plt.title('FUSEIMG')
3、图像融合
即将两个相同shape的图像按照一定的权重进行相加
图像相加:cv2.addWeighted(img1,a,img2,b,c):表示将img1和img2按照权重a,b相加,并且取偏置为c得到融合图像。
Fusing_img1 = cv2.addWeighted(img1,0.7,img3,0.3,10)
Fusing_img2 = cv2.addWeighted(img1,0.3,img3,0.7,10)
plt.subplot(2,2,1),plt.imshow(img1),plt.title('IMG1')
plt.subplot(2,2,2),plt.imshow(img3),plt.title('IMG2')
plt.subplot(2,2,3),plt.imshow(Fusing_img1),plt.title('FUSEIMG1')
plt.subplot(2,2,4),plt.imshow(Fusing_img2),plt.title('FUSEIMG2')
plt.show()
4、形态学运算
形态学运算主要包括:
1. 腐蚀:腐蚀边缘,除去毛刺。cv2.erode(img,kernel,iterations=n)
2. 膨胀:膨胀对象,增大面积。cv2.dilate(img,kernel,iterations=n)
3. 开运算:“开除毛刺”先腐蚀再膨胀。cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)
4. 闭运算:先膨胀再腐蚀,填空隙。cv2.morphologyEx(img, cv2.MORPH_CLOSE,kernel)
5. 梯度:取图像边界,膨胀-腐蚀。cv2.morphologyEx(img,cv2.MORPH_GRADIENT, kernel)
6. 礼帽:原始图像-开运算:可以突出明亮区域。cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel)
7. 黑帽:闭运算-原始图像。cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel)
img4 = cv2.imread(r"material\z1-3.png") #原图是黑色字体,白色背景,将它变为白色字体黑色背景
# thres,img4 = cv2.threshold(img4,250 ,255,cv2.THRESH_BINARY_INV)
plt.imshow(img4)
形态学卷积核设置
- 可使用numpy自行设置,指定数据类型为uint8
- 可使用cv2.getStructuringElement(类型,(尺寸))创建
- 类型1:cv2.MORPH_RECT:矩形卷积核
- 类型2:cv2.MORPH_CROSS:十字形卷积核;
- cv2.MORPH_ELLIPSE:椭圆形卷积核。
kernel = np.ones((3,3),np.uint8)
print(kernel)
设置卷积核,也可随意设置值,但是数据类型为uint8。
def cv_show(name,img):
cv2.imshow(name,img)
cv2.waitKey(0)
cv2.destroyAllWindows()
for i in range(1,5):
plt.subplot(2,2,i)
erosion_img = cv2.erode(img4,kernel,iterations=i)
plt.imshow(erosion_img)
plt.title(f"The {i} th erode")
进行了四次腐蚀操作,可以看出毛刺已经没有了,而且随着腐蚀的深入,白色的越来越少。
for i in range(1,5):
# plt.subplot(2,2,i)
dilation_img = cv2.dilate(img4,kernel,iterations=i)
cv_show('a',dilation_img)
# plt.imshow(dilation_img)
# plt.title(f"The {i} th dilate")
进行了四次膨胀操作,可以发现随着膨胀的进行,白色区域越来越粗了。
其他形态学运算基于上述两种进行组合得到。
- 开运算是先腐蚀掉毛刺,再膨胀,因此它与原图形大小相当且没有毛刺
- 闭运算是先膨胀使得毛刺变大,再腐蚀导致无法腐蚀掉毛刺,因此它与原图形差距不大
- 梯度运算是用闭运算减开运算,得到的是原图形的轮廓
- 礼帽是原图像减去开运算,因而剩下毛刺
- 黑帽是闭运算减去原图像,因此得到的大部分是黑色,余下部分轮廓点(仔细看可以看到)
original_img = cv2.imread(r"material\z1-3.png")
open_img = cv2.morphologyEx(original_img,cv2.MORPH_OPEN,kernel) # 开运算
close_img = cv2.morphologyEx(original_img,cv2.MORPH_CLOSE,kernel) # 闭运算
gradient_img = cv2.morphologyEx(original_img,cv2.MORPH_GRADIENT,kernel) # 梯度运算
tophat_img = cv2.morphologyEx(original_img,cv2.MORPH_TOPHAT,kernel) # 礼帽运算
blackhat_img = cv2.morphologyEx(original_img,cv2.MORPH_BLACKHAT,kernel) # 黑帽运算
cv_show('open_img',open_img)
cv_show('close_img',close_img)
cv_show('gradient_img',gradient_img)
cv_show('tophat_img',tophat_img)
blackhat_img = original_img-blackhat_img+tophat_img+gradient_img
img_media = cv2.medianBlur(blackhat_img,3) # 中值滤波
img_media = cv2.medianBlur(blackhat_img,3) # 中值滤波
cv_show('blackhat_img',blackhat_img)
cv_show('img_media',img_media)
# plt.subplot(2,3,1),plt.imshow(original_img),plt.title('ORIGINAL'),plt.s
# plt.subplot(2,3,2),plt.imshow(open_img),plt.title('OPEN')
# plt.subplot(2,3,3),plt.imshow(close_img),plt.title('CLOSE')
# plt.subplot(2,3,4),plt.imshow(gradient_img),plt.title('GRADIENT')
# plt.subplot(2,3,5),plt.imshow(tophat_img),plt.title('TOPHAT')
# plt.subplot(2,3,6),plt.imshow(blackhat_img),plt.title('BLACKHAT')
# plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.4, wspace=0.3, hspace=0.2)
# plt.tight_layout()
# plt.savefig('activation_functions.png')
# plt.show()
# 创建一个包含4个子图的图形
fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(10, 8))
# 调整子图之间的间距
axes[0, 0].imshow(original_img)
axes[0, 0].set_title('original_img')
axes[0, 1].imshow(open_img)
axes[0, 1].set_title('open_img')
axes[1, 0].imshow(close_img)
axes[1, 0].set_title('close_img')
axes[1, 1].imshow(gradient_img)
axes[1,1].set_title('gradient_img')
axes[1, 2].imshow(tophat_img)
axes[1, 2].set_title('tophat_img')
axes[0, 2].imshow(blackhat_img)
axes[0,2].set_title('blackhat_img')
# fig.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.4, wspace=0.1, hspace=0.1)
plt.subplots_adjust(hspace=0.3)
plt.tight_layout()
plt.savefig('activation_functions.png')
plt.show()
标签:plt,img,title,imshow,cv2,形态学,Opencv,图像,size
From: https://blog.csdn.net/Airporal/article/details/142441106