灰度图像环形零件内外径区分填充的提速优化需求
快速区分环形零件内外径边缘的方案
1. 直接处理边缘坐标(最快方案)
既然已经拿到了亚像素边缘点的坐标数组,完全不用碰图像填充,直接通过几何分析区分内外径:
基于中心距离聚类:环形的内外径边缘点,到图像中心的距离会形成两个明显的数值簇:
- 计算每个边缘点到图像中心(
(图像宽/2, 图像高/2))的欧氏距离; - 用阈值分割(比如Otsu自动阈值)把距离大的归为外径边缘,小的归为内径边缘。
代码示例:
import numpy as np from skimage.filters import threshold_otsu # edges是subpixel-edges输出的Nx2坐标数组(x,y) center = np.array([image.shape[1]/2, image.shape[0]/2]) distances = np.linalg.norm(edges - center, axis=1) # 自动计算距离阈值 thresh = threshold_otsu(distances) outer_edges = edges[distances > thresh] inner_edges = edges[distances <= thresh]纯数值计算,毫秒级就能完成,完全不受图像尺寸影响。
- 计算每个边缘点到图像中心(
DBSCAN密度聚类:如果环形有轻微偏心,用密度聚类区分两个边缘簇:
from sklearn.cluster import DBSCAN # 调整eps和min_samples适配你的亚像素点密度 clustering = DBSCAN(eps=2, min_samples=10).fit(edges) labels = clustering.labels_ # 通过距离中心的均值判断哪个簇是外径 outer_label = 0 if np.mean(distances[labels==0]) > np.mean(distances[labels==1]) else 1 outer_edges = edges[labels==outer_label] inner_edges = edges[labels==1-outer_label]
2. 优化图像填充速度(保留掩码需求)
如果必须生成内外径掩码,换用OpenCV的底层实现替代skimage的形态学重建:
OpenCV的cv2.floodFill是C++优化的,速度比skimage快一个数量级,大图像也能压在0.5秒内:
import cv2 import numpy as np # 假设输入是二值边缘图 img = cv2.imread('ring_image.png', 0) h, w = img.shape # 生成外径掩码:从图像角落填充,非填充区域就是外径范围 mask_outer = np.zeros((h+2, w+2), np.uint8) cv2.floodFill(img.copy(), mask_outer, (0,0), 255) outer_mask = cv2.bitwise_not(mask_outer[1:-1,1:-1]) # 生成内径掩码:从图像中心填充,填充区域就是内径范围 mask_inner = np.zeros((h+2, w+2), np.uint8) cv2.floodFill(img.copy(), mask_inner, (w//2, h//2), 255) inner_mask = mask_inner[1:-1,1:-1]
3. 直接检测同心圆(一步到位测径)
如果是规则环形,直接用亚像素霍夫变换检测两个同心圆,直接得到内外径:
from skimage.transform import hough_circle, hough_circle_peaks # edges是二值边缘图(若已有亚像素点,可先转成二值图) # 替换成你的环形半径大致范围 hough_radii = np.arange(50, 150, 1) hough_res = hough_circle(edges, hough_radii) # 提取最明显的两个圆(对应内外径) accums, cx, cy, radii = hough_circle_peaks(hough_res, hough_radii, total_num_peaks=2) outer_radius = max(radii) inner_radius = min(radii)
内容的提问来源于stack exchange,提问作者mehmet_kacmaz_03
相关产品推荐
相关产品推荐

