*本文介绍图像形态学的应用和使用图像形态学进行骨架提取算法。核心心代码均来自互联网。*
一、提取水平垂直线
示例1 五线谱
#! /usr/bin/env python # -*- coding:utf-8 -*- import cv2 src = cv2.imread("1.png") gray_src = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) cv2.imshow("input image", src) cv2.imshow("gray image", gray_src) gray_src = cv2.bitwise_not(gray_src) binary_src = cv2.adaptiveThreshold(gray_src, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 15, -2) cv2.imshow("binary_src", binary_src) # 提取水平线 #hline = cv2.getStructuringElement(cv2.MORPH_RECT, ((src.shape[1] // 16), 1), (-1, -1)) # 提取垂直线 vline = cv2.getStructuringElement(cv2.MORPH_RECT, (1, (src.shape[0] // 16)), (-1, -1)) # 形态学的开操作——先腐蚀再膨胀,合并用morphologyEx # temp = cv2.erode(binary_src, hline) # dst = cv2.dilate(temp, hline) dst = cv2.morphologyEx(binary_src, cv2.MORPH_OPEN, vline) dst = cv2.bitwise_not(dst) cv2.imshow("Final image", dst) cv2.waitKey(0)
示例2 三线格
#! /usr/bin/env python # -*- coding:utf-8 -*- import cv2 src = cv2.imread("1.png") gray_src = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) cv2.imshow("input image", src) cv2.imshow("gray image", gray_src) gray_src = cv2.bitwise_not(gray_src) binary_src = cv2.adaptiveThreshold(gray_src, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 15, -2) cv2.imshow("binary_src", binary_src) # 提取垂直线 vline = cv2.getStructuringElement(cv2.MORPH_RECT, (1, (src.shape[0] // 29)), (-1, -1)) # 形态学的开操作——先腐蚀再膨胀,合并用morphologyEx dst = cv2.morphologyEx(binary_src, cv2.MORPH_OPEN, vline) dst = cv2.bitwise_not(dst) cv2.imshow("Final image", dst) cv2.waitKey(0)
二、形态学骨架提取
图像骨架提取是提取目标在图像上的中心像素轮廓。关于骨架提取,现存的算法有一千种以上,分为迭代和非迭代两大类。在迭代算法中,又分为并行迭代和顺序迭代两种。使用腐蚀和膨胀操作就可以获得图像骨架。
#! /usr/bin/env python # -*- coding:utf-8 -*- import numpy as np import cv2 import sys im_path = 'hello.png' im = cv2.imread(im_path, 0) if im is None: sys.exit() ret, im = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY) element = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3)) skel = np.zeros(im.shape, np.uint8) erode = np.zeros(im.shape, np.uint8) temp = np.zeros(im.shape, np.uint8) i = 0 while True: cv2.imshow('im %d' % i, im) erode = cv2.erode(im, element) temp = cv2.dilate(erode, element) # 消失的像素是skeleton的一部分 temp = cv2.subtract(im, temp) skel = cv2.bitwise_or(skel, temp) im = erode.copy() if cv2.countNonZero(im) == 0: break; i += 1 cv2.imshow('Skeleton', skel) cv2.waitKey()