#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
离线测试脚本：直接复用 detect_circle 逻辑进行测试
运行环境：MaixPy (Sipeed MAIX)
"""
import sys
import os
# import time
from maix import image,time
import cv2
import numpy as np

# ==================== 全局配置 (与 test_main.py 保持一致) ====================
REAL_RADIUS_CM = 20  # 靶心实际半径（厘米）

# ==================== 复制的核心算法 ====================
# 注意：这里直接复制了 detect_circle 的逻辑，避免 import main 导致的冲突


def detect_circle_v3(frame, laser_point=None):
    """检测图像中的靶心（优先清晰轮廓，其次黄色区域）- 返回椭圆参数版本
    增加红色圆圈检测，验证黄色圆圈是否为真正的靶心
    如果提供 laser_point，会选择最接近激光点的目标
    
    Args:
        frame: 图像帧
        laser_point: 激光点坐标 (x, y)，用于多目标场景下的目标选择
    
    Returns:
        (result_img, best_center, best_radius, method, best_radius1, ellipse_params)
    """
    img_cv = image.image2cv(frame, False, False)
    
    best_center = best_radius = best_radius1 = method = None
    ellipse_params = None
    
    # HSV 黄色掩码检测（模糊靶心）
    hsv = cv2.cvtColor(img_cv, cv2.COLOR_RGB2HSV)
    h, s, v = cv2.split(hsv)

    # 调整饱和度策略：稍微增强，不要过度
    s = np.clip(s * 1.1, 0, 255).astype(np.uint8) 

    hsv = cv2.merge((h, s, v))

    # 放宽 HSV 阈值范围（针对模糊图像的关键调整）
    lower_yellow = np.array([7, 80, 0])   # 饱和度下限降低，捕捉淡黄色
    upper_yellow = np.array([32, 255, 255]) # 亮度上限拉满

    mask_yellow = cv2.inRange(hsv, lower_yellow, upper_yellow)

    # 调整形态学操作
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    mask_yellow = cv2.morphologyEx(mask_yellow, cv2.MORPH_CLOSE, kernel) 

    contours_yellow, _ = cv2.findContours(mask_yellow, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 存储所有有效的黄色-红色组合
    valid_targets = []
    
    if contours_yellow:
        for cnt_yellow in contours_yellow:
            area = cv2.contourArea(cnt_yellow)
            perimeter = cv2.arcLength(cnt_yellow, True)

            # 计算圆度
            if perimeter > 0:
                circularity = (4 * np.pi * area) / (perimeter * perimeter)
            else:
                circularity = 0

            logger = get_logger()
            if area > 50 and circularity > 0.7:
                if logger:
                    logger.info(f"[target] -> 面积:{area}, 圆度:{circularity:.2f}")
                # 尝试拟合椭圆
                yellow_center = None
                yellow_radius = None
                yellow_ellipse = None
                
                if len(cnt_yellow) >= 5:
                    (x, y), (width, height), angle = cv2.fitEllipse(cnt_yellow)
                    yellow_ellipse = ((x, y), (width, height), angle)
                    axes_minor = min(width, height)
                    radius = axes_minor / 2
                    yellow_center = (int(x), int(y))
                    yellow_radius = int(radius)
                else:
                    (x, y), radius = cv2.minEnclosingCircle(cnt_yellow)
                    yellow_center = (int(x), int(y))
                    yellow_radius = int(radius)
                    yellow_ellipse = None

                # 如果检测到黄色圆圈，再检测红色圆圈进行验证
                if yellow_center and yellow_radius:
                    # HSV 红色掩码检测（红色在HSV中跨越0度，需要两个范围）
                    # 红色范围1: 0-10度（接近0度的红色）
                    lower_red1 = np.array([0, 80, 0])
                    upper_red1 = np.array([10, 255, 255])
                    mask_red1 = cv2.inRange(hsv, lower_red1, upper_red1)
                    
                    # 红色范围2: 170-180度（接近180度的红色）
                    lower_red2 = np.array([170, 80, 0])
                    upper_red2 = np.array([180, 255, 255])
                    mask_red2 = cv2.inRange(hsv, lower_red2, upper_red2)
                    
                    # 合并两个红色掩码
                    mask_red = cv2.bitwise_or(mask_red1, mask_red2)
                    
                    # 形态学操作
                    kernel_red = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
                    mask_red = cv2.morphologyEx(mask_red, cv2.MORPH_CLOSE, kernel_red)
                    
                    contours_red, _ = cv2.findContours(mask_red, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
                    
                    found_valid_red = False
                    
                    if contours_red:
                        # 找到所有符合条件的红色圆圈
                        for cnt_red in contours_red:
                            area_red = cv2.contourArea(cnt_red)
                            perimeter_red = cv2.arcLength(cnt_red, True)
                            
                            if perimeter_red > 0:
                                circularity_red = (4 * np.pi * area_red) / (perimeter_red * perimeter_red)
                            else:
                                circularity_red = 0
                            
                            # 红色圆圈也应该有一定的圆度
                            if area_red > 50 and circularity_red > 0.6:
                                # 计算红色圆圈的中心和半径
                                if len(cnt_red) >= 5:
                                    (x_red, y_red), (w_red, h_red), angle_red = cv2.fitEllipse(cnt_red)
                                    radius_red = min(w_red, h_red) / 2
                                    red_center = (int(x_red), int(y_red))
                                    red_radius = int(radius_red)
                                else:
                                    (x_red, y_red), radius_red = cv2.minEnclosingCircle(cnt_red)
                                    red_center = (int(x_red), int(y_red))
                                    red_radius = int(radius_red)
                                
                                # 计算黄色和红色圆心的距离
                                if red_center:
                                    dx = yellow_center[0] - red_center[0]
                                    dy = yellow_center[1] - red_center[1]
                                    distance = np.sqrt(dx*dx + dy*dy)
                                    
                                    # 圆心距离阈值：应该小于黄色半径的某个倍数（比如1.5倍）
                                    max_distance = yellow_radius * 1.5
                                    
                                    # 红色圆圈应该比黄色圆圈大（外圈）
                                    if distance < max_distance and red_radius > yellow_radius * 0.8:
                                        found_valid_red = True
                                        logger = get_logger()
                                        if logger:
                                            logger.info(f"[target] -> 找到匹配的红圈: 黄心({yellow_center}), 红心({red_center}), 距离:{distance:.1f}, 黄半径:{yellow_radius}, 红半径:{red_radius}")
                                        
                                        # 记录这个有效目标
                                        valid_targets.append({
                                            'center': yellow_center,
                                            'radius': yellow_radius,
                                            'ellipse': yellow_ellipse,
                                            'area': area
                                        })
                                        break
                    
                    if not found_valid_red:
                        logger = get_logger()
                        if logger:
                            logger.debug("Debug -> 未找到匹配的红色圆圈，可能是误识别")
    
    # 从所有有效目标中选择最佳目标
    if valid_targets:
        if laser_point:
            # 如果有激光点，选择最接近激光点的目标
            best_target = None
            min_distance = float('inf')
            for target in valid_targets:
                dx = target['center'][0] - laser_point[0]
                dy = target['center'][1] - laser_point[1]
                distance = np.sqrt(dx*dx + dy*dy)
                if distance < min_distance:
                    min_distance = distance
                    best_target = target
            if best_target:
                best_center = best_target['center']
                best_radius = best_target['radius']
                ellipse_params = best_target['ellipse']
                method = "v3_ellipse_red_validated_laser_selected"
                best_radius1 = best_radius * 5
        else:
            # 如果没有激光点，选择面积最大的目标
            best_target = max(valid_targets, key=lambda t: t['area'])
            best_center = best_target['center']
            best_radius = best_target['radius']
            ellipse_params = best_target['ellipse']
            method = "v3_ellipse_red_validated"
            best_radius1 = best_radius * 5

    result_img = image.cv2image(img_cv, False, False)
    return result_img, best_center, best_radius, method, best_radius1, ellipse_params

def detect_circle(frame):
    """检测图像中的靶心（优先清晰轮廓，其次黄色区域）"""
    img_cv = image.image2cv(frame, False, False)
    # gray = cv2.cvtColor(img_cv, cv2.COLOR_RGB2GRAY)
    # blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    # edged = cv2.Canny(blurred, 50, 150)
    # kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    # ceroded = cv2.erode(cv2.dilate(edged, kernel), kernel)

    # contours, _ = cv2.findContours(ceroded, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    # best_center = best_radius = best_radius1 = method = None

    # hsv = cv2.cvtColor(img_cv, cv2.COLOR_RGB2HSV)
    # h, s, v = cv2.split(hsv)
    # s = np.clip(s * 2, 0, 255).astype(np.uint8)
    # hsv = cv2.merge((h, s, v))
    # lower_yellow = np.array([7, 80, 0])
    # upper_yellow = np.array([32, 255, 182])
    # mask = cv2.inRange(hsv, lower_yellow, upper_yellow)
    # kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    # mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
    # mask = cv2.morphologyEx(mask, cv2.MORPH_DILATE, kernel)
    # contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # if contours:
    #     largest = max(contours, key=cv2.contourArea)
    #     if cv2.contourArea(largest) > 50:
    #         (x, y), radius = cv2.minEnclosingCircle(largest)
    #         best_center = (int(x), int(y))
    #         best_radius = int(radius)
    #         best_radius1 = radius * 5
    #         method = "v2"

    # auto
    # R:31 M:v2 D:2.410110127692767
    # hsv = cv2.cvtColor(img_cv, cv2.COLOR_RGB2HSV)
    # h, s, v = cv2.split(hsv)

    # # 1. 增强饱和度（模糊照片需要更强的增强）
    # s = np.clip(s * 2.5, 0, 255).astype(np.uint8)  # 从2.0改为2.5

    # # 2. 增强亮度（模糊照片可能偏暗）
    # v = np.clip(v * 1.2, 0, 255).astype(np.uint8)  # 新增：提升亮度

    # hsv = cv2.merge((h, s, v))

    # # 3. 放宽HSV颜色范围（特别是模糊照片）
    # # 降低饱和度下限，提高亮度上限
    # lower_yellow = np.array([5, 50, 30])   # H:5-35, S:50-255, V:30-255
    # upper_yellow = np.array([35, 255, 255])

    # mask = cv2.inRange(hsv, lower_yellow, upper_yellow)

    # # 4. 增强形态学操作（连接被分割的区域）
    # kernel_small = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    # kernel_large = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))  # 更大的核

    # # 先开运算去除噪声
    # mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel_small)
    # # 多次膨胀连接区域（模糊照片需要更多膨胀）
    # mask = cv2.dilate(mask, kernel_large, iterations=2)  # 增加迭代次数
    # mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel_large)  # 闭运算填充空洞

    # contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # if contours:
    #     largest = max(contours, key=cv2.contourArea)
    #     area = cv2.contourArea(largest)
    #     if area > 50:
    #         # 5. 使用面积计算等效半径（更准确）
    #         equivalent_radius = np.sqrt(area / np.pi)
            
    #         # 6. 同时使用minEnclosingCircle作为备选（取较大值）
    #         (x, y), enclosing_radius = cv2.minEnclosingCircle(largest)
            
    #         # 取两者中的较大值，确保不遗漏
    #         radius = max(equivalent_radius, enclosing_radius)
            
    #         best_center = (int(x), int(y))
    #         best_radius = int(radius)
    #         best_radius1 = radius * 5
    #         method = "v2"

    # codegee
    # R:24 M:v2 D:3.061493895819174
    # R:22 M:v2 D:3.3644971681267077  np.clip(s * 1.1, 0, 255)
    hsv = cv2.cvtColor(img_cv, cv2.COLOR_RGB2HSV)
    h, s, v = cv2.split(hsv)

    # 2. 调整饱和度策略：
    # 不要暴力翻倍，可以尝试稍微增强，或者使用 CLAHE 增强亮度/对比度
    # 这里我们稍微增加一点饱和度，并确保不溢出
    s = np.clip(s * 1.1, 0, 255).astype(np.uint8) 
    # 对亮度通道 v 也可以做一点 CLAHE 处理来增强对比度（可选）
    # clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
    # v = clahe.apply(v)

    hsv = cv2.merge((h, s, v))

    # 3. 放宽 HSV 阈值范围（针对模糊图像的关键调整）
    # 降低 S 的下限 (80 -> 35)，提高 V 的上限 (182 -> 255)
    lower_yellow = np.array([7, 80, 0])   # 饱和度下限降低，捕捉淡黄色
    upper_yellow = np.array([32, 255, 255]) # 亮度上限拉满

    mask = cv2.inRange(hsv, lower_yellow, upper_yellow)

    # 4. 调整形态学操作
    # 去掉 MORPH_OPEN，因为它会减小面积。
    # 使用 MORPH_CLOSE (先膨胀后腐蚀) 来填充内部小黑洞，连接近邻区域
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) 
    # 再进行一次膨胀，确保边缘被包含进来
    # mask = cv2.dilate(mask, kernel, iterations=1) 

    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    if contours:
        largest = max(contours, key=cv2.contourArea)
        
        # 这里可以适当降低面积阈值，或者保持不变
        if cv2.contourArea(largest) > 50:
            # (x, y), radius = cv2.minEnclosingCircle(largest)
            # best_center = (int(x), int(y))
            # best_radius = int(radius)
            
            # --- 核心修改开始 ---
            # 1. 尝试拟合椭圆 (需要轮廓点至少为5个)
            if len(largest) >= 5:
                # 返回值: ((中心x, 中心y), (长轴, 短轴), 旋转角度)
                (x, y), (axes_major, axes_minor), angle = cv2.fitEllipse(largest)

                # 2. 计算半径
                # 选项A：取长短轴的平均值 (比较稳健)
                # radius = (axes_major + axes_minor) / 4

                # 选项B：直接取短轴的一半 (抗模糊最强，推荐)
                radius = axes_minor / 2

                best_center = (int(x), int(y))
                best_radius = int(radius)
                method = "v2_ellipse"
            else:
                # 如果点太少无法拟合椭圆，降级回 minEnclosingCircle
                (x, y), radius = cv2.minEnclosingCircle(largest)
                best_center = (int(x), int(y))
                best_radius = int(radius)
                method = "v2"
            # --- 核心修改结束 ---

            # 你的后续逻辑
            best_radius1 = radius * 5
            

    # operas 4.5
    # R:25 M:v2 D:2.9554872521538527
    # hsv = cv2.cvtColor(img_cv, cv2.COLOR_RGB2HSV)
    # h, s, v = cv2.split(hsv)
    
    # # 1. 适度增强饱和度（不要过度，否则噪声也会增强）
    # s = np.clip(s * 1.5, 0, 255).astype(np.uint8)
    # hsv = cv2.merge((h, s, v))
    
    # # 2. 放宽 HSV 阈值范围（关键改动）
    # # - 饱和度下限从 80 降到 40（捕捉淡黄色）
    # # - 亮度上限从 182 提高到 255（允许更亮的黄色）
    # lower_yellow = np.array([7, 40, 30])
    # upper_yellow = np.array([35, 255, 255])
    
    # mask = cv2.inRange(hsv, lower_yellow, upper_yellow)
    
    # # 3. 调整形态学操作：用 CLOSE 替代 OPEN
    # # CLOSE（先膨胀后腐蚀）：填充内部空洞，连接相邻区域
    # # OPEN（先腐蚀后膨胀）：会缩小区域，不适合模糊图像
    # kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7))  # 稍大的核
    # mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
    # mask = cv2.dilate(mask, kernel, iterations=1)  # 额外膨胀，确保边缘被包含
    
    # contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # if contours:
    #     largest = max(contours, key=cv2.contourArea)
    #     if cv2.contourArea(largest) > 50:
    #         (x, y), radius = cv2.minEnclosingCircle(largest)
    #         best_center = (int(x), int(y))
    #         best_radius = int(radius)
    #         best_radius1 = radius * 5
    #         method = "v2"

            # # --- 新增：将 Mask 叠加到原图上用于调试 ---
            # # 创建一个彩色掩码（红色通道为255，其他为0）
            # mask_overlay = np.zeros_like(img_cv)
            # mask_overlay[:, :, 2] = mask  # 将掩码放在红色通道 (BGR中的R)
            #
            # cv2.addWeighted(img_cv, 0.6, mask_overlay, 0.4, 0, img_cv)

    result_img = image.cv2image(img_cv, False, False)
    return result_img, best_center, best_radius, method, best_radius1


def detect_circle_v2(frame):
    """检测图像中的靶心（优先清晰轮廓，其次黄色区域）- 返回椭圆参数版本"""
    global REAL_RADIUS_CM
    img_cv = image.image2cv(frame, False, False)
    
    best_center = best_radius = best_radius1 = method = None
    ellipse_params = None  # 存储椭圆参数 ((x, y), (axes_major, axes_minor), angle)
    
    # HSV 黄色掩码检测（模糊靶心）
    hsv = cv2.cvtColor(img_cv, cv2.COLOR_RGB2HSV)
    h, s, v = cv2.split(hsv)

    # 调整饱和度策略：稍微增强，不要过度
    s = np.clip(s * 1.1, 0, 255).astype(np.uint8) 

    hsv = cv2.merge((h, s, v))

    # 放宽 HSV 阈值范围（针对模糊图像的关键调整）
    lower_yellow = np.array([7, 80, 0])   # 饱和度下限降低，捕捉淡黄色
    upper_yellow = np.array([32, 255, 255]) # 亮度上限拉满

    mask = cv2.inRange(hsv, lower_yellow, upper_yellow)

    # 调整形态学操作
    # 使用 MORPH_CLOSE (先膨胀后腐蚀) 来填充内部小黑洞，连接近邻区域
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) 

    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    if contours:
        largest = max(contours, key=cv2.contourArea)
        
        if cv2.contourArea(largest) > 50:
            # 尝试拟合椭圆 (需要轮廓点至少为5个)
            if len(largest) >= 5:
                # 返回值: ((中心x, 中心y), (width, height), 旋转角度)
                # 注意：width 和 height 是外接矩形的尺寸，不是长轴和短轴
                (x, y), (width, height), angle = cv2.fitEllipse(largest)
                
                # 保存椭圆参数（保持原始顺序，用于绘制）
                ellipse_params = ((x, y), (width, height), angle)
                
                # 计算半径：使用较小的尺寸作为短轴
                axes_minor = min(width, height)
                radius = axes_minor / 2

                best_center = (int(x), int(y))
                best_radius = int(radius)
                method = "v2_ellipse"
            else:
                # 如果点太少无法拟合椭圆，降级回 minEnclosingCircle
                (x, y), radius = cv2.minEnclosingCircle(largest)
                best_center = (int(x), int(y))
                best_radius = int(radius)
                method = "v2"
                ellipse_params = None  # 圆形，没有椭圆参数

            best_radius1 = radius * 5

    result_img = image.cv2image(img_cv, False, False)
    return result_img, best_center, best_radius, method, best_radius1, ellipse_params

# ==================== 测试逻辑 ====================

def run_offline_test(image_path):
    """读取图片，检测圆，绘制结果，保存图片"""
    
    # 1. 检查文件是否存在
    if not os.path.exists(image_path):
        print(f"[ERROR] 找不到图片文件: {image_path}")
        return

    # 2. 使用 maix.image 读取图片 (适配 MaixPy v4)
    try:
        # 使用 image.load 读取文件，返回 Image 对象
        img = image.load(image_path)
        print(f"[INFO] 成功读取图片: {image_path} (尺寸: {img.width()}x{img.height()})")
    except Exception as e:
        print(f"[ERROR] 读取图片失败: {e}")
        print("提示：请确认 MaixPy 版本是否为 v4，且图片路径正确。")
        return


    # 3. 调用 detect_circle_v2 函数
    print("[INFO] 正在调用 detect_circle_v2 进行检测...")
    start_time = time.ticks_ms()
    
    result_img, center, radius, method, radius1, ellipse_params = detect_circle_v3(img)
    
    cost_time = time.ticks_ms() - start_time
    print(f"[INFO] 检测完成，耗时: {cost_time}ms")
    print(f"       结果 -> 圆心: {center}, 半径: {radius}, 方法: {method}")
    if ellipse_params:
        (ell_center, (width, height), angle) = ellipse_params
        print(f"       椭圆 -> 中心: ({ell_center[0]:.1f}, {ell_center[1]:.1f}), 长轴: {max(width, height):.1f}, 短轴: {min(width, height):.1f}, 角度: {angle:.1f}°")

    # 4. 绘制辅助线（可选，用于调试）
    if center and radius:
        # 为了绘制椭圆，需要转换回 cv2 图像
        img_cv = image.image2cv(result_img, False, False)
        
        cx, cy = center
        
        # 如果有椭圆参数，绘制椭圆
        if ellipse_params:
            (ell_center, (width, height), angle) = ellipse_params
            cx_ell, cy_ell = int(ell_center[0]), int(ell_center[1])
            
            # 确定长轴和短轴
            if width >= height:
                # width 是长轴，height 是短轴
                axes_major = width
                axes_minor = height
                major_angle = angle  # 长轴角度就是 angle
                minor_angle = angle + 90  # 短轴角度 = 长轴角度 + 90度
            else:
                # height 是长轴，width 是短轴
                axes_major = height
                axes_minor = width
                major_angle = angle + 90  # 长轴角度 = width角度 + 90度
                minor_angle = angle  # 短轴角度就是 angle
            
            # 使用 OpenCV 绘制椭圆（绿色，线宽2）
            cv2.ellipse(img_cv, 
                    (cx_ell, cy_ell),              # 中心点
                    (int(width/2), int(height/2)), # 半宽、半高
                    angle,                          # 旋转角度（OpenCV需要原始angle）
                    0, 360,                         # 起始和结束角度
                    (0, 255, 0),                    # 绿色 (RGB格式)
                    2)                              # 线宽
            
            # 绘制椭圆中心点（红色）
            cv2.circle(img_cv, (cx_ell, cy_ell), 3, (255, 0, 0), -1)
            
            import math            
            # 绘制短轴（蓝色线条）
            minor_length = axes_minor / 2
            minor_angle_rad = math.radians(minor_angle)
            dx_minor = minor_length * math.cos(minor_angle_rad)
            dy_minor = minor_length * math.sin(minor_angle_rad)
            pt1_minor = (int(cx_ell - dx_minor), int(cy_ell - dy_minor))
            pt2_minor = (int(cx_ell + dx_minor), int(cy_ell + dy_minor))
            cv2.line(img_cv, pt1_minor, pt2_minor, (0, 0, 255), 2)  # 蓝色 (RGB格式)
        else:
            # 如果没有椭圆参数，绘制圆形（红色）
            cv2.circle(img_cv, (cx, cy), radius, (0, 0, 255), 2)
            cv2.circle(img_cv, (cx, cy), 2, (0, 0, 255), -1)
        
        # 转换回 maix image
        result_img = image.cv2image(img_cv, False, False)
        
        # 定义颜色对象用于文字
        try:
            color_black = image.Color.from_rgb(0,0,0)
        except AttributeError:
            color_black = image.Color(0,0,0)

        # D. 添加文字信息
        FOCAL_LENGTH_PIX = 1900
        d = (REAL_RADIUS_CM * FOCAL_LENGTH_PIX) / radius1 / 100.0
        info_str = f"R:{radius} M:{method} D:{d:.2f}" 
        print(info_str)
        
        # 计算文字位置，防止超出图片边界
        r_outer = int(radius * 11.0) if radius else 100
        text_y = cy - r_outer - 20 if cy > r_outer + 20 else cy + r_outer + 20
        
        # 调用 draw_string
        result_img.draw_string(0, 0, info_str, color=color_black, scale=1.0)


    # 5. 保存结果图片
    output_path = image_path.replace(".bmp", "_result.bmp")
    output_path = image_path.replace(".jpg", "_result.jpg")
    try:
        result_img.save(output_path, quality=100)
        print(f"[SUCCESS] 结果已保存至: {output_path}")
    except Exception as e:
        print(f"[ERROR] 保存图片失败: {e}")

if __name__ == "__main__":
    # ================= 配置区域 =================
    
    # 1. 设置要测试的图片路径
    # 建议将图片放在与脚本同级目录，或者使用绝对路径
    TARGET_IMAGE = "/root/phot/None_314_258_0_0041.bmp" 
    
    # TARGET_DIR = "/root/phot_test2"  # 修改为你想要读取的目录路径
    
    # 支持的图片格式
    IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.bmp']
    
    # ================= 执行区域 =================
    if 'TARGET_DIR' in locals():
        # 读取目录下所有图片文件，过滤掉 _result.jpg 后缀的文件
        image_files = []
        if os.path.exists(TARGET_DIR) and os.path.isdir(TARGET_DIR):
            for filename in os.listdir(TARGET_DIR):
                # 检查文件扩展名
                if any(filename.lower().endswith(ext) for ext in IMAGE_EXTENSIONS):
                    # 过滤掉 _result.jpg 后缀的文件
                    if not filename.endswith('_result.jpg'):
                        filepath = os.path.join(TARGET_DIR, filename)
                        if os.path.isfile(filepath):
                            image_files.append(filepath)
            
            # 按文件名排序（可选）
            image_files.sort()
            
            print(f"[INFO] 在目录 {TARGET_DIR} 中找到 {len(image_files)} 张图片")
            
            # 处理每张图片
            for img_path in image_files:
                print(f"\n{'='*10} 开始处理: {img_path} {'='*10}")
                run_offline_test(img_path)
        else:
            print(f"[ERROR] 目录不存在或不是有效目录: {TARGET_DIR}")
        
    else:
        run_offline_test(TARGET_IMAGE)
