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

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

结果图:

Python-Opencv 形态学+算子实现轮廓提取_第1张图片

 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

效果图:

Python-Opencv 形态学+算子实现轮廓提取_第2张图片

 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

效果图:

Python-Opencv 形态学+算子实现轮廓提取_第3张图片

 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

效果图:

Python-Opencv 形态学+算子实现轮廓提取_第4张图片

 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

结果图:

Python-Opencv 形态学+算子实现轮廓提取_第5张图片

 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

效果图:

Python-Opencv 形态学+算子实现轮廓提取_第6张图片

 

你可能感兴趣的:(图像处理与模式识别,python,opencv,计算机视觉)