基于OpenCV实现图像掩码转几何形状并计算各边长度的问题
针对掩码提取多边形顶点并计算边长的OpenCV实现方案
你原有方案的问题是仅提取了轮廓的四个方向极值点,无法得到多边形的全部顶点,我们可以通过轮廓多边形拟合方法实现需求,修改后的完整代码如下:
import cv2 import math def getCalculatedImg(): # 加载图像 img = cv2.imread('img.jpg') gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 阈值处理得到二值图 ret, thresh = cv2.threshold(gray_image, 50, 255, cv2.THRESH_BINARY) # 查找轮廓,取最大面积轮廓 contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) c = max(contours, key=cv2.contourArea) # 多边形拟合获取所有顶点 # 计算轮廓周长作为精度参数依据 perimeter = cv2.arcLength(c, True) # 0.01为拟合精度系数,可根据实际效果调整 epsilon = 0.01 * perimeter approx_vertices = cv2.approxPolyDP(c, epsilon, True) # 转换为坐标列表格式 vertices = [tuple(point[0]) for point in approx_vertices] vertex_count = len(vertices) # 绘制连线、顶点、计算边长 edge_lengths = [] for i in range(vertex_count): # 当前顶点和下一个顶点(最后一个顶点连回第一个顶点闭合) p1 = vertices[i] p2 = vertices[(i+1) % vertex_count] # 绘制边 cv2.line(img, p1, p2, (36, 255, 12), 2) # 绘制顶点 cv2.circle(img, p1, 8, (0, 50, 255), -1) # 计算边长(欧氏距离,单位为像素) length = math.hypot(p2[0] - p1[0], p2[1] - p1[1]) edge_lengths.append(round(length, 2)) # 可选:将边长标注在图上 mid_x = (p1[0] + p2[0]) // 2 mid_y = (p1[1] + p2[1]) // 2 cv2.putText(img, f"{edge_lengths[-1]}px", (mid_x, mid_y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2) # 输出信息 print(f"多边形顶点总数:{vertex_count}") print(f"所有顶点坐标:{vertices}") print(f"各边长度(像素):{edge_lengths}") # 保存结果 cv2.imwrite('outlined_boundered_image.jpg', img) return img
参数调整说明
- 拟合精度系数:代码中
epsilon = 0.01 * perimeter里的0.01可根据需求调整,数值越小拟合得到的顶点越多、越贴近原始轮廓,数值越大顶点越少、多边形简化程度越高 - 单位换算:当前计算得到的边长单位为像素,如果需要转换为实际物理长度,需要提前获取图像的像素比例尺做换算
内容的提问来源于stack exchange,提问作者user16731999
相关产品推荐
相关产品推荐

