In this tutorial we will learn how to obtain video from a webcam and convert it to black and white, using OpenCV and Python.
For an explanation on how to get video from a web camera using OpenCV, please check here.
A very simple way of converting an image to black and white with OpenCV can be done with a binary thresholding operation. For a tutorial explaining how to convert an image to black and white with this approach, please check here.
The code shown below was tested on Windows 8.1, with version 4.1.2 of OpenCV. The Python version used was 3.7.2.
As usual, we start our code by importing the cv2 module.
Then we will instantiate an object of class VideoCapture. As input of the constructor of this class we need to pass a number with the identifier of the camera we want to use. In my case, since I only have one camera attached to the computer, I should use the value 0.
capture = cv2.VideoCapture(0)
After this we will start getting frames from the camera, so we can then convert them to black and white and display them in a window. We will do this inside an infinite loop that will only break if the ESC key is pressed.
while (True): # Grab frames and convert to Black and White if cv2.waitKey(1) == 27: break
To obtain a frame from the camera, we simply need to call the read method on our VideoCapture object.
This method receives no arguments and returns a tuple with the following values:
- A Boolean value indicating if the frame was successfully obtained;
- The frame, as a numpy ndarray.
(ret, frame) = capture.read()
To be able to apply the thresholding operation that will convert the image to black and white, we first need to convert it to gray scale.
We can do this with a call to the cvtColor function, passing as first input the image and as second the color space conversion code. In our case, we want the code COLOR_BGR2GRAY since we are converting the image from BGR to gray.
As output, this function will return a new ndarray representing the image in gray scale.
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
After this we can apply the thresholding operation with a call to the threshold function. We are going to use the simplest thresholding algorithm: binary thresholding.
As already explained on this tutorial, in the binary thresholding operation, we define a threshold value. Then, for each pixel of the gray scale image, if the value of the pixel is lesser than the given threshold, it is set to zero. Otherwise, it is set to a user defined value (in our case, this user defined value should be 255, which corresponds to white).
So, as first input of the threshold function, we pass the gray scale frame. As second input we pass the mentioned threshold. Since we are passing a gray scale image, its pixel values vary between 0 and 255. So we pass a threshold in the middle of the scale: 127.
As third parameter, we pass the user defined value to which a pixel should be converted in case its value is greater than the threshold. As already mentioned, we will pass the value 255, which corresponds to white.
The fourth and last parameter is a constant that specifies the type of thresholding to be applied. We will pass the value THRESH_BINARY, which corresponds to the already mentioned binary thresholding.
This function returns as output a tuple. The first value of the tuple can be ignored for our use case. The second value corresponds to the resulting image, in black and white, after the binary thresholding is applied.
(thresh, blackAndWhiteFrame) = cv2.threshold(grayFrame, 127, 255, cv2.THRESH_BINARY)
To finalize, we will show both frames in two distinct windows.
cv2.imshow('video bw', blackAndWhiteFrame) cv2.imshow('video original', frame)
The full frame capture loop can be seen below.
while (True): (ret, frame) = capture.read() grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) (thresh, blackAndWhiteFrame) = cv2.threshold(grayFrame, 127, 255, cv2.THRESH_BINARY) cv2.imshow('video bw', blackAndWhiteFrame) cv2.imshow('video original', frame) if cv2.waitKey(1) == 27: break
After the loop breaks we will no longer need the camera. Thus, we should release it with a call to the release method on the VideoCapture object. We will also destroy all the windows previously opened with a call to the destroyAllWindows function.
The complete code can be seen below.
import cv2 capture = cv2.VideoCapture(0) while (True): (ret, frame) = capture.read() grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) (thresh, blackAndWhiteFrame) = cv2.threshold(grayFrame, 127, 255, cv2.THRESH_BINARY) cv2.imshow('video bw', blackAndWhiteFrame) cv2.imshow('video original', frame) if cv2.waitKey(1) == 27: break capture.release() cv2.destroyAllWindows()
Testing the code
To test the code, simply run it in a tool of your choice, with a web camera attached to your computer. In my case I’m using PyCharm, a Python IDE.
You should get a result like the one shown in the figure 1 below. As expected, we see both windows: one showing the original video and the other showing the video converted to black and white.