形态学 - 骨架

目录

1. 介绍

2. 代码讲解

3. code


1. 介绍

骨架的定义很简单:

就是目标的前景像素点集合内部最大的内切圆盘,将所有的内切圆盘的圆心连起来就是骨架

形态学 - 骨架_第1张图片

 

形态学的骨架抽取是根据腐蚀和开运算定义的:

形态学 - 骨架_第2张图片

  • 这里的S(A) 就是骨架,Sk(A) 是骨架的子集
  • 第二个公式的意思就是,将前景像素做K次腐蚀,每次腐蚀完的时候,将腐蚀图做开运算(因为开运算是原图的子集) 。将腐蚀前的图片 - 开运算后的图像 做骨架的子集
  • 每次K腐蚀一次就得到一个子集,K停止的条件是腐蚀之后,A为空集
  • 最后将所有的子集相加

这里我们还是对二值图像处理

2. 代码讲解

骨架抽取的算法为:

具体的实现步骤是:

1. 建立一个canvas,用来保存骨架的子集或者全集。并建立3*3 十字架的结构元

2. 做循环迭代,循环停止的条件是原图被腐蚀成空集。img.any() 可以理解为,img 这个二维矩阵里,所有元素为零的话,返回False

3. 对原图做开运算,然后得到原图和开图像的差。这里减号不会溢出,因为二值图像非0即255,而开图像一定是原图像的子集,所以不会溢出

4. 将结果并在canvas里面,这里canvas 和自己并的话就是可以当骨架子集,又可以当骨架全集

5. 腐蚀原图

形态学 - 骨架_第3张图片

 

3. code

代码为:

import numpy as np
import cv2


def skeleton_extraction(img):          # 骨架抽取算法

    canvas = np.zeros(img.shape,dtype=np.uint8)                # 将结果保留在这
    kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))  # 3*3 方形结构元

    while img.any():     # 循环迭代

        img_open = cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)      # 做开运算
        img_diff = img - img_open                                   # 原图 - 开运算图
        canvas = cv2.bitwise_or(canvas,img_diff)                    # 将结果并在一起
        img = cv2.erode(img,kernel)                                 # 腐蚀

    dst = canvas                            #  dst 返回的图片
    return dst.astype(np.uint8)


img = cv2.imread('./c.png',0)
_, img_bin = cv2.threshold(img,100,255,cv2.THRESH_BINARY)        # 二值化处理
ret = skeleton_extraction(img_bin.copy())          # 传入拷贝图像

cv2.imshow('img',np.hstack((img_bin,ret)))
cv2.waitKey()
cv2.destroyAllWindows()

图像顺序为:

原图、骨架

形态学 - 骨架_第4张图片

 

你可能感兴趣的:(数字图像处理,python,算法,图像处理,opencv)