如何判断随机坐标是否在YOLOv8输出的分割Segment范围内?
解决YOLOv8 Segment坐标点归属判断的几种方案
方法一:用OpenCV的点多边形测试(推荐,轻量且准确)
YOLO输出的segment是二维点集,直接用OpenCV的cv2.pointPolygonTest()函数即可判断点是否在多边形内,该函数对非凸多边形完全支持:返回值>0表示点在内部,=0表示在边线上,<0表示在外部。
示例代码:
import cv2 import numpy as np from ultralytics import YOLO model = YOLO('yolov8x-seg.pt') outputs = model('image.jpg', return_outputs=True) # 待判断的随机坐标,格式为(x, y) test_point = (100, 200) for output in outputs: for segment in output['segment']: # 转换为OpenCV要求的np.int32格式 poly = np.array(segment, np.int32).reshape((-1, 1, 2)) # 第三个参数设为False,仅判断归属不计算距离 result = cv2.pointPolygonTest(poly, test_point, False) if result > 0: print(f"点{test_point}在当前segment范围内") elif result == 0: print(f"点{test_point}在当前segment的边缘上") else: print(f"点{test_point}不在当前segment范围内")
方法二:用NumPy实现射线法(无额外依赖)
如果不想引入OpenCV依赖,可以自己实现射线法:从测试点向右发射一条射线,统计与多边形边的交点数,奇数则点在内部,偶数则在外部,对非凸多边形同样适用。
示例代码:
import numpy as np from ultralytics import YOLO def point_in_polygon(point, polygon): x, y = point inside = False n = len(polygon) for i in range(n): p1x, p1y = polygon[i] p2x, p2y = polygon[(i+1)%n] # 判断点是否处于边的y值区间内 if ((p1y > y) != (p2y > y)): # 计算射线与边的x轴交点 x_intersect = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x if x < x_intersect: inside = not inside return inside model = YOLO('yolov8x-seg.pt') outputs = model('image.jpg', return_outputs=True) test_point = (100, 200) for output in outputs: for segment in output['segment']: if point_in_polygon(test_point, segment): print(f"点{test_point}在当前segment范围内") else: print(f"点{test_point}不在当前segment范围内")
关于Shapely的补充说明
你担心Shapely的Polygon类有限制其实没必要,它完全支持非凸多边形,甚至带孔的多边形也能处理,只是需要额外安装依赖。如果使用的话,代码非常简洁:
from shapely.geometry import Point, Polygon from ultralytics import YOLO model = YOLO('yolov8x-seg.pt') outputs = model('image.jpg', return_outputs=True) test_point = Point(100, 200) for output in outputs: for segment in output['segment']: poly = Polygon(segment) if poly.contains(test_point): print(f"点{test_point}在当前segment范围内") elif poly.touches(test_point): print(f"点{test_point}在当前segment的边缘上") else: print(f"点{test_point}不在当前segment范围内")
内容的提问来源于stack exchange,提问作者aspyct
相关产品推荐
相关产品推荐

