8.1 Python图像处理之图像典型分割-SUSAN边缘检测

8.1 Python图像处理之图像典型分割-SUSAN边缘检测

1 算法原理

SUSAN 的全名是:Smallest Univalue Segment Assimilating Nucleus。它是一种很有特色高效的边缘和角点检测算子,它不仅可以检测图像目标的边界点,而且能够较Robust(鲁棒) 地检测目标的角点。并且具有结构保留的降噪功能,是一种基于灰度的特征点获取方法, 适用于图像中边缘和角点的检测, 可以去除图像中的噪声, 它具有简单、有效、抗噪声能力强、计算速度快的特点。

image-20210807172942449

SUSAN 边缘检测算法原理借助上图进行阐述。其中图片是白色背景,有一个颜色比较暗淡的矩形(dark area)。用一个园形模板在图像上移动,若模板内的像素灰度与模板中心的像素(被称为核 Nucleus)灰度值小于一定的阈值,则认为该点与核 Nucleus 具有相同的灰度,满足该条件的像素组成的区域就称为 USAN(Univalue Segment Assimilating Nucleus)。

在图片上有 5 个圆形区域。圆形区域表示的是掩码区域。把圆形区域内的每一个位置的像素值与圆心处的像素值相比较,那么圆中的的像素可以分为两类,一类是像素值与圆心处的像素值相近的,另一类是像素值与圆心的处的像素值相差比较大的。如果将模板中各个像素的灰度都与模板中心的核像素的灰度进行比较,那么就会发现总有一部分模板区域和灰度与核像素的灰度相同或相似,这部分区域可以称为 USAN(Univalue Segment Assimilating Nuclues).USAN 区域包含很多与图像结构有关的信息。利用这种区域的尺寸、重心、二阶矩的分析,可以得到图像中的角点,边缘等信息。从上图所示,当核像素处在图像中的灰度一致区域时,USAN 的面积会达到最大。第 e 个模板就是属于这种情况。

2 代码

运行代码说明

1.要改变代码中的图片地址(地址不能有中文)

更改put(path)函数中的路径put(r'../image/image1.jpg')

2.注意最后的plt.savefig('1.new.jpg')是保存plt图像,如果不使用可以注释掉

代码依赖包:

matplotlib  3.4.2
numpy  1.20.3
opencv-python  4.1.2.30
pillow  8.2.0
# pip安装
pip install matplotlib numpy opencv-python pillow
import cv2
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

def img_extraction(image):
    """ img_extraction 函数利用susan角点检测算法,对图像进行处理"""
    print("最小灰度值,%d" % image.min())
    print("最大灰度值,%d" % image.max())
    threshold_value = (int(image.max())-int(image.min()))/10
    print("初始阈值为: %d" % threshold_value)
    offsetX = [
                -1, 0, 1,
            -2, -1, 0, 1, 2,
        -3, -2, -1, 0, 1, 2, 3,
        -3, -2, -1, 0, 1, 2, 3,
        -3, -2, -1, 0, 1, 2, 3,
            -2, -1, 0, 1, 2,
                -1, 0, 1
        ]
    offsetY = [
                -3, -3, -3,
            -2, -2, -2, -2, -2,
        -1, -1, -1, -1, -1, -1, -1,
             0, 0, 0, 0, 0, 0, 0,
             1, 1, 1, 1, 1, 1, 1,
                2, 2, 2, 2, 2,
                   3, 3, 3
        ]
    for i in range(3, image.shape[0] - 3):     # 利用圆形模板遍历图像,计算每点处的USAN值
        for j in range(3, image.shape[1] - 3):
            same = 0
            for k in range(0, 37):
                if abs(int(image[i + int(offsetY[k]), j + int(offsetX[k]), 0]) - int(image[i, j, 0])) < threshold_value:             # 计算相似度
                        same += 1
                    # print()
            if same < 18:
                image[i, j, 0] = 18 - same
                image[i, j, 1] = 18 - same
                image[i, j, 2] = 18 - same
            else:
                image[i, j, 0] = 0
                image[i, j, 1] = 0
                image[i, j, 2] = 0
def img_revise(image):
    """img_revise 函数用于对角点处理后的图像,进行非极大值抑制修正"""
    X = [-1, -1, -1, 0, 0, 1, 1, 1]     # X轴偏移
    Y = [-1, 0, 1, -1, 1, -1, 0, 1]     # Y轴偏移
    for i in range(4, image.shape[0]-4):
        for j in range(4, image.shape[1]-4):
            flag = 0
            for k in range(0, 8):
                # print(i)
                if image[i, j, 0] <= image[int(i + X[k]), int(j + Y[k]), 0]:
                    flag += 1
                    break
            if flag == 0:       # 判断是否是周围8个点中最大的值,是则保留
                image[i, j, 0] = 255
                image[i, j, 1] = 255
                image[i, j, 2] = 255
            else:
                image[i, j, 0] = 0
                image[i, j, 1] = 0
                image[i, j, 2] = 0

def put(path):
    img = cv2.imread(path,0)
    # img = cv2.imread(os.path.join(base, path),0)
    # L为灰度 为RGB分量
    im = np.array(Image.open(path).convert('L').convert('RGB'))

    img_extraction(im)  # susan角点检测算法
    img_revise(im)  # 非极大值抑制修正

    plt.subplot(121), plt.imshow(img, "gray")
    plt.title("灰度图"), plt.axis('off')
    plt.subplot(122), plt.imshow(im, "gray")
    plt.title("susan边缘检测 "), plt.axis('off')
    # plt.savefig('1.new-img.jpg')

    plt.show()

# 图像处理函数,要传入路径
put(r'../image/image1.jpg')

3 效果

image-20210807173915051

  • 5
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值