연속된 5개의 프레임으로 움직이는 공을 보여주는데,
화살표는 그것의 변위 벡터를 보여준다.
변위 벡터를 보여준다는 뜻은 객체의 움직임을 시각화 한다는 뜻이다.
이번시간에 배우는것은 빛을 이용해서 객체의 움직임을 시각화 하는것으로 보면된다.
# Load video stream, short clip
#cap = cv2.VideoCapture('walking_short_clip.mp4')
# Load video stream, long clip
cap = cv2.VideoCapture('walking.avi')
# Get the height and width of the frame (required to be an interger)
width = int(cap.get(3))
height = int(cap.get(4))
# Define the codec and create VideoWriter object. The output is stored in '*.avi' file.
out = cv2.VideoWriter('optical_flow_walking.avi', cv2.VideoWriter_fourcc('M','J','P','G'), 30, (width, height))
# Set parameters for ShiTomasi corner detection
feature_params = dict( maxCorners = 100,
qualityLevel = 0.3,
minDistance = 7,
blockSize = 7 )
# Set parameters for lucas kanade optical flow
lucas_kanade_params = dict( winSize = (15,15),
maxLevel = 2,
criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
# Create some random colors
# Used to create our trails for object movement in the image
color = np.random.randint(0,255,(100,3))
# Take first frame and find corners in it
ret, prev_frame = cap.read()
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
# Find inital corner locations
prev_corners = cv2.goodFeaturesToTrack(prev_gray, mask = None, **feature_params)
# Create a mask image for drawing purposes
mask = np.zeros_like(prev_frame)
while(1):
ret, frame = cap.read()
if ret == True:
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# calculate optical flow
new_corners, status, errors = cv2.calcOpticalFlowPyrLK(prev_gray,
frame_gray,
prev_corners,
None,
**lucas_kanade_params)
# Select and store good points
good_new = new_corners[status==1]
good_old = prev_corners[status==1]
# Draw the points
for new in good_new:
a, b = new.ravel()
frame = cv2.circle(frame, (int(a), int(b)), 5, (0, 255, 0), -1)
img = cv2.add(frame,mask)
# Save Video
out.write(img)
# Show Optical Flow
#imshow('Optical Flow - Lucas-Kanade',img)
# Now update the previous frame and previous points
prev_gray = frame_gray.copy()
prev_corners = good_new.reshape(-1,1,2)
else:
break
cap.release()
out.release()
A. 광학 흐름 계산
new_corners, status, errors = cv2.calcOpticalFlowPyrLK(prev_gray,
frame_gray,
prev_corners,
None,
**lucas_kanade_params)
B. 이동 경로 시각화
for i,(new,old) in enumerate(zip(good_new, good_old)):
a, b = new.ravel()
c, d = old.ravel()
mask = cv2.line(mask, ( 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)
C. 프레임에 그리기
img = cv2.add(frame,mask)
배경을 검게 만들고 트랙킹을 한다음 추척하고 싶은 개체만 보이게 한다.
위의 Lucas-Kanade 와 다른점은 아래 두가지 이다.
A. 밀도 있는 광학 흐름 계산
flow = cv2.calcOpticalFlowFarneback(previous_gray, next,
None, 0.5, 3, 15, 3, 5, 1.2, 0)
B. 속도와 각도에 따른 색상 계산
magnitude, angle = cv2.cartToPolar(flow[...,0], flow[...,1])
hsv[...,0] = angle * (180 / (np.pi/2))
hsv[...,2] = cv2.normalize(magnitude, None, 0, 255, cv2.NORM_MINMAX)
final = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
# Load video stream, short clip
#cap = cv2.VideoCapture('walking_short_clip.mp4')
# Load video stream, long clip
cap = cv2.VideoCapture('walking.avi')
# Get the height and width of the frame (required to be an interger)
width = int(cap.get(3))
height = int(cap.get(4))
# Define the codec and create VideoWriter object. The output is stored in '*.avi' file.
out = cv2.VideoWriter('dense_optical_flow_walking.avi', cv2.VideoWriter_fourcc('M','J','P','G'), 30, (width, height))
# Get first frame
ret, first_frame = cap.read()
previous_gray = cv2.cvtColor(first_frame, cv2.COLOR_BGR2GRAY)
hsv = np.zeros_like(first_frame)
hsv[...,1] = 255
while True:
# Read of video file
ret, frame2 = cap.read()
if ret == True:
next = cv2.cvtColor(frame2,cv2.COLOR_BGR2GRAY)
# Computes the dense optical flow using the Gunnar Farneback’s algorithm
flow = cv2.calcOpticalFlowFarneback(previous_gray, next,
None, 0.5, 3, 15, 3, 5, 1.2, 0)
# use flow to calculate the magnitude (speed) and angle of motion
# use these values to calculate the color to reflect speed and angle
magnitude, angle = cv2.cartToPolar(flow[...,0], flow[...,1])
hsv[...,0] = angle * (180 / (np.pi/2))
hsv[...,2] = cv2.normalize(magnitude, None, 0, 255, cv2.NORM_MINMAX)
final = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
# Save Video
out.write(final)
# Show our demo of Dense Optical Flow
#imshow('Dense Optical Flow', final)
# Store current image as previous image
previous_gray = next
else:
break
cap.release()
out.release()