如何使用树莓派通过OpenCV进行人脸识别

  • 内容
  • 评论
  • 相关

本文的重点是在树莓派上如何使用OpenCV来读取、显示并识别图像,我们可以理解为这是简单的图片识别或人脸识别,图像识别是使用OpenCV时需要掌握的基础之一,也是很多代码中最常用的一部分。

前言

如果我们想制作一个安防机器人,在你不在家的时候机器人在家中巡游并拍照,那么本文将是类似项目的基础。 下面让我们首先分别来了解用于读取、显示和保存图像的函数。然后通过编写代码,使程序能通过树莓派摄像头模块来检测人脸,并在检测到的人脸周围创建一个矩形并拍照记录,从而实现简单的人脸识别。

在树莓派上使用OpenCV读取图片

在OpenCV中用于读取图像的函数是cv2.imread(),它有两个参数,具体如下:

  1. 第一个参数是写入图片的名称。如果图片在当前工作目录中,那么可以只写带扩展名的名称,否则,就必须给出图片的完整路径。
  2. 第二个参数传递一个标志,该标志告诉程序应该如何读取图片,它又包含了以下三种标志:
  • 1 或 cv2.IMREAD_COLOR 加载彩色图像,使用默认颜色,忽略图像的透明度。
  • 0 或 cv2.IMREAD_GRAYSCALE 加载灰度图像。
  • -1 或 cv2.IMREAD_UNCHANGED 加载图像,包括alpha通道。
image = cv2.imread('obama.jpg', 0)
或者
image = cv2.imread('obama.jpg', cv2.IMREAD_GRAYSCALE)

在树莓派上使用 OpenCV 显示图像

在OpenCV中用于显示图像的函数是cv2.imshow()。这个函数同样传递两个参数:第一个参数是窗口名称,第二个参数是图像名称。注意:单独使用这个函数和参数不支持更改此函数创建的窗口大小。

如果需要调整窗口大小,那么需要用到函数 cv2.namedWindow(),它可以新创建一个窗口,然后使用再函数 cv2.imshow() 在其中显示图像。

cv2.namedWindow('Obama', cv2.WINDOW_NORMAL) 
cv2.imshow('Obama', image)

在树莓派上使用 OpenCV 写入图像

在OpenCV中写入图片的函数是cv2.imwrite(),它还是传递两个参数:第一个参数是图像的文件名(图片将使用这个名称进行保存),第二个参数是想要保存的对象图片名称。该函数支持把图片保存为其他格式, 如将把JPG图像更改为PNG格式保存。

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

实现读取、显示和写入图片的Python代码

# 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()

运行这个代码之后,将出现一个类似于下面的输出窗口。如果你按' s ',程序会以灰度形式保存图像,但如果你按ESC,它会退出窗口而不保存图像。 下图以美国前总统奥巴马图片为例。

Obama
Obama

代码释义

cv2.waitkey() 是一个键盘事件函数,它将为键盘事件指定一个等待时间。它有一个参数,该参数是一个时间参数,以毫秒为单位。如果在指定的时间内按下某个键,程序将继续执行。传递 0 意味着只有某一个键被触后才执行后续程序,否则将一直处于等待状态。

cv2.destroyAllWindows() 函数的作用是:关闭所有打开的窗口。如果要关闭特定窗口,使用 cv2.destroyWindow() 时需要在参数中指定窗口名称。

在树莓派上使用OpenCV完成人脸识别

现在根据我们上面的知识,让我们来写一个演示代码,代码将在一直查找人脸,直到找到为止,当检测到一个人脸后,代码会在人脸周围创建一个矩形框,然后保存图像。

 # 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()

当我们运行这段代码后,应该能够看到一个新的图像文件被写入到相应的目录中,该图片会以矩形框突出显示人脸。效果如下图,仍然以Obama为例:

美国前总统奥巴马
美国前总统奥巴马

如果我们想深入了解人脸识别,弄懂基础知识是很必要的。