# Project 8
"""
Description
1. Use Lucas Kanade Optical Flow method to perform sparse Optical Flow for pixels of interest.
2. Pixels or features of interest are derived from Shi-Tomasi corner detector algorithm
Task
1. Perform Optical flow on the videofile provided and highlight the features of interest using shi tomasi algorithm.
2. Submit the processed video along with its masked video sequence to the portal.
Deliverables:
1. The code is to be attached with comment.
2. The processed video along with proper highlights.
"""
# Imporing necessary packages
import cv2
# OpenCV-Python is a library of Python bindings designed to solve computer vision problems.
import numpy as np # np is an alias for numpy
# general-purpose array-processing package.
# It provides a high-performance multidimensional array object,
# and tools for working with these arrays
#tracking features, Identifying corners through
#shi-tomasi corner detector method
def find_features(gray_image):
# Extracting the features from the gray scaled image using cv2.goodFeaturesToTrack method
# No masking
# Here Maximum Corners detection is 100
# Quality Level is 0.1
# Minimum distance between two features is 10 to avoid features that are closely spaced
# Window size is 5
points = cv2.goodFeaturesToTrack(gray_image,mask=None,maxCorners=100,qualityLevel=0.1,minDistance=10,blockSize=5)
return points
# Lucas Kanade sparse optical flow model
def LK_model(gray_t_1,gray_t,prev_points):
# Window size = (10,10)
# Max level means Level of the Pyramid
# Criteria is for setup to perform the operation
points,status,error = cv2.calcOpticalFlowPyrLK(gray_t_1,gray_t,prev_points,None,winSize=(10,10),maxLevel=2,criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
return (points,status,error)
# driver script
# Reading MP4 files using cv2.VideoCapture
capture = cv2.VideoCapture("traffic.mp4")
# Initiate Color
color = np.random.randint(0,255,(100,3))
# Reading the image/frame i.e., (T-1)th frame from the video
ret,prev_frame = capture.read()
# Converting (T-1)th frame into GRAY Scaled image
prev_gray = cv2.cvtColor(prev_frame,cv2.COLOR_BGR2GRAY)
# Finding the features such as corner using shi-tomasi corner detector method
prev_points = find_features(prev_gray)
# Creating mask image
mask_image = np.zeros_like(prev_frame)
img_array = []
#reading further frames
while(1):
# Read the next (T)th frame
ret,frame = capture.read()
# Check whether the video is finished or not, If frame is None then its End of video
# Then Destroy all the windows
if frame is None:
cv2.destroyAllWindows()
break
# Converting current (T)th frame into GRAY Scaled image
current_gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
# Calculating the current points, status and error using Lucas Kanade model
current_points,status,error = LK_model(prev_gray,current_gray,prev_points)
# Check Current points
if current_points is not None:
current_points = current_points[status==1]
old_points = prev_points[status==1]
# Mapping
for i,(current,prev) in enumerate(zip(current_points,old_points)):
a,b = current.ravel()
c,d = prev.ravel()
# Masking the screen with black
mask_image = cv2.line(mask_image,(int(a),int(b)),(int(c),int(d)),color[i].tolist(),2)
# Plotting the features
frame = cv2.circle(frame,(int(a),int(b)),5,color[i].tolist(),-1)
img = cv2.add(frame,mask_image)
height,width,layers = img.shape
size = (width,height)
img_array.append(img)
#display image
cv2.imshow('frame',img)
k = cv2.waitKey(5)
if k == 27:
cv2.destroyAllWindows()
break
#set the current frame as the (T-2)th frame and update the current points as the previous points(T-1)th
prev_gray = current_gray.copy()
prev_points = current_points.reshape(-1,1,2)
# Collecting the frames and writes into the Video MP4 file
out = cv2.VideoWriter('ProcessedVideo.mp4',cv2.VideoWriter_fourcc(*'DIVX'),15,size)
for i in range(len(img_array)):
out.write(img_array[i])
out.release()