Learn how to use the image processing program OpenCV on Raspberry Pi to read, display, and write images.

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.

        cv2.imwrite('newobama.png', image)
    

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.

Image in Grayscale Mode
        # 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.

Image with face highlighted
Muhammad Aqib
I am an embedded programmer with the expertise in Arduino, Raspberry pi, ESP8266, IOT and OpenCV.