Files
hirres_tractor_vision/lib/alg/line_detection.py
2025-05-30 16:30:37 +08:00

116 lines
3.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import cv2
import numpy as np
def detect_lines_in_depth_image(depth_image, roi,min_depth):
"""
Detect lines in a depth image within a specified Region of Interest (ROI).
:param depth_image: The depth image in grayscale16 format.
:param roi: The Region of Interest (ROI) to limit the detection region within the depth image.
:return: The detected lines with coordinates relative to the original depth image.
"""
lines_list = []
# Convert the depth image to a format suitable for line detection using OpenCV
# Scale the depth image from uint16 to uint8
# Extract the ROI from the depth image
x, y, w, h = roi
roi_image = depth_image[y:y+h, x:x+w]
min_dist = np.min(roi_image)
max_dist = np.max(roi_image)
print(f"ROI shape{roi_image.shape}")
print(f"ROI深度范围{min_dist} - {max_dist}")
# norm_img = cv2.normalize(roi_image, None, 0,255, cv2.NORM_MINMAX, cv2.CV_8U)
min_dist = min_depth
# max_dist = 1800
norm_img = (roi_image-min_dist)/(max_dist-min_dist)
norm_img = norm_img * 255
norm_img = np.clip(norm_img,0,255)
norm_img = norm_img.astype(np.uint8)
# cv2.imwrite('dbg_norm.png',norm_img)
edges = cv2.Canny(norm_img,15,30,apertureSize=3)
# cv2.imwrite('dbg_edges.png',edges)
# Use OpenCV's line detection algorithm (e.g., HoughLines or HoughLinesP) to detect lines within the specified ROI
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 20, minLineLength=10, maxLineGap=100)
norm_depth_img = cv2.normalize(depth_image, None, 0,255, cv2.NORM_MINMAX, cv2.CV_8U)
colored_img = cv2.cvtColor(norm_depth_img,cv2.COLOR_GRAY2BGR)
# Adjust the line coordinates to be relative to the original depth image
if lines is not None:
for points in lines:
# Extracted points nested in the list
x1,y1,x2,y2=points[0]
x1=x1+x
y1=y1+y
x2=x2+x
y2=y2+y
# Draw the lines joing the points
# On the original image
cv2.line(colored_img,(x1,y1),(x2,y2),(0,255,0),2)
# Maintain a simples lookup list for points
lines_list.append([(x1,y1),(x2,y2)])
# Save the result image
# cv2.imwrite('dbg_detectedLines.png',colored_img)
# Return the detected lines with adjusted coordinates
return lines_list
def calculate_line_angle(line):
"""
计算线条与水平线x轴之间的角度。
:param line: 线条的两个端点坐标,格式为 [(x1, y1), (x2, y2)]
:return: 线条与水平线之间的角度以度为单位范围为0-180度
"""
# 提取两个点的坐标
(x1, y1), (x2, y2) = line
# 计算斜率,处理垂直线的情况
if x2 - x1 == 0:
return 90.0 # 垂直线
# 计算斜率
slope = (y2 - y1) / (x2 - x1)
# 计算角度(弧度)并转换为度
angle = np.arctan(slope) * 180 / np.pi
# 确保角度为正0-180度范围内
if angle < 0:
angle += 180
#转换成与相机中线之间的角度
return angle
def calculate_distance_point_to_line(point, line):
"""
计算一个点到一条线的距离。
:param point: 点的坐标,格式为 (x, y)
:param line: 线的两个端点坐标,格式为 [(x1, y1), (x2, y2)]
:return: 点到线的距离
"""
(x0, y0) = point
(x1, y1), (x2, y2) = line
numerator = abs((y2 - y1) * x0 - (x2 - x1) * y0 + x2 * y1 - y2 * x1)
denominator = np.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2)
return (numerator / denominator)*2.5+5
if __name__ == '__main__':
img = cv2.imread('dbg_233900303_z.png',cv2.IMREAD_UNCHANGED)
line_list = detect_lines_in_depth_image(img,(320,240,640,480),1100)
print(line_list)
for line in line_list:
angle = calculate_line_angle(line)
dist = calculate_distance_point_to_line((320,240),line)
print(f'angle={angle} dist={dist}')