191 lines
7.2 KiB
Python
191 lines
7.2 KiB
Python
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() |