如何用OpenCV获取轮廓两点间折线及指定红色多边形?
在Python+OpenCV中定位红色多边形
问题说明
已知点A、B、C的坐标,以及图像的宽度(image_w)和高度(image_h),需要找到图中红色绘制的闭合多边形。目前已通过代码找到射线B→A、B→C与图像边界的交点A和C,当前代码及运行结果如下:
当前代码实现
line_end_1 = None line_end_2 = None print(f"线段列表(A-B、B-C): {line_list}") print(f"点B: {center_start}") for line in line_list: # 图像四条边界的线段集合 contours = [[(0,0),(image_w,0)],[(image_w,0),(image_w, image_h)],[(image_w, image_h),(0,image_h)],[(0, image_h),(0,0)]] for contour in contours: line_end = find_intersection(line, contour) if line_end_1 is None and line_end is not None: line_end_1 = line_end print(f"点A: {line_end_1}") elif line_end_2 is None and line_end is not None: line_end_2 = line_end print(f"点C: {line_end_2}")
运行结果示例
线段列表(A-B、B-C): [[(150, 275), (869, 625)], [(150, 275), (620, -372)]] 点B: (150, 275) 点A: (571, 480) 点C: (349, 0)
解决方案
红色多边形是由点A、B、C,加上图像边界上连接A和C的路径共同构成的闭合区域。具体实现步骤如下:
1. 优化交点检测逻辑
当前代码全局收集前两个交点,容易出现顺序混乱。建议针对每条射线单独查找与图像边界的唯一交点:
# 定义图像四条边界线段 image_edges = [ [(0, 0), (image_w, 0)], # 顶部边界 [(image_w, 0), (image_w, image_h)], # 右侧边界 [(image_w, image_h), (0, image_h)], # 底部边界 [(0, image_h), (0, 0)] # 左侧边界 ] ray_intersections = [] # 遍历每条从B出发的射线 for ray in line_list: for edge in image_edges: intersect = find_intersection(ray, edge) if intersect is not None: ray_intersections.append(intersect) break # 射线与矩形边界仅一个交点,找到即停止 # 提取A、C两点(确保顺序与line_list对应) point_A, point_C = ray_intersections point_B = center_start
2. 生成图像边界连接路径
确定A、C所在的图像边界,生成连接两点的图像边界顶点序列:
def get_edge_index(point, img_w, img_h): """判断点位于图像的哪条边界""" x, y = point if y == 0: return 0 # 顶部 elif x == img_w: return 1 # 右侧 elif y == img_h: return 2 # 底部 elif x == 0: return 3 # 左侧 return -1 # 获取A、C所在的边界索引 edge_A = get_edge_index(point_A, image_w, image_h) edge_C = get_edge_index(point_C, image_w, image_h) # 图像四个顶点按顺时针顺序 corner_points = [(0,0), (image_w,0), (image_w,image_h), (0,image_h)] # 生成从A到C的图像边界路径 boundary_path = [point_A] current_edge = edge_A while current_edge != edge_C: # 添加当前边界的终点(即图像顶点) boundary_path.append(corner_points[(current_edge + 1) % 4]) current_edge = (current_edge + 1) % 4 boundary_path.append(point_C)
3. 构建完整多边形并绘制
拼接顶点序列,生成闭合多边形后用OpenCV绘制:
import cv2 import numpy as np # 构建完整的多边形顶点顺序:A→B→C→[图像边界从C到A的反向路径] polygon_vertices = [point_A, point_B, point_C] + boundary_path[::-1][1:] # 转换为OpenCV要求的格式 polygon_np = np.array(polygon_vertices, np.int32) polygon_np = polygon_np.reshape((-1, 1, 2)) # 绘制红色闭合多边形(thickness为负数时填充内部) cv2.polylines(image, [polygon_np], isClosed=True, color=(0, 0, 255), thickness=2) # 若需要填充多边形,使用fillPoly # cv2.fillPoly(image, [polygon_np], color=(0, 0, 255))
关键说明
- 确保
find_intersection函数能正确计算线段(射线)与直线的交点,且返回的交点位于图像边界线段的范围内 - 多边形顶点顺序需保持顺时针或逆时针,否则OpenCV绘制可能出现异常
内容的提问来源于stack exchange,提问作者Simone Allegra
相关产品推荐
相关产品推荐

