What will we cover in this tutorial?
We will use OpenCV to capture a live feed from your webcam and insert a logo into the lower right corner. It will end up like this.
Step 1: Getting a live stream from your webcam using OpenCV
First thing first. You need to have OpenCV installed. If you use PyCharm then you can read this tutorial to get it installed.
OpenCV is a powerful computer vision and machine learning library, which luckily has a Python interface.
To get the webcam on your laptop you can simply set it up by calling VideoCapture().
import cv2 # Setup camera cap = cv2.VideoCapture(0) # Set a smaller resolution cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) while cap.isOpened(): # Capture frame-by-frame ret, frame = cap.read() if ret: # Display the resulting frame cv2.imshow('WebCam', frame) if cv2.waitKey(25) & 0xFF == ord('q'): break else: break # When everything done, release the capture cap.release() cv2.destroyAllWindows()
This will stream your webcam to your screen in a 640×480 window. You can adjust the size in as you please.
The main program is captured in a while-loop. It reads a frame and a return value. Then it displayed it with imshow(). It called waitKey(25), which will wait 25 milliseconds and if q is pressed, it will break out of the while-loop and terminate.
One thing you will notice, is that the picture is a flipped mirror. We will deal with that in a moment.
Step 2: Understand NumPy and what a view is
Well, we will not cover all of NumPy here, but one thing is important to understand. Firstly, which might not be clear from the above, but the image objects from OpenCV are NumPy arrays (ndarray). Hence, we can use this in manipulating the objects, which we will below.
We will utilize how view works in NumPy arrays. A view is explained simplest with an example.
import numpy as np a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) view = a[1:, 1:] print(a) print(view) view[:] = 0 print(a)
In the above example we will get the following output.
[[1 2 3] [4 5 6] [7 8 9]] [[5 6] [8 9]] [[1 2 3] [4 0 0] [7 0 0]]
Where we first see the ndarray a and then the view of view. Exactly, the view of view. When you assign view = a, it will only be a view into it. That means, if you change values of view, they also change in a. This is apparent in the final two lines view[:] = 0 and the following print statement of a. The view[:] = 0 assigns all values in view to 0. As they point into a, the values of a are changed.
First time you see this, it might be a bit confusing.
But consider this.
import numpy as np a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) view = a[1:, 1:] view[:] = 0 a[:] = -1 print(view)
Which results in this output.
[[-1 -1] [-1 -1]]
As view still is looking at the positions in a.
Step 3: Using the view to mask out logo and add it in
With the above in mind of how a view works, the following code should be easier to digest.
import cv2 import numpy as np # Setup camera cap = cv2.VideoCapture(0) # Set a smaller resolution cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) # Read logo and resize logo = cv2.imread('logo.png') size = 100 logo = cv2.resize(logo, (size, size)) # Create a mask of logo img2gray = cv2.cvtColor(logo, cv2.COLOR_BGR2GRAY) ret, mask = cv2.threshold(img2gray, 1, 255, cv2.THRESH_BINARY) while cap.isOpened(): # Capture frame-by-frame ret, frame = cap.read() if ret: # Flip the frame frame = cv2.flip(frame, 1) # Region of Image (ROI), where we want to insert logo roi = frame[-size-10:-10, -size-10:-10] # Set an index of where the mask is roi[np.where(mask)] = 0 roi += logo cv2.imshow('WebCam', frame) if cv2.waitKey(25) & 0xFF == ord('q'): break else: break # When everything done, release the capture cap.release() cv2.destroyAllWindows()
A few things to notice. The cv2.flip(frame, 1) obviously flips the frame so it is like a mirror.
The roi (region of image) gives us a view, where we can change the values directly in the image from the frame. The first thing we do is to mask out our logo shape. Then we add the logo to the frame.
This should result in the expected output as given above.