如何用CV2通过形态学操作分离图像中的线条与圆形
提取图像中线条的解决方案
图像示例

已实现的圆形提取结果

提取线条的思路与代码
既然已经成功分离出圆形区域,我们可以通过阈值化原图减去圆形区域得到线条的初步掩码,再用小尺寸结构元素做闭运算修复线条孔洞,同时避免线条粘连:
import cv2 import matplotlib.pyplot as plt def otsuThresholding(img): # 实现Otsu阈值化(转为灰度后处理) gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) _, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) return thresh # 读取并预处理图像 image = cv2.imread('sample.png') image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) thresh_img = otsuThresholding(image) # 复用你的圆形提取代码 structuringElement_circle = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (18, 18)) imageErode = cv2.erode(thresh_img, structuringElement_circle) openingCircles = cv2.dilate(imageErode, structuringElement_circle) # 1. 提取线条初始掩码:阈值化原图减去圆形区域 lines_mask = cv2.subtract(thresh_img, openingCircles) # 2. 闭运算修复线条孔洞:用小椭圆结构元素,避免线条粘连 structuringElement_line = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) lines_final = cv2.morphologyEx(lines_mask, cv2.MORPH_CLOSE, structuringElement_line) # 展示结果 plt.figure(figsize=(12, 6)) plt.subplot(131) plt.title("阈值化原图") plt.imshow(thresh_img, 'gray', vmax=255, vmin=0) plt.subplot(132) plt.title("初步线条掩码") plt.imshow(lines_mask, 'gray', vmax=255, vmin=0) plt.subplot(133) plt.title("最终提取线条") plt.imshow(lines_final, 'gray', vmax=255, vmin=0) plt.show()
关键说明
- 直接从原图减圆形区域会得到带有孔洞的线条,这是因为圆形原本覆盖了线条的部分区域。
- 使用**小尺寸椭圆结构元素(如3x3)**做闭运算,先膨胀填补孔洞,再腐蚀恢复线条原有粗细,既能修复孔洞,又不会导致线条过度加粗粘连。如果3x3效果不够,可以尝试5x5的结构元素,但不要超过线条宽度的2倍。
内容的提问来源于stack exchange,提问作者ricklink
相关产品推荐
相关产品推荐

