python opencv 膨胀_【python-opencv】17-形态学操作-腐蚀与膨胀

本文介绍了Python OpenCV中的形态学操作,包括腐蚀和膨胀的概念及其实现。腐蚀通过取局部最小值使图像变瘦,膨胀则通过取局部最大值得到图像变胖的效果。此外,还探讨了开运算(腐蚀后膨胀)和闭运算(膨胀后腐蚀)的作用,以及形态学梯度、顶帽和黑帽等其他形态学操作的应用。
摘要由CSDN通过智能技术生成

3b68d6b24bb8d7d7c16a7839fa3713d3.png

形态学操作其实就是改变物体的形状,比如腐蚀就是"变瘦",膨胀就是"变胖",看下图就明白了:

aad134bafc4dd0581ba3b771ce1e116a.png

形态学操作一般作用于二值化图(也可直接作用于原图),来连接相邻的元素或分离成独立的元素。腐蚀和膨胀是针对图片中的白色部分!

腐蚀

腐蚀的效果是把图片"变瘦",其原理是在原图的小区域内取局部最小值。因为是二值化图,只有0和255,所以小区域内有一个是0该像素点就为0:

cc4511fc618685dc1cdcb043d723ef96.png

这样原图中边缘地方就会变成0,达到了瘦身目的

OpenCV中用cv2.erode()函数进行腐蚀,只需要指定核的大小就行:

img = cv2.imread('j.bmp', 0)

kernel= np.ones((5, 5), np.uint8)

erosion= cv2.erode(img, kernel) #腐蚀

这个核也叫结构元素,因为形态学操作其实也是应用卷积来实现的。

结构元素可以是矩形/椭圆/十字形,可以用cv2.getStructuringElement()来生成不同形状的结构元素,比如:

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) #矩形结构

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) #椭圆结构

kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5)) #十字形结构

1b6e6c98d302c71ed047ad1313608896.png

膨胀

膨胀与腐蚀相反,取的是局部最大值,效果是把图片"变胖":

dilation = cv2.dilate(img, kernel) #膨胀

开/闭运算

a82c96121e1d566b5e84ced9a57e363d.png

先腐蚀(瘦)后膨胀(胖)叫开运算(因为先腐蚀会分开物体,这样容易记住),其作用是:分离物体,消除小区域。这类形态学操作用cv2.morphologyEx()函数实现:

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) #定义结构元素

img= cv2.imread('j_noise_out.bmp', 0)

opening= cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) #开运算

fe34ef087d5b4fe1cd179a8170b813c4.png

defopen_demo(image):print(image.shape)

gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)

ret , binary= cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)#kernel = np.ones((5,5),np.uint16)

kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))

dst=cv.morphologyEx(binary,cv.MORPH_OPEN,kernel)

cv.imshow("open_demo",dst)

d7182da572c334c8361c2c3cd312829c.png

闭运算则相反:先膨胀后腐蚀(先膨胀会使白色的部分扩张,以至于消除/"闭合"物体里面的小黑洞,所以叫闭运算)

img = cv2.imread('j_noise_in.bmp', 0)

closing= cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) #闭运算

e077f7bd516203df76f54320d673ca83.png

defclose_demo(image):print(image.shape)

gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)

ret , binary= cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)

cv.imshow("binary", binary)#kernel = np.ones((5,5),np.uint16)

kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))

dst=cv.morphologyEx(binary,cv.MORPH_CLOSE,kernel)

cv.imshow("close_demo",dst)

a892c29fa3f19133c2dea9ebdbeab065.png

2041cfbd2302ec698ff91f4620ff7331.png

经验之谈:很多人对开闭运算的作用不是很清楚,看上图↑:

如果我们的目标物体外面有很多无关的小区域,就用开运算去除掉;

如果物体内部有很多小黑洞,就用闭运算填充掉。

开操作去掉外部小的干扰,用腐蚀也能做到,二者的区别在于开操作只去掉外部小的干扰而保留了其他部分不变

其他形态学操作

形态学梯度:膨胀图减去腐蚀图,dilation - erosion,这样会得到物体的轮廓:

