This tutorial focuses on how to use OpenCV on Raspberry Pi to read, display, and write images. This is one of the basic things you need to know when getting started with OpenCV and is one of the most commonly used parts of code.
If you wish to create a surveillance robot that roams around your home and takes pictures when you are not home, then this tutorial is one of the first steps you need to take to set that up.
Let’s first go through each function used to read, display and save an image. Then, we can write our code so that our program uses a Pi camera to detect faces, creates a rectangle around the detected faces, and snaps a picture.
Reading an Image With OpenCV on Raspberry Pi
The function used to read an image is cv2.imread(). This function takes two arguments.
The first argument takes the name of the image. If the image is in the working directory, then you can just write its name. Otherwise, you will have to give the full path of the image.
The second argument takes the flag that tells the program how the image should be read.
- 1 or cv2.IMREAD_COLOR loads a colored image. It uses the default color and neglects the image transparency.
- 0 or cv2.IMREAD_GRAYSCALE loads a grayscale image.
- -1 or cv2.IMREAD_UNCHANGED loads the image as such including alpha channel.
image = cv2.imread('obama.jpg', 0) or image = cv2.imread('obama.jpg', cv2.IMREAD_GRAYSCALE)
We can read an image by using any one of the above lines.
Displaying an Image in OpenCV With Raspberry Pi
The function used to show an image is cv2.imshow(). This function also takes two arguments: the first argument is the window name and the second argument is the name of the image.
NOTE: You cannot change the size of the window created by this function.
There is also a function (cv2.namedWindow()) that you can use to create a window and then use cv2.imshow() to display the image in it. You will be able to resize images this way.
cv2.namedWindow('Obama', cv2.WINDOW_NORMAL) cv2.imshow('Obama', image)
Write an Image in OpenCV with Raspberry Pi
The function to write the image is cv2.imwrite() and it also takes two arguments: the first argument is the image file name (Image will be saved with this file name) and the second argument is the name of the image you want to save.
You can also save the image in other formats like the following line will change the JPG image into PNG format.
Python Code to Read, Display, and Write Images
After running the code, an output window similar to the one below appears. If you press ‘s’, the program saves the image in grayscale but if you press ESC, it will exit the window without saving the image.
# Import OpenCV library import cv2 # Load color image in grayscale image = cv2.imread('obama.jpg', 0) #or #image = cv2.imread('obama.jpg', cv2.IMREAD_GRAYSCALE). # Create the resizeable window cv2.namedWindow('Obama', cv2.WINDOW_NORMAL) # Display the image cv2.imshow('Obama', image) # Wait until we get a key k=cv2.waitKey(0) # If pressed key is 's' if k == ord('s'): # Save the image cv2.imwrite('convertedimage.jpg', image) # Destroy all windows cv2.destroyAllWindows() # If pressed key is ESC elif k == 27: # Destroy all windows cv2.destroyAllWindows()
cv2.waitkey() is a keyboard binding function that waits for a specified amount of time for any keyboard event. It takes one argument, which is time in milliseconds. If the key is pressed in the specified timeframe, the program will continue. Passing 0 means it will wait indefinitely for a key.
cv2.destroyAllWindows() function destroys all the opened windows. If you want to destroy a specific window, use the cv2.destroyWindow() and pass the windows name as an argument.
Capture Image and Detect Faces With OpenCV on Raspberry Pi
Now based on what we learned, let’s write a demo code that will keep looking until a face is detected. After it detects a face, it will make a rectangle around that face and save the image.
# import the necessary packages from picamera.array import PiRGBArray from picamera import PiCamera import cv2 import numpy as np # initialize the camera and grab a reference to the raw camera capture camera = PiCamera() camera.resolution = (640, 480) camera.framerate = 30 rawCapture = PiRGBArray(camera, size=(640, 480)) # Load a cascade file for detecting faces face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml"); # capture frames from the camera for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True): # grab the raw NumPy array representing the image, then initialize the timestamp # and occupied/unoccupied text image = frame.array # Convert to grayscale gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) # Look for faces in the image using the loaded cascade file faces = face_cascade.detectMultiScale(gray, 1.1, 5) # Show the frame cv2.imshow("Frame", image) # Wait for key key = cv2.waitKey(1) & 0xFF # clear the stream in preparation for the next frame rawCapture.truncate(0) faceDetected = False # Draw a rectangle around every found face for (x,y,w,h) in faces: faceDetected = True # Create rectangle around the face cv2.rectangle(image,(x,y),(x+w,y+h),(255,255,0),2) # Save the image cv2.imwrite("result.jpg", image) if faceDetected == True: break cv2.destroyAllWindows()
Try running this code, you should be able to see a new image file written to the respective directory that highlights a face in the picture.