-
Notifications
You must be signed in to change notification settings - Fork 52
/
lkdemo.py
executable file
·103 lines (75 loc) · 2.98 KB
/
lkdemo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env python3
'''
lkdemo.py - Lucas-Kanade optical flow demo
Adapted from https://docs.opencv.org/3.4/d7/d8b/tutorial_py_lucas_kanade.html
My version doesn't error-out on failure to find flow; instead, it
searches for a new set of features to track.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
'''
import numpy as np
import cv2 as cv
# Use camera for capture
cap = cv.VideoCapture(0)
# Create params for ShiTomasi corner detection
feature_params = dict(maxCorners=100,
qualityLevel=0.3,
minDistance=7,
blockSize=7)
# Create params for lucas kanade optical flow
lk_params = dict(winSize=(15, 15),
maxLevel=2,
criteria=(cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT,
10, 0.03))
# Create some random colors
color = np.random.randint(0, 255, (100, 3))
# Take first frame and find corners in it
_, old_frame = cap.read()
old_gray = cv.cvtColor(old_frame, cv.COLOR_BGR2GRAY)
p0 = cv.goodFeaturesToTrack(old_gray, mask=None, **feature_params)
# Create a mask image for drawing purposes
mask = np.zeros_like(old_frame)
while True:
# Capture a frame
_, frame = cap.read()
# Convert it to grayscale
frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# Calculate optical flow
p1, st, err = cv.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None,
**lk_params)
# If no flow, look for new points
if p1 is None:
old_gray = cv.cvtColor(old_frame, cv.COLOR_BGR2GRAY)
p0 = cv.goodFeaturesToTrack(old_gray, mask=None, **feature_params)
# Get rid of old lines
mask = np.zeros_like(old_frame)
cv.imshow('frame', frame)
# Otherwise, show flow
else:
# Select good points
good_new = p1[st == 1]
good_old = p0[st == 1]
# Draw the tracks
for i, (new, old) in enumerate(zip(good_new, good_old)):
a, b = (int(x) for x in new.ravel())
c, d = (int(x) for x in old.ravel())
mask = cv.line(mask, (a, b), (c, d), color[i].tolist(), 2)
frame = cv.circle(frame, (a, b), 5, color[i].tolist(), -1)
# Display the image with the flow lines
img = cv.add(frame, mask)
cv.imshow('frame', img)
# Update the previous frame and previous points
old_gray = frame_gray.copy()
p0 = good_new.reshape(-1, 1, 2)
# Force display, quitting on ESC
if (cv.waitKey(1) & 0xff) == 27:
break
# Shut down
cv.destroyAllWindows()
cap.release()