我目前正致力于使用opencv和python进行自动驾驶汽车的车道检测。我使用了houghline变换来获得路线。从这些线我已经分别计算了具有负斜率和正斜率的线的平均斜率和截距值。为了减少错误,我想跟踪前3帧的计算平均斜率和截距。这样我就可以检查当前帧的平均斜率和截距值的偏差并相应地进行校正。有没有办法跟踪前3帧?
这是我到目前为止所做的。这是针对当前帧的。我想保持最多3个前一帧的计算平均值,并从当前帧访问这些值。
import numpy as np
import cv2
import math
cap = cv2.VideoCapture('video3.mov')
while (cap.isOpened()):
ret, frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HLS)
# HSL color mask
lower_white = np.uint8([0, 140, 0])
upper_white = np.uint8([255, 255, 255])
mask = cv2.inRange(hsv, lower_white, upper_white)
res = cv2.bitwise_and(frame, frame, mask=mask)
height = np.size(hsv, 0)
width = np.size(hsv, 1)
rows, cols = hsv.shape[:2]
bottom_left = [cols * 0, rows * 0.9]
top_left = [cols * 0.4, rows * 0.7]
bottom_right = [cols * 1, rows * 0.9]
top_right = [cols * 0.6, rows * 0.7]
vertices = np.array([[bottom_left, top_left, top_right, bottom_right]], dtype=np.int32)
maskzero = np.zeros_like(res)
cv2.fillPoly(maskzero, vertices, (255,) * maskzero.shape[2])
maskedimg = cv2.bitwise_and(res, maskzero)
# smoothed = cv2.medianBlur(maskedimg,3)
gaussian = cv2.GaussianBlur(maskedimg, (3, 3), 0)
# apply canny on masked image
cannymask = cv2.Canny(gaussian, 150, 250)
# apply hough transform houghlinesP
lines = cv2.HoughLinesP(cannymask, rho=1, theta=np.pi / 180, threshold=20, minLineLength=10, maxLineGap=300)
left_slope = []
right_slope = []
left_intercept = []
right_intercept = []
total_right_length = []
total_left_length = []
if lines is not None:
for line in lines:
for x1, y1, x2, y2 in line:
if (x2 - x1) != 0:
slope = (y2 - y1) / (x2 - x1)
intercept = y1 - slope * x1
length = np.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2)
angle = math.atan2(y2-y1,x2-x1)
degree = angle * 180 / np.pi
if x2 == x1 or y2 == y1:
continue
elif slope > 0:
if int(degree) in range (27,41):
right_slope.append(slope)
right_intercept.append(intercept)
total_right_length.append(length)
angle = math.atan2(y2 - y1, x2 - x1)
degree = angle * 180 / np.pi
print("positive",degree)
elif slope < 0:
if int(degree) in range (-62,-31):
left_slope.append(slope)
left_intercept.append(intercept)
total_left_length.append(length)
angle = math.atan2(y2 - y1, x2 - x1)
degree = angle * 180 / np.pi
print("negative",degree)
degreeint= int(degree)
#cv2.line(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
sum_right_length = np.sum(total_right_length) if len(total_right_length) > 0 else None
right_mean_slope=np.mean(right_slope) if len(right_slope)>0 else None
right_mean_intercept=np.mean(right_intercept) if len(right_intercept) > 0 else None
sum_left_length = np.sum(total_left_length) if len(total_left_length) > 0 else None
left_mean_slope = np.mean(left_slope) if len(left_slope)>0 else None
left_mean_intercept = np.mean(left_intercept) if len(left_intercept) > 0 else None
right_x1=0
right_y1=0
right_x2=0
right_y2=0
left_x1=0
left_x2=0
left_y2=0
left_y1=0
y1 = frame.shape[0] # bottom of the image
y2 = y1*0.7
if right_mean_intercept is not None and right_mean_slope is not None:
right_x1 = int((y1 - right_mean_intercept)/right_mean_slope)
right_x2 = int((y2 - right_mean_intercept)/right_mean_slope)
right_y1 = int(y1)
right_y2 = int(y2)
if left_mean_intercept is not None and left_mean_slope is not None:
left_x1 = int((y1 - left_mean_intercept)/left_mean_slope)
left_x2 = int((y2 - left_mean_intercept)/left_mean_slope)
left_y1 = int(y1)
left_y2 = int(y2)
cv2.line(frame, (right_x1, right_y1), (right_x2, right_y2), (0, 0, 255), 10)
cv2.line(frame, (left_x1, left_y1), (left_x2, left_y2), (255, 0,0), 10)
cv2.imshow("New_lines", frame)
if cv2.waitKey(100) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
我想保持左右平均斜率和3个先前帧的截距值,并从当前帧访问它们。
答案 0 :(得分:2)
import numpy as np
import cv2
import math
cap = cv2.VideoCapture('video3.mov')
previous = [ ] # We will keep track of previous 3 frames in this list
while (cap.isOpened()):
ret, frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HLS)
if len(previous) == 3 :
# do your thing like calculating the mean
for x in range(3):
print(previous[x]) # This is how you can access the previous frames
# ================================================================
# After you are done add the below two lines of code
# Below two lines are necessary to keep track of recent 3 frames
# ================================================================
previous = previous[1:] # Removing the first frame so now length of previous is 2
previous.append(frame) # Adding the current frame so length of previous is 3 again
else :
# else condition is for if frames are less then 3
# else condition is for the very beginning when you previous will start with empty list
previous.append(frame)
continue # If you want to do computation even when length of previous is less than 3 than comment the continue statement
if cv2.waitKey(100) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
答案 1 :(得分:0)
import numpy as np
import cv2
import math
cap = cv2.VideoCapture('video3.mov')
prevFrames = [None,None,None] # avoid index mishaps for [-1]..[-3]
# you need to test for None when accessing
while (cap.isOpened()):
ret, frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HLS)
# [...]
# access prevFrames[-1] for last frame,
# [-2] for the one before that,
# [-3] for the one 3 before now
# check value for None before using
sum_right_length = np.sum(total_right_length) if len(total_right_length) > 0 else None
right_mean_slope=np.mean(right_slope) if len(right_slope)>0 else None
right_mean_intercept=np.mean(right_intercept) if len(right_intercept) > 0 else None
sum_left_length = np.sum(total_left_length) if len(total_left_length) > 0 else None
left_mean_slope = np.mean(left_slope) if len(left_slope)>0 else None
left_mean_intercept = np.mean(left_intercept) if len(left_intercept) > 0 else None
# [...]
# add data from current frame at end
prevFrames.append( [right_mean_slope, left_mean_slope, right_mean_intercept, left_mean_intercept ]
if len(prevFrames) > 3:
prevFrames.pop(0) # remove and discard oldest element
cv2.line(frame, (right_x1, right_y1), (right_x2, right_y2), (0, 0, 255), 10)
cv2.line(frame, (left_x1, left_y1), (left_x2, left_y2), (255, 0,0), 10)
cv2.imshow("New_lines", frame)