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

如何用OpenCV获取角点(x,y)坐标及不同背景下台球桌定位

问题解答

1. 用OpenCV查找角点(x, y)坐标

OpenCV提供了多种成熟的角点检测方案,常用的有Harris角点检测和Shi-Tomasi角点检测,具体实现如下:

Harris角点检测

import cv2 as cv
import numpy as np

img = cv.imread("your_image.png")
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
gray = np.float32(gray)

# 执行Harris角点检测
dst = cv.cornerHarris(gray, 2, 3, 0.04)
# 膨胀结果便于标记角点
dst = cv.dilate(dst, None)
# 阈值化筛选角点
threshold = 0.01 * dst.max()
corners = np.where(dst > threshold)
# 转换为(x,y)坐标格式
corner_coords = [(x, y) for y, x in zip(corners[0], corners[1])]

# 可视化角点
img[dst > threshold] = [0, 0, 255]
cv.imshow("Harris Corners", img)
cv.waitKey(0)
cv.destroyAllWindows()

Shi-Tomasi角点检测(稳定性更强)

import cv2 as cv
import numpy as np

img = cv.imread("your_image.png")
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 检测指定数量的最强角点
corners = cv.goodFeaturesToTrack(gray, maxCorners=100, qualityLevel=0.01, minDistance=10)
corners = np.int0(corners)

# 提取(x,y)坐标
corner_coords = [(corner[0][0], corner[0][1]) for corner in corners]

# 可视化角点
for corner in corners:
    x, y = corner.ravel()
    cv.circle(img, (x, y), 3, (0, 255, 0), -1)
cv.imshow("Shi-Tomasi Corners", img)
cv.waitKey(0)
cv.destroyAllWindows()

2. 提取台球桌轮廓及球袋坐标

针对背景存在差异的台球桌图像,可通过预处理+边缘检测+直线拟合+交点计算的流程提取桌台轮廓,再基于轮廓定位球袋(标准台球桌共6个球袋:4个角点+2个侧边中点),优化后的代码如下:

import cv2 as cv
import numpy as np

def get_table_corners(lines):
    # 分类直线为水平/垂直方向
    horizontal_lines = []
    vertical_lines = []
    for line in lines:
        x1, y1, x2, y2 = line[0]
        # 通过斜率区分水平/垂直线
        if abs(y2 - y1) < abs(x2 - x1):
            horizontal_lines.append((y1 + y2) / 2)
        else:
            vertical_lines.append((x1 + x2) / 2)
    
    # 筛选最外沿的水平/垂直直线
    horizontal_lines = sorted(horizontal_lines)
    vertical_lines = sorted(vertical_lines)
    top_y, bottom_y = horizontal_lines[0], horizontal_lines[-1]
    left_x, right_x = vertical_lines[0], vertical_lines[-1]
    
    # 返回四个角点坐标
    return [(left_x, top_y), (right_x, top_y), (right_x, bottom_y), (left_x, bottom_y)]

# 读取图像
img = cv.imread(cv.samples.findFile('1.png'))
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 预处理:高斯模糊降低噪声干扰
blurred = cv.GaussianBlur(gray, (5, 5), 0)
# Canny边缘检测
edges = cv.Canny(blurred, 50, 150, apertureSize=3)
# 霍夫直线检测,调整参数适配台球桌线条
lines = cv.HoughLinesP(edges, 1, np.pi/180, threshold=80, minLineLength=100, maxLineGap=20)

if lines is not None:
    # 获取台球桌四个角点
    table_corners = get_table_corners(lines)
    # 绘制橙色桌台轮廓(匹配示例样式)
    for i in range(4):
        cv.line(img, (int(table_corners[i][0]), int(table_corners[i][1])), 
                (int(table_corners[(i+1)%4][0]), int(table_corners[(i+1)%4][1])), 
                (0, 165, 255), 3)
    
    # 提取6个球袋坐标
    pocket_coords = table_corners.copy()
    # 添加上下侧边中点
    pocket_coords.append(((left_x + right_x)/2, top_y))
    pocket_coords.append(((left_x + right_x)/2, bottom_y))
    # 标记球袋位置
    for (x, y) in pocket_coords:
        cv.circle(img, (int(x), int(y)), 5, (0, 0, 255), -1)

cv.imshow('台球桌轮廓与球袋', img)
cv.waitKey(0)
cv.destroyAllWindows()

关键优化说明

  • 新增高斯模糊预处理,过滤背景噪声对边缘检测的干扰
  • 调整霍夫直线检测参数,提升桌台线条的识别精度
  • 加入直线分类逻辑,精准筛选桌台最外沿的四条边,计算得到准确角点
  • 基于标准台球桌结构直接推导球袋坐标,无需额外检测

内容的提问来源于stack exchange,提问作者Mojtaba

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 00:22:54