import cv2 import os import numpy as np import matplotlib.pyplot as plt def test_images(): """测试图像处理并显示结果""" # 获取图像路径 image_dir = "/home/task/logs/image" if not os.path.exists(image_dir): print(f"找不到图像目录: {image_dir}") return # 获取所有原始图像 orig_images = [f for f in os.listdir(image_dir) if f.startswith("dual_track_orig_")] if not orig_images: print(f"未找到原始图像文件在 {image_dir} 目录下") return print(f"找到 {len(orig_images)} 张原始图像") # 对每张图像进行处理 for img_file in orig_images: img_path = os.path.join(image_dir, img_file) print(f"\n处理图像: {img_file}") # 读取图像 img = cv2.imread(img_path) if img is None: print(f"无法读取图像: {img_path}") continue # 获取图像尺寸 height, width = img.shape[:2] print(f"图像尺寸: {width}x{height}") # 转换为RGB以便使用matplotlib显示 img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转换到HSV颜色空间以便更容易提取黄色 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 标准黄色的HSV范围 lower_yellow = np.array([15, 80, 80]) upper_yellow = np.array([35, 255, 255]) # 创建黄色的掩码 mask = cv2.inRange(hsv, lower_yellow, upper_yellow) # 形态学操作以改善掩码 kernel = np.ones((5, 5), np.uint8) mask = cv2.dilate(mask, kernel, iterations=1) mask = cv2.erode(mask, np.ones((3, 3), np.uint8), iterations=1) # 边缘检测 edges = cv2.Canny(mask, 50, 150, apertureSize=3) # 霍夫变换检测直线 lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=25, minLineLength=width*0.05, maxLineGap=40) # 显示结果 fig, axs = plt.subplots(2, 2, figsize=(12, 10)) # 原始图像 axs[0, 0].imshow(img_rgb) axs[0, 0].set_title('原始图像') axs[0, 0].axis('off') # 黄色掩码 axs[0, 1].imshow(mask, cmap='gray') axs[0, 1].set_title('黄色掩码') axs[0, 1].axis('off') # 边缘检测 axs[1, 0].imshow(edges, cmap='gray') axs[1, 0].set_title('边缘检测') axs[1, 0].axis('off') # 直线检测结果 lines_img = img_rgb.copy() if lines is not None: center_x = width // 2 # 筛选垂直线 vertical_lines = [] for line in lines: x1, y1, x2, y2 = line[0] # 计算斜率 if abs(x2 - x1) < 5: # 几乎垂直的线 slope = 100 else: slope = (y2 - y1) / (x2 - x1) # 筛选接近垂直的线 if abs(slope) > 0.75: line_length = np.sqrt((x2-x1)**2 + (y2-y1)**2) mid_x = (x1 + x2) / 2 mid_y = (y1 + y2) / 2 # 根据是左侧还是右侧线使用不同颜色 color = (0, 0, 255) if mid_x < center_x else (255, 0, 0) # 绘制线段 cv2.line(lines_img, (x1, y1), (x2, y2), color, 2) # 记录垂直线 vertical_lines.append((line[0], mid_x, mid_y, slope, line_length)) # 按x坐标将线分为左右两组 left_lines = [line for line in vertical_lines if line[1] < center_x] right_lines = [line for line in vertical_lines if line[1] > center_x] print(f"检测到 {len(lines)} 条线,其中 {len(vertical_lines)} 条垂直线") print(f"左侧线: {len(left_lines)}, 右侧线: {len(right_lines)}") # 简化的对线进行评分 - 只考虑中心接近度 def score_by_center_proximity(lines, is_left): center_x = width // 2 scored_lines = [] for line in lines: _, mid_x, _, _, _ = line distance_to_center = abs(mid_x - center_x) # 归一化到图像宽度 normalized_distance = distance_to_center / (width * 0.5) center_score = max(0, 1.0 - normalized_distance) scored_lines.append((line, center_score)) # 按照中心接近度评分排序 return sorted(scored_lines, key=lambda x: x[1], reverse=True) # 找到最接近中心的左右线 best_left_lines = score_by_center_proximity(left_lines, True) best_right_lines = score_by_center_proximity(right_lines, False) # 绘制最佳左右线 if best_left_lines: best_left = best_left_lines[0][0] x1, y1, x2, y2 = best_left[0] cv2.line(lines_img, (x1, y1), (x2, y2), (0, 255, 0), 3) print(f"最佳左线: x={best_left[1]:.1f}, score={best_left_lines[0][1]:.2f}") if best_right_lines: best_right = best_right_lines[0][0] x1, y1, x2, y2 = best_right[0] cv2.line(lines_img, (x1, y1), (x2, y2), (0, 255, 0), 3) print(f"最佳右线: x={best_right[1]:.1f}, score={best_right_lines[0][1]:.2f}") # 绘制中心线 if best_left_lines and best_right_lines: best_left = best_left_lines[0][0] best_right = best_right_lines[0][0] # 计算轨道宽度 track_width = best_right[1] - best_left[1] print(f"轨道宽度: {track_width:.1f}像素 ({track_width/width*100:.1f}% 的图像宽度)") # 计算中心点 center_line_x = (best_left[1] + best_right[1]) / 2 center_line_y = height # 计算中心线与图像中心的偏差 deviation = center_line_x - center_x print(f"中心偏差: {deviation:.1f}像素") # 绘制中心点和偏差信息 cv2.circle(lines_img, (int(center_line_x), int(center_line_y)), 10, (255, 0, 255), -1) cv2.line(lines_img, (int(center_x), 0), (int(center_x), height), (0, 0, 255), 1) else: print("未检测到线段") # 将BGR转换为RGB以便matplotlib显示 lines_img = cv2.cvtColor(lines_img, cv2.COLOR_BGR2RGB) axs[1, 1].imshow(lines_img) axs[1, 1].set_title('检测到的线段') axs[1, 1].axis('off') plt.tight_layout() plt.show() # 等待用户按键继续 input("按Enter继续下一张图片...") if __name__ == "__main__": test_images()