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

如何检测指定轮廓内的物体?解决OpenCV pointPolygonTest报错问题

球场轮廓内的球检测问题解决

报错原因分析

你遇到的pointPolygonTest报错,是因为参数完全传反且类型错误:

  • 该函数的正确调用格式是cv.pointPolygonTest(多边形轮廓, 单个点坐标, 是否返回距离)
  • 你代码里把轮廓的局部点cnt[0]和所有轮廓的列表contours传反了,而且contours是多个轮廓的集合,不是单个点,导致函数收到长度为60的序列(你的轮廓数量),而它只需要(x,y)这样的二维点。

正确实现思路

  1. 先提取球场的轮廓:通常球场是画面中面积最大的轮廓,所以从轮廓列表里筛选面积最大的那个作为球场轮廓
  2. 提取球的轮廓:通过最小外接圆判断(你原代码的逻辑可以保留)
  3. 对每个球的中心坐标,用pointPolygonTest判断是否在球场轮廓内,仅绘制符合条件的球

修正后的代码

import cv2 as cv

def get_court_contour(inputCitra):
    # 获取所有轮廓
    contours, _ = cv.findContours(inputCitra, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    # 筛选面积最大的轮廓作为球场轮廓
    if not contours:
        return None
    return max(contours, key=cv.contourArea)

def contourBola(inputCitra, outputCitra, court_contour):
    if court_contour is None:
        return
    # 获取球的轮廓
    contours, _ = cv.findContours(inputCitra, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    for cnt in contours:
        # 计算球的最小外接圆和中心
        (x,y), radius = cv.minEnclosingCircle(cnt)
        center = (int(x), int(y))
        # 判断中心是否在球场轮廓内(返回值>0表示在内部)
        if cv.pointPolygonTest(court_contour, center, False) > 0:
            # 仅绘制球场内的球
            cv.circle(outputCitra, center, int(radius), (255,0,0), 3)

# 使用示例(假设你已经有预处理后的球场二值图和球的二值图)
# court_binary = ... # 预处理后的球场二值图像
# ball_binary = ... # 预处理后的球二值图像
# output = cv.cvtColor(court_binary, cv.COLOR_GRAY2BGR) # 初始化输出图像
# court_contour = get_court_contour(court_binary)
# contourBola(ball_binary, output, court_contour)
# cv.imshow("Result", output)
# cv.waitKey(0)

额外说明

  • 注意预处理步骤:你需要分别对球场和球做二值化处理,确保inputCitra传入的是对应的二值图像(黑白,目标区域为白色)
  • 如果球场轮廓不是面积最大的,可以根据轮廓的近似多边形(比如cv.approxPolyDP)来筛选,比如球场通常是矩形或近似矩形的轮廓

内容的提问来源于stack exchange,提问作者Mr. x

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 20:15:23