Challenge

Project 8

This code is written based on learnings in week 8 of CompVision

for concept explanation "Opencv24-python-tutorial" is referred

the code below shi tomasi corner detector and Lucas Kanade optical flow model

  • The shi-tomasi corner detector is modified version of Haris corner detector Haris corner detector uses: R = lambda_1*lambda_2 - k(lambda_1+lambda_2)^2 where as shi-tomasi model uses R = min(lamda_1,lamda_2), in case of shi tomasi model if lambda_1 and lamda_2 is greater than lamda_min then it is considered as corner
import cv2
import numpy as np
cv2.goodFeaturesToTrack():
  1. finds N strongest corners in the image by Shi-Tomasi method
  2. the image should be a grayscale image
  3. specify number of corners we want to find
  4. specify the quality level, which is a value between 0-1, this denotes the minimum quality of corner below which neuron is rejected.
  5. Then we provide the minimum euclidean distance between corners detected.
  6. the function finds corners in the image. All corners below quality level are rejected.
  7. Then it sorts the remaining corners based on quality in the descending order.
# tracking feature. identifying corner detector through shi-tomasi corner detector method
​
def find_features(gray_image):
    # extract the features information from the gray image using shi tomasi corner detector method 
    points = cv2.goodFeaturesToTrack(gray_image,mask=None,maxCorners=100,qualityLevel=0.1,minDistance=10,blockSize=5)
    return points
  1. Optical flow is the pattern of apparent motion of image objects between two consecutive frames caused by the movemement of object or camera.

  2. It is 2D vector field where each vector is a displacement vector showing the movement of points from first frame to second

  3. Optical flow works on several assumptions: a. The pixel intensities of an object do not change between consecutive frames. b. Neighbouring pixels have similar motion.

  4. the Lucas–Kanade method is a widely used differential method for optical flow estimation

  5. in python we use cv2.calcOpticalFlowPyrLK(): to this function we pass the previous frame, previous points and next frame. It returns next points along with some status numbers which has a value of 1 if next point is found, else zero. We iteratively pass these next points as previous points in next step

# Lucas Kanade sparse optical flow model
​
def lk_model(gray_t_1,gray_t,prevpoints):
    #win_size = (10,10)
    #max_level = 2
    #criteria = (cv2.TERM_CRITERIA_EPS|cv2.TERM_CRITERIA_COUNT,10,0.03)
    points,status,error = cv2.calcOpticalFlowPyrLK(gray_t_1,gray_t,prevpoints,None,winSize=(10,10),maxLevel=2,criteria=(cv2.TERM_CRITERIA_EPS|cv2.TERM_CRITERIA_COUNT,10,0.03))
    return (points,status,error)
# driver script
myvideo = cv2.VideoCapture('traffic.mp4') # read the video
​
color = np.random.randint(0,255,(100,3)) # extract the colours to draw the optical flow lines
​
# extract the status and first frame that will be treated as the previous frame(t-1)th frame
ret_status,prev_frame = myvideo.read() 
prev_gray = cv2.cvtColor(prev_frame,cv2.COLOR_BGR2GRAY) # convert the color image to gray image
prev_points = find_features(prev_gray) # find the feature like corners
mask_image = np.zeros_like(prev_frame) # create a mask image with all zeros
​
## Video writing 
# grab the width, height, and fps of the frames in the video stream.
frame_width = int(myvideo.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(myvideo.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(myvideo.get(cv2.CAP_PROP_FPS))
​
# initialize the FourCC and a video writer object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
output = cv2.VideoWriter('output.mp4', fourcc, fps, (frame_width, frame_height))
​
# reading further frames
while(1):
    ret,frame = myvideo.read() # read the next frame from video
    cur_gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) # converted the extracted frome from color to gray
    # use Lucas Kanade model to find current features and their status
    cur_points,status,error = lk_model(prev_gray,cur_gray,prev_points) 
    
    if cur_points is not None: # confirm the frame exists
        cur_points = cur_points[status==1] # consider all the current feature whose status is 1
        old_points = prev_points[status==1]# consider all the current feature whose status is 1
    
    for i, (current,prev) in enumerate(zip(cur_points,old_points)):
        a,b = current.ravel() # extract the features in form of 1-D array
        c,d = prev.ravel()
        mask_image = cv2.line(mask_image,(int(a),int(b)),(int(c),int(d)),color[i].tolist(),2)
        frame = cv2.circle(frame,(int(a),int(b)),5,color[i].tolist(),-1)
        
    img = cv2.add(frame,mask_image) # overlay the optical flow over the video 
    #img = frame
    # display image
    cv2.imshow('frame',img) # display overlayed video frame by frame
    #cv2.imshow('masked image', mask_image)
    #cv2.imwrite('myframe.jpg',frame)
    k = cv2.waitKey(5)
    if k==27:
        #cv2.destroyAllWindows()
        break
 # Set the current frame as (t-1)th frame and update the current point as prev point
    prev_gray = cur_gray.copy()
    prev_points = cur_points.reshape(-1,1,2)
    output.write(img)
    
cv2.destroyAllWindows()
cap.release()
​
Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.