Created
June 21, 2019 14:18
Star
You must be signed in to star a gist
Testing the OpenCV Optical Flow tutorial on the Raspberry Pi Zero
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import io | |
import time | |
import picamera | |
#from PIL import Image | |
import cv2 as cv | |
import numpy as np | |
NoI = 200 | |
# params for ShiTomasi corner detection | |
feature_params = dict( maxCorners = 100, | |
qualityLevel = 0.3, | |
minDistance = 7, | |
blockSize = 7 ) | |
# Parameters 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)) | |
def outputs(old_gray, p0, mask): | |
for i in range(NoI): | |
# This returns the stream for the camera to capture to | |
yield stream | |
# Once the capture is complete, the loop continues here | |
# (read up on generator functions in Python to understand | |
# the yield statement). Here you could do some processing | |
# on the image... | |
# Construct a numpy array from the stream | |
data = np.fromstring(stream.getvalue(), dtype=np.uint8) | |
# "Decode" the image from the array, preserving colour | |
frame = cv.imdecode(data, 1) | |
# OpenCV returns an array with data in BGR order. If you want RGB instead | |
# use the following... | |
frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) | |
# calculate optical flow | |
p1, st, err = cv.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params) | |
# 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 = new.ravel() | |
c,d = 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) | |
img = cv.add(frame,mask) | |
# Now update the previous frame and previous points | |
old_gray = frame_gray.copy() | |
p0 = good_new.reshape(-1,1,2) | |
# Finally, reset the stream for the next capture | |
stream.seek(0) | |
stream.truncate() | |
# Create the in-memory stream | |
stream = io.BytesIO() | |
with picamera.PiCamera() as camera: | |
camera.resolution = (640, 480) | |
camera.framerate = 80 | |
time.sleep(2) | |
# Take first frame and find corners in it | |
camera.capture(stream, format='jpeg') | |
# Construct a numpy array from the stream | |
data = np.fromstring(stream.getvalue(), dtype=np.uint8) | |
# "Decode" the image from the array, preserving colour | |
old_frame = cv.imdecode(data, 1) | |
# OpenCV returns an array with data in BGR order. If you want RGB instead | |
# use the following... | |
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) | |
start = time.time() | |
camera.capture_sequence(outputs(old_gray, p0, mask), 'jpeg', use_video_port=True) | |
#camera.capture_sequence(outputs(old_gray, p0, mask), 'jpeg', use_video_port=True) | |
finish = time.time() | |
print('Processed {} images at {:.2f}fps'.format(NoI, NoI / (finish - start))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment