0
点赞
收藏
分享

微信扫一扫

【youcans 的 OpenCV 例程200篇】145. 形态学之边缘和角点检测


【youcans 的 OpenCV 例程200篇】145. 形态学之边缘和角点检测


5.7 形态学之边缘和角点检测

边缘和角点不仅保留了图像的重要特征,而且极大地减少了信息的数据量,因而具有很大的信息熵,在场景重建、运动估计、目标跟踪与识别、图像的配准与匹配等计算机视觉领域具有重要作用。角点检测的方法主要是基于图像边缘或基于图像灰度,后者的应用更加广泛,如 Harris算子、Moravec 算子和 Susan 算子。

本节介绍一种基于形态学的边缘检测和角点检测方法。角点在水平和竖直方向的变化都很大,即 x,y 方向的梯度都很大;边缘在 x,y 中的一个方向上梯度很大;而平坦区域在水平竖直两个方向上的梯度都较小。

形态学边缘检测的原理是,图像中的物体在膨胀时向周围扩张,在腐蚀时会发生收缩,变化的区域都只发生在物体的边缘。图像的形态学梯度运算,是膨胀图像与腐蚀图像之差 ,可以得到图像的轮廓,通常用于提取物体边缘。

形态学角点检测的原理是,通过十字形、菱形、方形、X 型等不同形状结构元的膨胀腐蚀,使原图像的边缘不发生变化,仅有焦点被腐蚀。

需要说明的是,本案例只是为了示范形态学方法的功能,并不是高效、精准的角点检测方法。


例程 10.36:基于灰度形态学的边缘检测和角点检测

形态学检测边缘的原理是,图像中的物体在膨胀时向周围扩张,在腐蚀时会发生收缩,变化的区域都只发生在物体的边缘。图像的形态学梯度运算,是膨胀图像与腐蚀图像之差 ,可以得到图像的轮廓,通常用于提取物体边缘。

(1)先用十字形结构元膨胀,图像在水平和垂直方向膨胀,而在 45度、135度的斜向没有膨胀;再用菱形核对膨胀结果进行腐蚀,使得膨胀结果在水平和垂直方向被腐蚀,而在45度、135度的斜向也有腐蚀。

(2)先用 X 形结构元膨胀,图像在水平、垂直方向、45度、135度斜向都发生膨胀;再用正方形核对膨胀结果进行腐蚀,使原图的角点被恢复,而水平、垂直方向的边缘被腐蚀。

(3) 二者相减,得到角点检测结果。

    # 10.36: 基于灰度形态学的拐角检测
    # 基于灰度形态学的复杂背景图像重建
    img = cv2.imread("../images/imgBuilding1.png", flags=1)
    imgSign = img.copy()
    imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 图片格式转换:BGR(OpenCV) -> Gray
    # ret, imgBin = cv2.threshold(imgGray, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)  # 二值化处理

    # 边缘检测
    element = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    imgEdge = cv2.morphologyEx(imgGray, cv2.MORPH_GRADIENT, element)  # 形态学梯度

    # 构造 5×5 结构元素,十字形、菱形、方形、X 型
    cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))  # 十字型结构元
    square = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))  # 矩形结构元
    xShape = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))  # X 形结构元
    diamond = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))  # 构造菱形结构元
    diamond[1, 1] = diamond[3, 3] = 1
    diamond[1, 3] = diamond[3, 1] = 1
    print(diamond)

    imgDilate1 = cv2.dilate(imgGray, cross)  # 用十字型结构元膨胀原图像
    imgErode1 = cv2.erode(imgDilate1, diamond)  # 用菱形结构元腐蚀图像

    imgDilate2 = cv2.dilate(imgGray, xShape)  # 使用 X 形结构元膨胀原图像
    imgErode2 = cv2.erode(imgDilate2, square)  # 使用方形结构元腐蚀图像

    imgDiff = cv2.absdiff(imgErode2, imgErode1)  # 将两幅闭运算的图像相减获得角点
    retval, thresh = cv2.threshold(imgDiff, 40, 255, cv2.THRESH_BINARY)  # # 二值化处理

    # 在原图上用半径为 5 的圆圈标记角点
    for j in range(thresh.size):
        y = int(j / thresh.shape[0])
        x = int(j % thresh.shape[0])
        if (thresh[x, y] == 255):
            cv2.circle(imgSign, (y, x), 5, (255, 0, 255))

    plt.figure(figsize=(9, 6))
    plt.subplot(131), plt.title("Origin"), plt.axis('off')
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    plt.subplot(132), plt.title("Edge"), plt.axis('off')
    plt.imshow(imgEdge, cmap='gray', vmin=0, vmax=255)
    plt.subplot(133), plt.title("Corner"), plt.axis('off')
    plt.imshow(cv2.cvtColor(imgSign, cv2.COLOR_BGR2RGB))
    plt.tight_layout()
    plt.show()

在这里插入图片描述


(本节完)


版权声明:

youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/123786155)

Copyright 2022 youcans, XUPT
Crated:2022-3-30


举报

相关推荐

0 条评论