From 852a948a6fde90015392aa654e828c79cd372916 Mon Sep 17 00:00:00 2001 From: havoc420ubuntu <2993167370@qq.com> Date: Tue, 27 May 2025 18:17:59 +0000 Subject: [PATCH] Refactor task navigation and enhance movement parameters - Updated task_1.py to improve navigation logic and streamline movement functions. - Enhanced task_2.py with refined movement parameters for better execution and added logging for debugging. - Adjusted function calls in main.py to reflect changes in task execution flow. --- test/task-path-track/yellow_area_demo.py | 106 ++++++++++++++++++ utils/yellow_area_analyzer.py | 132 +++++++++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 test/task-path-track/yellow_area_demo.py create mode 100644 utils/yellow_area_analyzer.py diff --git a/test/task-path-track/yellow_area_demo.py b/test/task-path-track/yellow_area_demo.py new file mode 100644 index 0000000..454cc38 --- /dev/null +++ b/test/task-path-track/yellow_area_demo.py @@ -0,0 +1,106 @@ +import cv2 +import os +import sys +import time +import argparse + +# 添加父目录到系统路径 +current_dir = os.path.dirname(os.path.abspath(__file__)) +project_root = os.path.dirname(os.path.dirname(current_dir)) +sys.path.append(project_root) + +from utils.yellow_area_analyzer import analyze_yellow_area_ratio + +def process_image(image_path, save_dir=None, show_steps=False): + """处理单张图像,分析黄色区域占比""" + print(f"处理图像: {image_path}") + + # 分析黄色区域占比 + start_time = time.time() + yellow_ratio = analyze_yellow_area_ratio(image_path, debug=show_steps, save_result=save_dir is not None) + processing_time = time.time() - start_time + + # 输出结果 + print(f"处理时间: {processing_time:.3f}秒") + print(f"黄色区域占比: {yellow_ratio:.2%}") + + if yellow_ratio > 0.5: + print("警告: 图像中黄色区域占比超过50%") + elif yellow_ratio > 0.3: + print("注意: 图像中黄色区域占比较高") + elif yellow_ratio < 0.05: + print("注意: 图像中几乎没有黄色区域") + + print("-" * 30) + + # 如果保存结果,确保目录存在 + if save_dir and not os.path.exists(save_dir): + os.makedirs(save_dir) + + return yellow_ratio + +def process_directory(dir_path, save_dir=None, show_steps=False): + """处理目录中的所有图像""" + print(f"处理目录: {dir_path}") + + # 检查目录是否存在 + if not os.path.isdir(dir_path): + print(f"错误: 目录 '{dir_path}' 不存在") + return + + # 获取目录中的所有图像文件 + image_extensions = ['.jpg', '.jpeg', '.png', '.bmp'] + image_files = [f for f in os.listdir(dir_path) + if os.path.isfile(os.path.join(dir_path, f)) and + os.path.splitext(f)[1].lower() in image_extensions] + + if not image_files: + print(f"错误: 目录 '{dir_path}' 中没有图像文件") + return + + # 处理每个图像文件 + results = {} + for image_file in image_files: + image_path = os.path.join(dir_path, image_file) + yellow_ratio = process_image(image_path, save_dir, show_steps) + results[image_file] = yellow_ratio + + # 输出统计信息 + print("=" * 50) + print(f"处理完成,共 {len(results)} 张图像") + if results: + avg_ratio = sum(results.values()) / len(results) + max_ratio = max(results.values()) + min_ratio = min(results.values()) + max_file = max(results, key=results.get) + min_file = min(results, key=results.get) + + print(f"平均黄色区域占比: {avg_ratio:.2%}") + print(f"最大黄色区域占比: {max_ratio:.2%} (文件: {max_file})") + print(f"最小黄色区域占比: {min_ratio:.2%} (文件: {min_file})") + + return results + +def main(): + parser = argparse.ArgumentParser(description='黄色区域分析演示程序') + parser.add_argument('--input', type=str, default='captured_images/test/image_20250525_090252.png', help='输入图像或目录的路径') + parser.add_argument('--output', type=str, default='./results', help='输出结果的保存路径') + parser.add_argument('--show', default=True, action='store_true', help='显示处理步骤') + + args = parser.parse_args() + + # 检查输入路径 + if not os.path.exists(args.input): + print(f"错误:路径 '{args.input}' 不存在") + return + + # 根据输入类型处理 + if os.path.isfile(args.input): + # 单个文件 + process_image(args.input, args.output, args.show) + else: + # 目录 + process_directory(args.input, args.output, args.show) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/utils/yellow_area_analyzer.py b/utils/yellow_area_analyzer.py new file mode 100644 index 0000000..006453f --- /dev/null +++ b/utils/yellow_area_analyzer.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import cv2 +import numpy as np +import os +import argparse +import matplotlib.pyplot as plt + +def analyze_yellow_area_ratio(image_path, debug=False, save_result=False): + """ + 专门针对黄色区域的分析算法 + + 参数: + image_path: 图片路径 + debug: 是否显示处理过程中的图像,用于调试 + save_result: 是否保存处理结果图像 + + 返回: + yellow_ratio: 黄色区域占比(0-1之间的浮点数) + """ + # 读取图片 + img = cv2.imread(image_path) + if img is None: + raise ValueError(f"无法读取图片: {image_path}") + + # 获取图片文件名(不带路径和扩展名) + filename = os.path.splitext(os.path.basename(image_path))[0] + + # 转换为HSV色彩空间(更适合颜色分割) + hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) + + # 提取图像的各个通道 + h, s, v = cv2.split(hsv) + + # 黄色在HSV中的范围:色调约为20-30度(OpenCV中为10-30) + # 黄色通常有较高的饱和度和亮度 + yellow_hue_lower = np.array([20, 100, 100]) + yellow_hue_upper = np.array([40, 255, 255]) + + # 创建黄色区域掩码 + yellow_mask = cv2.inRange(hsv, yellow_hue_lower, yellow_hue_upper) + + # 应用形态学操作 + kernel = np.ones((5, 5), np.uint8) + yellow_mask = cv2.morphologyEx(yellow_mask, cv2.MORPH_OPEN, kernel) + yellow_mask = cv2.morphologyEx(yellow_mask, cv2.MORPH_CLOSE, kernel) + + # 使用连通区域分析,去除小的噪点区域 + num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(yellow_mask, connectivity=8) + + # 过滤小的连通区域 + min_size = 500 # 最小连通区域大小 + filtered_yellow_mask = np.zeros_like(yellow_mask) + + # 从索引1开始,因为0是背景 + for i in range(1, num_labels): + if stats[i, cv2.CC_STAT_AREA] >= min_size: + filtered_yellow_mask[labels == i] = 255 + + # 计算黄色区域占比 + height, width = yellow_mask.shape + total_pixels = height * width + yellow_pixels = np.sum(filtered_yellow_mask == 255) + yellow_ratio = yellow_pixels / total_pixels + + # 在原图上标记黄色区域 + result = img.copy() + overlay = img.copy() + overlay[filtered_yellow_mask > 0] = [0, 165, 255] # 用橙色标记黄色区域 + cv2.addWeighted(overlay, 0.4, img, 0.6, 0, result) # 半透明效果 + + # 显示检测结果信息 + cv2.putText(result, f"Yellow Ratio: {yellow_ratio:.2%}", (10, 30), + cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 165, 255), 2) + + # 调试模式:显示处理过程图像 + if debug: + plt.figure(figsize=(15, 10)) + + plt.subplot(231) + plt.title("Original Image") + plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) + + plt.subplot(232) + plt.title("Hue Channel") + plt.imshow(h, cmap='hsv') + + plt.subplot(233) + plt.title("Saturation Channel") + plt.imshow(s, cmap='gray') + + plt.subplot(234) + plt.title("Initial Yellow Mask") + plt.imshow(yellow_mask, cmap='gray') + + plt.subplot(235) + plt.title("Filtered Yellow Mask") + plt.imshow(filtered_yellow_mask, cmap='gray') + + plt.subplot(236) + plt.title("Yellow Detection Result") + plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB)) + + plt.tight_layout() + plt.show() + + # 保存结果 + if save_result: + result_dir = "results" + os.makedirs(result_dir, exist_ok=True) + output_path = os.path.join(result_dir, f"{filename}_yellow_area_result.jpg") + cv2.imwrite(output_path, result) + print(f"结果已保存至: {output_path}") + + return yellow_ratio + +def main(): + parser = argparse.ArgumentParser(description='分析图片中黄色区域占比') + parser.add_argument('--image_path', default='./image_20250525_090252.png', type=str, help='图片路径') + parser.add_argument('--debug', default=False, action='store_true', help='显示处理过程图像') + parser.add_argument('--save', action='store_true', help='保存处理结果图像') + args = parser.parse_args() + + try: + yellow_ratio = analyze_yellow_area_ratio(args.image_path, args.debug, args.save) + print(f"黄色区域占比: {yellow_ratio:.2%}") + except Exception as e: + print(f"错误: {e}") + +if __name__ == "__main__": + main() \ No newline at end of file