pegasus_cam_homogoraphy
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
pegasus_cam_homogoraphy [2019/03/08 04:50] – [Homography Overview] dwallace | pegasus_cam_homogoraphy [2019/03/08 04:54] (current) – [Networked Video Homography using the Pegasus Cam] dwallace | ||
---|---|---|---|
Line 8: | Line 8: | ||
\\ | \\ | ||
- | This tutorial shows how to implement real-time networked video homography using the Pegasus Cam. The big picture problem is to allow small teams of robots to collaborate using shared visual information. Solving this partially or completely is important because it will allow for teams of robots to collaborate in scenarios such as disaster rescue and cleanup, emergency response, and human-robot collaboration. This tutorial demonstrates how to implement real-time networked video homography using Python OpenCV and the Pegasus Cam. This tutorial takes approximately 1 hour to complete. | + | This tutorial shows how to implement real-time networked video homography using the Pegasus Cam. The big picture problem is to allow small teams of robots to collaborate using shared visual information. Solving this partially or completely is important because it will allow for teams of robots to collaborate in scenarios such as disaster rescue and cleanup, emergency response, and human-robot collaboration. This tutorial demonstrates how to implement real-time networked video homography using Python OpenCV and the Pegasus Cam. This tutorial takes approximately 1 hour to complete. |
- | \\ | + | |
+ | The source code for the real-time networked homography with the Pegasus Cams can be seen on the [[https:// | ||
===== Motivation and Audience ===== | ===== Motivation and Audience ===== | ||
Line 40: | Line 42: | ||
However, in order to optimize this program for real-time, it is more desirable to complete steps 1-4 for the first few frames, and then use that homography matrix for the rest of the stream, only applying the transformation for every frame of the two video streams. | However, in order to optimize this program for real-time, it is more desirable to complete steps 1-4 for the first few frames, and then use that homography matrix for the rest of the stream, only applying the transformation for every frame of the two video streams. | ||
+ | |||
+ | Good examples of homography in common life is creating a panoramic image with your smartphone. | ||
===== Code Overview ===== | ===== Code Overview ===== | ||
+ | The code for the real-time homography was implemented in Python. The full code with detailed comments can be seen below. | ||
+ | |||
+ | <code python> | ||
+ | # USAGE | ||
+ | # python realtime_stitching.py | ||
+ | |||
+ | # import the necessary packages | ||
+ | from __future__ import print_function | ||
+ | from pyimagesearch.basicmotiondetector import BasicMotionDetector | ||
+ | from pyimagesearch.panorama import Stitcher | ||
+ | from imutils.video import VideoStream | ||
+ | import numpy as np | ||
+ | import datetime | ||
+ | import imutils | ||
+ | import time | ||
+ | import cv2 | ||
+ | |||
+ | # initialize the Pegasus Cam video streams and allow them to warmup | ||
+ | print(" | ||
+ | leftStream = cv2.VideoCapture(" | ||
+ | rightStream = cv2.VideoCapture(" | ||
+ | time.sleep(2.0) | ||
+ | |||
+ | # initialize the image stitcher, motion detector, and total | ||
+ | # number of frames read | ||
+ | stitcher = Stitcher() | ||
+ | motion = BasicMotionDetector(minArea=500) | ||
+ | total = 0 | ||
+ | |||
+ | # loop over frames from the video streams | ||
+ | while(1): | ||
+ | # grab the frames from their respective video streams | ||
+ | retl, left = leftStream.read() | ||
+ | retr, right = rightStream.read() | ||
+ | |||
+ | # resize the frames | ||
+ | left = imutils.resize(left, | ||
+ | right = imutils.resize(right, | ||
+ | |||
+ | # stitch the frames together to form the panorama | ||
+ | # IMPORTANT: you might have to change this line of code | ||
+ | # depending on how your cameras are oriented; frames | ||
+ | # should be supplied in left-to-right order | ||
+ | result = stitcher.stitch([left, | ||
+ | |||
+ | # no homograpy could be computed | ||
+ | if result is None: | ||
+ | print(" | ||
+ | break | ||
+ | |||
+ | # convert the panorama to grayscale, blur it slightly, update | ||
+ | # the motion detector | ||
+ | gray = cv2.cvtColor(result, | ||
+ | gray = cv2.GaussianBlur(gray, | ||
+ | locs = motion.update(gray) | ||
+ | |||
+ | # only process the panorama for motion if a nice average has | ||
+ | # been built up | ||
+ | if total > 32 and len(locs) > 0: | ||
+ | # initialize the minimum and maximum (x, y)-coordinates, | ||
+ | # respectively | ||
+ | (minX, minY) = (np.inf, np.inf) | ||
+ | (maxX, maxY) = (-np.inf, -np.inf) | ||
+ | |||
+ | # loop over the locations of motion and accumulate the | ||
+ | # minimum and maximum locations of the bounding boxes | ||
+ | for l in locs: | ||
+ | (x, y, w, h) = cv2.boundingRect(l) | ||
+ | (minX, maxX) = (min(minX, x), max(maxX, x + w)) | ||
+ | (minY, maxY) = (min(minY, y), max(maxY, y + h)) | ||
+ | |||
+ | # draw the bounding box | ||
+ | cv2.rectangle(result, | ||
+ | (0, 0, 255), 3) | ||
+ | |||
+ | # increment the total number of frames read and draw the | ||
+ | # timestamp on the image | ||
+ | total += 1 | ||
+ | timestamp = datetime.datetime.now() | ||
+ | ts = timestamp.strftime(" | ||
+ | cv2.putText(result, | ||
+ | cv2.FONT_HERSHEY_SIMPLEX, | ||
+ | |||
+ | # show the output images | ||
+ | cv2.imshow(" | ||
+ | cv2.imshow(" | ||
+ | cv2.imshow(" | ||
+ | key = cv2.waitKey(1) & 0xFF | ||
+ | |||
+ | # if the `q` key was pressed, break from the loop | ||
+ | if key == ord(" | ||
+ | break | ||
+ | |||
+ | # do a bit of cleanup | ||
+ | print(" | ||
+ | print(total) | ||
+ | cv2.destroyAllWindows() | ||
+ | leftStream.release() | ||
+ | rightStream.release() | ||
+ | </ | ||
\\ | \\ | ||
===== Demonstration ===== | ===== Demonstration ===== | ||
+ | After implementing the real-time homography code form the previous section, you should get results similar to the video below. | ||
+ | \\ | ||
+ | {{ youtube> | ||
\\ | \\ | ||
pegasus_cam_homogoraphy.1552049401.txt.gz · Last modified: by dwallace