- 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.
132 lines
4.4 KiB
Python
132 lines
4.4 KiB
Python
#!/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() |