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

基于OpenCV Python的倾斜射击靶检测及透视校正优化需求

射击靶自动透视校正与圆环检测解决方案

问题背景

使用OpenCV完成射击靶检测任务,相机位于靶下方导致拍摄图像倾斜。手动通过findHomography执行透视变换后,靶标呈椭圆且模糊,无法自动识别靶标外圈及各圆环,需实现自动透视校正让靶标呈现标准正圆,同时完成外圈及所有圆环的检测。

解决方案步骤

1. 自动检测靶标轮廓与透视校正

手动选角误差大,改用自动流程获取靶标四个边角:

  • 对原图做灰度转换、高斯模糊、边缘检测预处理
  • 提取画面中最大轮廓(对应靶标外框),通过轮廓近似得到四边形边角
  • 根据靶标正圆属性,将变换后目标区域设为正方形,保证校正后靶标为正圆

2. 优化透视变换逻辑

之前变换后出现椭圆的核心原因是未保持靶标的正圆比例,射击靶为正圆形,因此目标透视区域必须设置为正方形,而非随意宽高。

3. 圆环检测优化

改用霍夫圆检测替代轮廓检测,更适配正圆场景;同时调整预处理流程,增强靶标圆环的对比度,提升检测精度。

完整实现代码

import cv2
import numpy as np

def auto_correct_target(image_path):
    # 读取原始图像
    original_image = cv2.imread(image_path)
    if original_image is None:
        print("无法读取目标图像")
        return
    
    # 预处理:灰度化、模糊降噪、边缘检测
    gray = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    edges = cv2.Canny(blurred, 50, 150)
    
    # 提取最大轮廓(靶标外框)
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours = sorted(contours, key=cv2.contourArea, reverse=True)
    target_contour = contours[0]
    
    # 轮廓近似为四边形边角
    peri = cv2.arcLength(target_contour, True)
    approx = cv2.approxPolyDP(target_contour, 0.02 * peri, True)
    if len(approx) != 4:
        print("未检测到靶标的四个边角")
        return
    
    # 整理并排序原始边角点(顺时针:左上、右上、右下、左下)
    original_corners = np.float32([point[0] for point in approx])
    original_corners = sorted(original_corners, key=lambda x: x[0])
    left_points = sorted(original_corners[:2], key=lambda x: x[1])
    right_points = sorted(original_corners[2:], key=lambda x: x[1])
    ordered_corners = np.float32([left_points[0], right_points[0], right_points[1], left_points[1]])
    
    # 计算靶标实际尺寸,确保变换后为正方形(正圆)
    target_size = max(
        np.linalg.norm(ordered_corners[0] - ordered_corners[1]),
        np.linalg.norm(ordered_corners[1] - ordered_corners[2]),
        np.linalg.norm(ordered_corners[2] - ordered_corners[3]),
        np.linalg.norm(ordered_corners[3] - ordered_corners[0])
    )
    target_size = int(target_size)
    
    # 定义目标透视点(正方形区域)
    new_corners = np.float32([
        [0, 0],
        [target_size - 1, 0],
        [target_size - 1, target_size - 1],
        [0, target_size - 1]
    ])
    
    # 计算透视变换矩阵并应用
    M = cv2.getPerspectiveTransform(ordered_corners, new_corners)
    corrected_image = cv2.warpPerspective(original_image, M, (target_size, target_size))
    
    # 校正后图像预处理,用于圆环检测
    corrected_gray = cv2.cvtColor(corrected_image, cv2.COLOR_BGR2GRAY)
    corrected_blurred = cv2.GaussianBlur(corrected_gray, (9, 9), 2)
    
    # 霍夫圆检测:识别所有同心圆环
    circles = cv2.HoughCircles(
        corrected_blurred,
        cv2.HOUGH_GRADIENT,
        dp=1.2,
        minDist=30,
        param1=50,
        param2=30,
        minRadius=int(target_size*0.05),
        maxRadius=int(target_size*0.5)
    )
    
    # 绘制检测到的圆环与圆心
    if circles is not None:
        circles = np.uint16(np.around(circles))
        for i in circles[0, :]:
            cv2.circle(corrected_image, (i[0], i[1]), i[2], (0, 255, 0), 2)
            cv2.circle(corrected_image, (i[0], i[1]), 2, (0, 0, 255), 3)
    
    # 显示结果
    cv2.imshow("原始图像", original_image)
    cv2.imshow("校正后图像与圆环检测", corrected_image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

# 调用函数,替换为你的图像路径
auto_correct_target("ImageLocation")

关键优化说明

  • 自动边角检测:替代手动选点,通过轮廓近似自动获取靶标边角,消除人为误差
  • 正圆比例约束:将变换后目标区域设为正方形,确保靶标从椭圆恢复为标准正圆
  • 霍夫圆检测:相比轮廓检测,更适配正圆场景,可精准识别所有同心圆环
  • 预处理优化:高斯模糊+边缘检测的组合,有效过滤噪声,提升轮廓与圆环检测的稳定性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:45:30