0fdb0fe2f588d651fa81b2bc31b27fbe.png

img = cv2.imread('school.bmp', 0)

gradient= cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

90a5f89486de6fa9c0f9c746b6ce20e7.png

顶帽(tophat):原图减去开操作后的图:src - opening

tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

黑帽(blackhat):闭运算图像与原图像差值:closing - src

blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

e788f7275bc760514556e4ed59357221.png

1725912305b18146f79011b2c0ebea9a.png

128466a0e44abef9a3051d41058118f4.png

0500cd5ba97443050cdeb9a26d813ad3.png

9daae83e22f4ca7b5bc49b3221c4eb33.png

deftophat_demo(image):

gray=cv.cvtColor(image, cv.COLOR_BGR2GRAY)

ret, binary= cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV |cv.THRESH_OTSU)#kernel = np.ones((5,5),np.uint16)

kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))

dst=cv.morphologyEx(gray, cv.MORPH_GRADIENT, kernel)#dst = cv.morphologyEx(binary, cv.MORPH_BLACKHAT, kernel)

"""给dst图像添加亮度"""

#cimage = np.array(gray.shape,np.uint8)

#cimage = 120

#dst = cv.add(dst,cimage)

cv.imshow("MORPH_GRADIENT_demo", dst)

对Binary二值图进行腐蚀 膨胀等形态学操作

75dbef10f31722b8039e29885b43fca2.png

deferode_demo(image):print(image.shape)

gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)

ret , binary= cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)#kernel = np.ones((5,5),np.uint16)

kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))

dst= cv.erode(binary,kernel=kernel)

cv.imshow("erode_demo",dst)defdilate_demo(image):print(image.shape)

gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)

ret , binary= cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)

cv.imshow("binary", binary)#kernel = np.ones((5,5),np.uint16)

kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))

dst= cv.dilate(binary,kernel=kernel)

cv.imshow("dilate_demo",dst)

对BGR原图直接进行腐蚀 膨胀等形态学操作

024abfb2ef1c2221ed3a98e20a2705b3.png

"""BGR图像直接进行腐蚀 膨胀"""src0= cv.imread('beauty1.jpg')

cv.imshow('input_image',src0)

kernel= cv.getStructuringElement(cv.MORPH_RECT,(5,5))

dilate_dst= cv.dilate(src0,kernel=kernel)

cv.imshow("dilate_dst",dilate_dst)

erode_dst= cv.erode(src0,kernel=kernel)

cv.imshow("erode_dst",erode_dst)

参考:

https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html#morphological-ops

https://www.jianshu.com/p/05ef50ac89ac

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用OpenCV进行轮廓检测、斑点检测或圆形检测可以使用以下代码: 首先,导入必要的库和读取图像: ```python import cv2 import numpy as np img = cv2.imread('image.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ``` 接下来,使用阈值处理将图像转换为二进制图像: ```python ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) ``` 接着,使用形态学操作去除噪点: ```python kernel = np.ones((3,3), np.uint8) opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel,iterations=2) ``` 对于轮廓检测,可以使用`cv2.findContours()`函数: ```python contours, hierarchy = cv2.findContours(opening,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) ``` 对于斑点检测或圆形检测,可以使用`cv2.HoughCircles()`函数: ```python circles = cv2.HoughCircles(opening,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0) ``` 最后,可以将检测结果可视化: ```python cv2.drawContours(img, contours, -1, (0,0,255), 2) for i in circles[0,:]: cv2.circle(img,(i[0],i[1]),i[2],(0,255,0),2) cv2.imshow('image',img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 完整代码如下: ```python import cv2 import numpy as np img = cv2.imread('image.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) kernel = np.ones((3,3), np.uint8) opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel,iterations=2) contours, hierarchy = cv2.findContours(opening,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) circles = cv2.HoughCircles(opening,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0) cv2.drawContours(img, contours, -1, (0,0,255), 2) for i in circles[0,:]: cv2.circle(img,(i[0],i[1]),i[2],(0,255,0),2) cv2.imshow('image',img) cv2.waitKey(0) cv2.destroyAllWindows() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值