我现在有了这段代码,它非常适合检测视频中的红线,问题是我目前一条红线大约有 40 行(见图),我想将其减少到仅1 这样我就可以轻松确定红色方块的交点以及随后的角点,有人有想法吗?:
代码:
import cv2
import numpy as np
def detect_grid(frame):
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower_red = np.array([0, 100, 100])
upper_red = np.array([10, 255, 255])
mask1 = cv2.inRange(hsv, lower_red, upper_red)
lower_red = np.array([140, 20, 20])
upper_red = np.array([180, 255, 255])
mask2 = cv2.inRange(hsv, lower_red, upper_red)
red_mask = mask1 + mask2
kernel = np.ones((5, 5), np.uint8)
red_mask = cv2.morphologyEx(red_mask, cv2.MORPH_OPEN, kernel)
red_mask = cv2.morphologyEx(red_mask, cv2.MORPH_CLOSE, kernel)
lines = cv2.HoughLinesP(red_mask, 1, np.pi / 180, threshold=50, minLineLength=50, maxLineGap=5)
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(frame, (x1, y1), (x2, y2), (0, 255, 0), 5)
cap = cv2.VideoCapture('redline_rectified.mp4')
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
detect_grid(frame)
cv2.imshow('Grid Detection', frame)
if cv2.waitKey(1) & 0xFF == ord(' '):
break
cap.release()
cv2.destroyAllWindows()
我现在得到的:
通常,我基本上通过轮廓检测和分析轮廓来手动解决线检测问题。由于您的输入很清楚,我继续修改您的代码。
以下是我针对您的情况应用的步骤:如果两条线彼此靠近,则忽略其中一条。我在最后得到了这个输出,其中有清晰的线条。
这是代码。开头部分相同,只是修改了函数的结尾:
import cv2
import numpy as np
def detect_grid(frame):
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower_red = np.array([0, 100, 100])
upper_red = np.array([10, 255, 255])
mask1 = cv2.inRange(hsv, lower_red, upper_red)
lower_red = np.array([140, 20, 20])
upper_red = np.array([180, 255, 255])
mask2 = cv2.inRange(hsv, lower_red, upper_red)
red_mask = mask1 + mask2
kernel = np.ones((5, 5), np.uint8)
red_mask = cv2.morphologyEx(red_mask, cv2.MORPH_OPEN, kernel)
red_mask = cv2.morphologyEx(red_mask, cv2.MORPH_CLOSE, kernel)
lines = cv2.HoughLinesP(red_mask, 1, np.pi / 180, threshold=350, minLineLength=50, maxLineGap=50)
if lines is not None:
# Filter out lines that are too close
filtered_lines = []
for line in lines:
x1, y1, x2, y2 = line[0]
p1 = np.array([x1, y1])
p2 = np.array([x2, y2])
too_close = False
for other_line in filtered_lines:
x3, y3, x4, y4 = other_line
p3 = np.array([x3, y3])
p4 = np.array([x4, y4])
# Calculate Euclidean distance
distance = np.linalg.norm(np.cross(p2 - p1, p1 - p3)) / np.linalg.norm(p2 - p1)
if distance < 10:
too_close = True
break
if not too_close:
filtered_lines.append(line[0])
for line in filtered_lines:
x1, y1, x2, y2 = line
cv2.line(frame, (x1, y1), (x2, y2), (0, 255, 255), 3)
cv2.imwrite("/home/ubuntu/a.jpg", frame)
img = cv2.imread("/home/ubuntu/lines.png")
detect_grid(img)