目录
1. 介绍
2. 代码实现
1. 介绍
顶帽变换和底帽变换就是图像的加减和开闭运算的结合
顶帽变换的公式为:原图 - 原图的开运算
- 这里结合开运算的几何图形解释来介绍顶帽变换。
- 因为开运算是结构元从下往上推动的过程,所以会删除图像灰度值相对周围高的亮点,而其他的区域影响是不大的。那么原图 - 原图的开运算的话,就是保留灰度值较高的亮点,顶帽运算相当于把开运算删除的亮点补回来了。
- 并且,可以发现,open运算的图像灰度值均 <= 原图,所以是原图 - open运算的图像
底帽变换的公式为:图像闭运算 - 原图
- 这里结合闭运算的几何图形解释来介绍底帽变换。
- 因为闭运算是结构元从上往下推动的过程,所以会删除图像灰度值相对周围低的暗点,而其他的区域影响是不大的。那么原图的闭运算 - 原图的话,就是保留灰度值较低的暗点,底帽变换相当于把闭运算删除的暗点补回来了。
- 并且,可以发现,close运算的图像灰度值均 >= 原图,所以是close运算的图像 - 原图
由此可以得出结论
顶帽变换(白顶帽变换):是保留图像中的相对周围灰度值较高的亮点,并且结构元的size越大,保留亮点的数目越多,因为相对周围灰度值较高的那个 ''相对的程度'' 被改变了(比如原来5相对1就是高,那么567往上都被保存。现在变成3相对1就是高,那么345往上都会被保留)
底帽变换(黑底帽变换):是保留图像中的相对周围灰度值较低的暗点,并且结构元的size越大,保留暗点的数目越多
2. 代码实现
变换的代码为:
import numpy as np
import cv2def noise(img): # 添加椒盐噪声for i in range(2000):x = np.random.randint(0,img.shape[0])y = np.random.randint(0,img.shape[1])img[x][y] = np.random.randint(0,2) * 255 # 随机产生0 255 椒盐噪声return img.astype(np.uint8)img = cv2.imread('./flower.jpg',0)
img_noise = noise(img.copy()) # 产生噪声图像kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))dst_tophat = cv2.morphologyEx(img_noise,cv2.MORPH_TOPHAT,kernel) # 顶帽变换
dst_blackhat = cv2.morphologyEx(img_noise,cv2.MORPH_BLACKHAT,kernel) # 底帽变换cv2.imshow('img',np.hstack((img,img_noise,dst_tophat,dst_blackhat))) # show
cv2.waitKey()
cv2.destroyAllWindows()
图像处理的结果:
图像顺序:原图、加了椒盐噪声的图像、顶帽变换、底帽变换
可以发现,顶帽变换将噪声图像上面的salt噪声都保留了,而底帽变换将pepper噪声点都保留了
如果将代码里面的 kernel size 改成20的话,就会保留更多的亮暗点