目录
腐蚀
操作思想
腐蚀的操作思想和土壤侵蚀一样,会侵蚀前景物体的边界。这样内核会在图像中滑动,除非内核下所有像素都为1,不然全部侵蚀为0。
腐蚀操作更适合于二值图像,如果是彩色图像会对每个通道进行处理
接下来我补充一个新图
这个图是经过cv2.resize重置过大小的 大家可以直接下载使用,保证屏幕能看见完全体
cv2.resize我将会在下一节补充篇讲解
之前一直留着的cv2.createTrackbar也会讲解
一句话概括
消除毛刺,减少白色区域
案例
erodeResize = cv2.imread('Picture/ErodeResize.png')
ksize = 1
kernel = np.ones((ksize,ksize),np.uint8)
iteration = 1
def On_Tracker(value):
iteration = cv2.getTrackbarPos('Iteration','Orgin Vs Erode')
ksize = cv2.getTrackbarPos('ksize','Orgin Vs Erode')
kernel = np.ones((ksize,ksize),np.uint8)
erode = cv2.erode(erodeResize,kernel,iterations = iteration)
res = np.hstack((erodeResize,erode))
cv2.imshow('Orgin Vs Erode',res)
erode = cv2.erode(erodeResize,kernel,iteration)
cv2.namedWindow('Orgin Vs Erode')
cv2.createTrackbar('ksize','Orgin Vs Erode',1,7,On_Tracker)
cv2.createTrackbar('Iteration','Orgin Vs Erode',1,5,On_Tracker)
cv2.setTrackbarMin('ksize','Orgin Vs Erode',1)
cv2.setTrackbarMin('Iteration','Orgin Vs Erode',1)
res = np.hstack((erodeResize,erode))
cv2.imshow('Orgin Vs Erode',res)
cv2.waitKey(0)
cv2.destroyAllWindows()
大家可以自行滑动上方的滑动条来查看效果
膨胀
简介
膨胀操作与腐蚀操作相反。在膨胀操作中,如果内核下至少有一个像素是最大值,那么该像素就会被设为最大值。因此,它增加了图像中的白色区域,或者说增加了前景目标对象的尺寸大小。通常情况下,在去除噪声后,在腐蚀操作之后就是膨胀。因为腐蚀消除了白色的噪音,但它也缩小了我们的前景物体,所以我们需要扩大回它。因为当噪音消失了,原本应该存在的白色面积也不会自主回来。而且膨胀在连接物体的破碎部分时也很有用。
一句话概括
增加白色区域,连接破碎部分
案例
kernel = np.ones((2,2),np.uint8)
erodeResize = cv2.imread('Picture/ErodeResize.png')
erode = cv2.erode(erodeResize,kernel,iterations=2)
cv2.imwrite('Picture/OneErode.png',erode)
保存一张2内核迭代2次的侵蚀图像
我们可以明显看到侵蚀完之后 那些毛刺确实没有了 但是字体也变模糊了,甚至有些位置被侵蚀的段落了,这时候我们就可以用膨胀操作回来,毛刺因为本身就是多出来的 所以膨胀是不会把毛刺变回来的。
def On_Tracker_Dilate(value):
ksize = cv2.getTrackbarPos('Kernel','Dilate')
iteration = cv2.getTrackbarPos('Iteration','Dilate')
kernel = np.ones((ksize,ksize),np.uint8)
dilate = cv2.dilate(origin,kernel,iterations=iteration)
res = np.hstack((origin,dilate))
cv2.imshow('Dilate',res)
ksize = 1
iteration = 1
kernel = np.ones((ksize,ksize),np.uint8)
origin = cv2.imread('Picture/OneErode.png')
cv2.namedWindow('Dilate')
dilate = cv2.dilate(origin,kernel,iterations=iteration)
cv2.createTrackbar('Kernel','Dilate',1,10,On_Tracker_Dilate)
cv2.createTrackbar('Iteration','Dilate',1,10,On_Tracker_Dilate)
cv2.setTrackbarMin('Kernel','Dilate',1)
cv2.setTrackbarMin('Iteration','Dilate',1)
res = np.hstack((origin,dilate))
cv2.imshow('Dilate',res)
cv2.waitKey(0)
cv2.destroyAllWindows()
自己拖动滑动条就可以看见效果了
开、闭运算
简介
开运算:先腐蚀后膨胀
闭运算:先膨胀后腐蚀
案例
def On_Track_OpenAndClose(value):
ksize = cv2.getTrackbarPos('Kernel','Opening And Closing')
kernel = np.ones((ksize,ksize),np.uint8)
itertion = cv2.getTrackbarPos('Iteration','Opening And Closing')
opening = cv2.morphologyEx(origin,cv2.MORPH_OPEN,kernel=kernel,iterations=itertion)
closing = cv2.morphologyEx(origin,cv2.MORPH_CLOSE,kernel=kernel,iterations=itertion)
res = np.hstack((origin,opening,closing))
cv2.imshow('Opening And Closing',res)
ksize = 1
itertion = 1
kernel = np.ones((ksize,ksize),np.uint8)
origin = cv2.imread('Picture/ErodeResize.png')
cv2.namedWindow('Opening And Closing')
cv2.createTrackbar('Kernel','Opening And Closing',1,10,On_Track_OpenAndClose)
cv2.createTrackbar('Iteration','Opening And Closing',1,10,On_Track_OpenAndClose)
cv2.setTrackbarMin('Kernel','Opening And Closing',1)
cv2.setTrackbarMin('Iteration','Opening And Closing',1)
opening = cv2.morphologyEx(origin,cv2.MORPH_OPEN,kernel=kernel,iterations=itertion)
closing = cv2.morphologyEx(origin,cv2.MORPH_CLOSE,kernel=kernel,iterations=itertion)
res = np.hstack((origin,opening,closing))
cv2.imshow('Opening And Closing',res)
cv2.waitKey(0)
cv2.destroyAllWindows()
其实在这个地方不应该设置滑动条 看效果的,因为这边是一个函数,迭代次数的增加只是变成了做了多少次开闭运算,而不是侵蚀多少次后膨胀多少次那些,但我已经不想再去一个一个找具体数值来找到最好的效果,教学视频可以一次一次,一次一次讲,但文章专栏只能设置滑动条让你们自己尝试
形态学梯度
简介
形态学梯度是图像膨胀与腐蚀的差值。它可以用来突出图像中的边缘和轮廓。具体来说,膨胀操作会增加图像中的白色区域,而腐蚀操作会减少图像中的白色区域。因此,当我们从膨胀后的图像中减去腐蚀后的图像时,只有边缘处的像素值才会有所不同,而其他地方的像素值都为0。这样,形态学梯度就可以突出图像中的边缘和轮廓。
一句话概括
膨胀 - 腐蚀 = 梯度
得到边界变换信息
案例
def On_Track_Gradient(value):
kernel = np.ones((cv2.getTrackbarPos('Kernel','Gradient'),cv2.getTrackbarPos('Kernel','Gradient')),np.uint8)
gradient = cv2.morphologyEx(origin,cv2.MORPH_GRADIENT,kernel=kernel)
res = np.hstack((origin,gradient))
cv2.imshow('Gradient',res)
ksize = 2
kernel = np.ones((ksize,ksize),np.uint8)
origin = cv2.imread('Picture/ErodeResize.png')
cv2.namedWindow('Gradient')
cv2.createTrackbar('Kernel','Gradient',2,10,On_Track_Gradient)
cv2.setTrackbarMin('Kernel','Gradient',2)
gradient = cv2.morphologyEx(origin,cv2.MORPH_GRADIENT,kernel=kernel)
res = np.hstack((origin,gradient))
cv2.imshow('Gradient',res)
cv2.waitKey(0)
cv2.destroyAllWindows()
可以相当明显的看到边界
礼帽(顶帽)与黑帽
简介
礼帽操作,也称为顶帽操作,是原始图像与其开运算之后的图像之差。它可以用来突出比原始图像周围亮度更低的细节,例如去除不均匀光照的影响。
黑帽操作是闭运算后的图像与原始图像之差。它可以用来突出比原始图像周围亮度更高的细节。
一句话概括
礼帽 = 原始输入-开运算
黑帽 = 闭运算-原始输入
案例
kernel = np.ones((3,3),np.uint8)
origin = cv2.imread('Picture/ErodeResize.png')
topHat = cv2.morphologyEx(origin,cv2.MORPH_TOPHAT,kernel=kernel)
blackHat = cv2.morphologyEx(origin,cv2.MORPH_BLACKHAT,kernel=kernel)
res = np.hstack((origin,topHat,blackHat))
cv2.imshow('TopHat And BlackHat',res)
cv2.waitKey(0)
cv2.destroyAllWindows()
此处你们可自行尝试如何实现交互的滑动条