98 lines
3.4 KiB
Python
Executable File
98 lines
3.4 KiB
Python
Executable File
import cv2
|
|
import numpy as np
|
|
import os
|
|
|
|
def detect_yellow_distance_from_bottom(image_path, visualize=False):
|
|
"""
|
|
增强可视化版本的鱼眼图像黄色点检测
|
|
"""
|
|
def show_step(step_name, img, delay=500):
|
|
"""显示处理步骤"""
|
|
if visualize:
|
|
cv2.imshow(step_name, img)
|
|
cv2.waitKey(delay)
|
|
cv2.imwrite(f"saved_images/step_{step_name}.jpg", img)
|
|
|
|
# 1. 读取图像
|
|
img = cv2.imread(image_path)
|
|
if img is None:
|
|
raise ValueError("无法读取图像")
|
|
show_step("01_original", img)
|
|
|
|
# 2. 鱼眼矫正(简化版,实际需用真实相机参数)
|
|
h, w = img.shape[:2]
|
|
K = np.array([[w, 0, w//2], [0, h, h//2], [0, 0, 1]]) # 假设的相机矩阵
|
|
D = np.array([-0.3, 0.1, 0, 0]) # 假设的畸变系数
|
|
undistorted = cv2.fisheye.undistortImage(img, K, D)
|
|
show_step("02_undistorted", undistorted)
|
|
|
|
# 3. 颜色空间转换
|
|
hsv = cv2.cvtColor(undistorted, cv2.COLOR_BGR2HSV)
|
|
show_step("03_hsv", cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)) # 转回BGR便于显示
|
|
|
|
# 4. 颜色阈值处理
|
|
lower_yellow = np.array([20, 150, 150]) # 调整后的阈值
|
|
upper_yellow = np.array([30, 255, 255])
|
|
color_mask = cv2.inRange(hsv, lower_yellow, upper_yellow)
|
|
show_step("04_color_mask", color_mask)
|
|
|
|
# 5. 形态学处理
|
|
kernel = np.ones((5,5), np.uint8)
|
|
opened = cv2.morphologyEx(color_mask, cv2.MORPH_OPEN, kernel)
|
|
closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, kernel)
|
|
show_step("05_morphology", closed)
|
|
|
|
# 6. 创建垂直区域掩模
|
|
center_x = w // 2
|
|
line_width = max(5, int(w * 0.02)) # 2%宽度
|
|
vertical_mask = np.zeros((h,w), dtype=np.uint8)
|
|
cv2.rectangle(vertical_mask, (center_x-line_width,0), (center_x+line_width,h), 255, -1)
|
|
show_step("06_vertical_mask", vertical_mask)
|
|
|
|
# 7. 组合掩模
|
|
final_mask = cv2.bitwise_and(closed, vertical_mask)
|
|
show_step("07_final_mask", final_mask)
|
|
|
|
# 8. 轮廓检测
|
|
contours, _ = cv2.findContours(final_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
|
contour_img = cv2.cvtColor(final_mask, cv2.COLOR_GRAY2BGR)
|
|
cv2.drawContours(contour_img, contours, -1, (0,255,0), 2)
|
|
show_step("08_contours", contour_img)
|
|
|
|
if not contours:
|
|
print("未检测到黄色区域")
|
|
return None, None, final_mask
|
|
|
|
# 9. 寻找最低点
|
|
lowest_point = max(
|
|
[tuple(cnt[cnt[:,:,1].argmax()][0]) for cnt in contours],
|
|
key=lambda p: p[1]
|
|
)
|
|
distance = h - lowest_point[1]
|
|
|
|
# 10. 最终可视化
|
|
result_img = undistorted.copy()
|
|
cv2.line(result_img, (center_x,0), (center_x,h), (0,255,0), 1)
|
|
cv2.circle(result_img, lowest_point, 10, (0,0,255), -1)
|
|
cv2.line(result_img, lowest_point, (lowest_point[0],h), (0,0,255), 2)
|
|
cv2.putText(result_img, f"Distance: {distance}px", (10,30),
|
|
cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)
|
|
show_step("09_final_result", result_img)
|
|
|
|
return distance, center_x, final_mask
|
|
|
|
# 使用示例
|
|
try:
|
|
os.makedirs("saved_images", exist_ok=True)
|
|
distance, center_x, _ = detect_yellow_distance_from_bottom(
|
|
"/home/mi-task/saved_images/right_eg.jpg",
|
|
visualize=True
|
|
)
|
|
|
|
if distance is not None:
|
|
print(f"中垂线最低黄点距离底部: {distance}像素 (x={center_x})")
|
|
else:
|
|
print("未检测到目标")
|
|
|
|
except Exception as e:
|
|
print(f"错误: {str(e)}") |