Python-Opencv 形态学+算子实现轮廓提取

本文介绍了图像处理中的形态学操作,包括腐蚀与膨胀用于提取内边界和外边界,以及形态学梯度的计算。此外,还讨论了Sobel、Scharr和Laplacian算子在轮廓提取中的应用,展示了它们如何帮助获取图像的关键轮廓信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 形态学

图像的形态学操作主要是腐蚀和膨胀,在原理上就是结构元和原图进行卷积操作,只不过原始卷积是进行计算,而腐蚀和膨胀是看结构元覆盖范围内1的情况。

1.1. 腐蚀与膨胀定义

腐蚀定义:若结构元覆盖的二值图像素都为1,则该结构元覆盖的像素置为1

膨胀定义:若结构元覆盖的二值图像素有1,则该结构元附带的像素置为1

1.2. 提取内边界

由于图像经过腐蚀之后边缘向内缩了一圈,那么原图减去腐蚀后结果就是图像的内边界

def inner_edge(img):
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
    img_erode = cv2.erode(img, kernel)
    img_edge = img - img_erode
return img_edge

结果图:

 1.3. 提取外边界

同样地,图像经过膨胀后,边缘向外扩展了一圈,那么再减去原图就是外边界

def outer_edge(img):
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
    img_dilate = cv2.dilate(img, kernel)
    img_edge = img_dilate - img
    return img_edge

效果图:

 1.4. 形态学梯度

形态学梯度,就是膨胀后的结果减去腐蚀后结果,也就是内外边界相加

def grade_edge(img):
    edge_inner = inner_edge(img)
    edge_outer = outer_edge(img)
    grade_edge = edge_inner + edge_outer
    return grade_edge

效果图:

 2. 算子轮廓提取

高通滤波器在空域的卷积,起到的效果就是提取轮廓信息,常用的算子有Sobel,Scharr和Laplacian算子。

2.1. Sobel算子

由于Sobel算子只对x或者y方向进行轮廓提取,所以为了得到完整轮廓,需要将两个方向的轮廓进行整合。同时由于Sobel算子存在负元素,所以使用16s进行及计算,然后再取绝对值。

def sobel_edge(img):
    edge_x = cv2.Sobel(img, cv2.CV_16S, 1, 0, ksize=1)
    edge_y = cv2.Sobel(img, cv2.CV_16S, 0, 1, ksize=1)
    Scale_x = cv2.convertScaleAbs(edge_x)
    Scale_y = cv2.convertScaleAbs(edge_y)
    img_edge = cv2.addWeighted(Scale_x, 0.5, Scale_y, 0.5, 0)
    return img_edge

效果图:

 2.2. Scharr

当Sobel算子的大小设置为-1是即为特殊情况,被称作Scharr算子。同样地,Scharr算子也存在只对一个方向提取轮廓,所以需要将两个方向的轮廓相加。

def scharr_edge(img):
    edge_x = cv2.Sobel(img, cv2.CV_16S, 1, 0, ksize=-1)
    edge_y = cv2.Sobel(img, cv2.CV_16S, 0, 1, ksize=-1)
    Scale_x = cv2.convertScaleAbs(edge_x)
    Scale_y = cv2.convertScaleAbs(edge_y)
    img_edge = cv2.addWeighted(Scale_x, 0.5, Scale_y, 0.5, 0)
    return img_edge

结果图:

 2.3. Laplacian算子

与Sobel和Scharr算子不同之处在于,Laplacian没有对于某个方向的限制,所以代码上是需要一次处理即可。

def laplacian_edge(img):
    img_edge = cv2.Laplacian(img, cv2.CV_16S, ksize=1)
    img_edge = cv2.convertScaleAbs(img_edge)
    return img_edge

效果图:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云龙弓手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值