You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断随机坐标是否在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 03:55:19