如何在视频处理中保留多个先前帧的记录

时间:2018-01-17 13:45:48

标签: python opencv video-processing

我目前正致力于使用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个先前帧的截距值,并从当前帧访问它们。

2 个答案:

答案 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)