add ArUco but no activated
This commit is contained in:
@@ -8,7 +8,7 @@ import _thread
|
||||
import json
|
||||
import os
|
||||
import binascii
|
||||
from maix import time, camera
|
||||
from maix import time
|
||||
import threading
|
||||
import config
|
||||
from logger_manager import logger_manager
|
||||
@@ -861,7 +861,8 @@ class LaserManager:
|
||||
center_temp = None
|
||||
radius_temp = None
|
||||
if config.LASER_REQUIRE_IN_ELLIPSE:
|
||||
result_img_temp, center_temp, radius_temp, method_temp, best_radius1_temp, ellipse_params_temp = vision.detect_circle_v3(frame, None)
|
||||
# 使用统一的检测接口(支持ArUco和传统方法)
|
||||
result_img_temp, center_temp, radius_temp, method_temp, best_radius1_temp, ellipse_params_temp = vision.detect_target(frame, None)
|
||||
|
||||
# 只有检测到靶心时才继续处理激光点
|
||||
if center_temp is None or radius_temp is None:
|
||||
@@ -1114,7 +1115,7 @@ class LaserManager:
|
||||
|
||||
return self._laser_point is not None
|
||||
|
||||
def compute_laser_position(self, circle_center, laser_point, radius, method):
|
||||
def compute_laser_position(self, circle_center, laser_point, radius, method, ellipse_params=None):
|
||||
"""计算激光相对于靶心的偏移量(单位:厘米)
|
||||
|
||||
Args:
|
||||
@@ -1122,6 +1123,7 @@ class LaserManager:
|
||||
laser_point: 激光点坐标 (x, y)
|
||||
radius: 靶心半径(像素)
|
||||
method: 检测方法("模糊" 或其他)
|
||||
ellipse_params: 椭圆参数,用于透视校正(可选)
|
||||
|
||||
Returns:
|
||||
(dx, dy): 激光相对于靶心的偏移量(厘米),如果输入无效则返回 (None, None)
|
||||
@@ -1131,6 +1133,14 @@ class LaserManager:
|
||||
|
||||
cx, cy = circle_center
|
||||
lx, ly = laser_point
|
||||
|
||||
# 如果有椭圆参数,使用透视校正计算
|
||||
if ellipse_params is not None and method != "aruco":
|
||||
return self._compute_with_perspective_correction(
|
||||
circle_center, laser_point, radius, ellipse_params
|
||||
)
|
||||
|
||||
# 传统计算方法
|
||||
# r = 22.16 * 5
|
||||
r = radius * 5
|
||||
self.logger.debug(f"compute_laser_position: circle_center: {circle_center} laser_point: {laser_point} radius: {radius} method: {method} r: {r}")
|
||||
@@ -1138,6 +1148,87 @@ class LaserManager:
|
||||
target_y = (ly-cy)/r*100
|
||||
self.logger.info(f"lx:{lx} ly: {ly} cx: {cx} cy: {cy} result_x: {target_x} result_y: {-target_y} real_r_x: {lx-cx} real_r_y: {-1*(ly-cy)}")
|
||||
return (target_x, -target_y)
|
||||
|
||||
def _compute_with_perspective_correction(self, circle_center, laser_point, radius, ellipse_params):
|
||||
"""
|
||||
使用透视校正计算激光偏移
|
||||
|
||||
当相机不正对靶子时,圆会变成椭圆。使用椭圆参数进行透视校正,
|
||||
将图像坐标转换到物理坐标系,再计算偏移。
|
||||
|
||||
Args:
|
||||
circle_center: 靶心中心坐标 (x, y)
|
||||
laser_point: 激光点坐标 (x, y)
|
||||
radius: 靶心半径(像素)
|
||||
ellipse_params: ((center_x, center_y), (width, height), angle)
|
||||
|
||||
Returns:
|
||||
(dx, dy): 校正后的偏移量(厘米)
|
||||
"""
|
||||
import math
|
||||
|
||||
try:
|
||||
(ex, ey), (width, height), angle = ellipse_params
|
||||
cx, cy = circle_center
|
||||
lx, ly = laser_point
|
||||
|
||||
# 步骤1: 平移到椭圆中心
|
||||
dx1 = lx - cx
|
||||
dy1 = ly - cy
|
||||
|
||||
# 步骤2: 旋转坐标系,使椭圆轴与坐标轴对齐
|
||||
angle_rad = math.radians(-angle)
|
||||
cos_a = math.cos(angle_rad)
|
||||
sin_a = math.sin(angle_rad)
|
||||
|
||||
x_rot = dx1 * cos_a - dy1 * sin_a
|
||||
y_rot = dx1 * sin_a + dy1 * cos_a
|
||||
|
||||
# 步骤3: 归一化到单位圆
|
||||
# 椭圆半轴
|
||||
a = width / 2.0
|
||||
b = height / 2.0
|
||||
|
||||
# 归一化坐标
|
||||
if a > 0 and b > 0:
|
||||
x_norm = x_rot / a
|
||||
y_norm = y_rot / b
|
||||
else:
|
||||
x_norm = x_rot
|
||||
y_norm = y_rot
|
||||
|
||||
# 步骤4: 计算物理距离
|
||||
# 使用平均半径作为参考
|
||||
avg_radius = (a + b) / 2.0
|
||||
pixels_per_cm = avg_radius / 20.0 # 假设靶心半径20cm对应avg_radius像素
|
||||
|
||||
if pixels_per_cm > 0:
|
||||
# 归一化距离(单位:靶心半径的倍数)
|
||||
norm_distance = math.sqrt(x_norm**2 + y_norm**2)
|
||||
# 转换为厘米(假设靶心半径20cm)
|
||||
distance_cm = norm_distance * 20.0
|
||||
|
||||
# 计算方向
|
||||
angle_offset = math.atan2(y_norm, x_norm)
|
||||
|
||||
dx_cm = distance_cm * math.cos(angle_offset)
|
||||
dy_cm = -distance_cm * math.sin(angle_offset) # Y轴翻转
|
||||
|
||||
self.logger.debug(f"[PERSPECTIVE] 原始偏移: ({dx1:.1f}, {dy1:.1f})px, "
|
||||
f"校正后: ({dx_cm:.2f}, {dy_cm:.2f})cm, "
|
||||
f"椭圆: ({width:.1f}, {height:.1f}), 角度: {angle:.1f}°")
|
||||
|
||||
return (dx_cm, dy_cm)
|
||||
else:
|
||||
# 回退到直接计算
|
||||
r = radius * 5
|
||||
return ((lx-cx)/r*100, -(ly-cy)/r*100)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"[PERSPECTIVE] 透视校正计算失败: {e}")
|
||||
# 回退到直接计算
|
||||
r = radius * 5
|
||||
return ((lx-cx)/r*100, -(ly-cy)/r*100)
|
||||
|
||||
# # 根据检测方法动态调整靶心物理半径(简化模型)
|
||||
# circle_r = (radius / 4.0) * 20.0 if method == "模糊" else (68 / 16.0) * 20.0
|
||||
|
||||
Reference in New Issue
Block a user