Jetson 17 OpenCV 人脸识别
来自Waveshare Wiki
基于 OpenCV 的人脸识别
本章节介绍如何使用 OpenCV 来比对特征库,实现人脸识别功能,该功能的效率不如 MediaPipe 的方案高,但是该方案可以通过更换特征库文件来检测其它物体。
准备工作
由于产品开机默认会自动运行主程序,主程序会占用摄像头资源,这种情况下是不能使用本教程的,需要结束主程序或禁止主程序自动运行后再重新启动机器人。
这里需要注意的是,由于机器人主程序中使用了多线程且由 crontab 配置开机自动运行,所以常规的 sudo killall python 的方法通常是不起作用的,所以我们这里介绍禁用主程序自动运行的方法。
如果你已经禁用了机器人主程序的开机自动运行,则不需要执行下面的结束主程序章节。
结束主程序
1. 点击上方本页面选项卡旁边的 “+”号,会打开一个新的名为 Launcher 的选项卡。
2. 点击 Other 内的 Terminal,打开终端窗口。
3. 在终端窗口内输入 bash 后按回车。
4. 现在你可以使用 Bash Shell 来控制机器人了。
5. 输入命令: sudo killall -9 python
例程
以下代码块可以直接运行:
1. 选中下面的代码块
2. 按 Shift + Enter 运行代码块
3. 观看实时视频窗口
4. 按 STOP 关闭实时视频,释放摄像头资源
如果运行时不能看到摄像头实时画面
- 需要点击上方的 Kernel - Shut down all kernels
- 关闭本章节选项卡,再次打开
- 点击 STOP 释放摄像头资源后重新运行代码块
- 重启设备
本章节特性
人脸特征库文件与本`.ipynb`处于同一路径内,你可以通过更改 faceCascade 来更改需要检测的内容,你需要使用其它的特征文件来替换当前的 haarcascade_frontalface_default.xml。
当代码块正常运行时,你可以让机器人的摄像头对准人脸,观察画面中会自动圈出人脸所在的位置。
import cv2 # 导入 OpenCV 库,用于图像处理 from picamera2 import Picamera2 # 用于访问 Raspberry Pi Camera 的库 import numpy as np # 用于数学计算的库 from IPython.display import display, Image # 用于在 Jupyter Notebook 中显示图像 import ipywidgets as widgets # 用于创建交互式界面的小部件,如按钮 import threading # 用于创建新线程,以便异步执行任务 # 加载 Haar 特征级联分类器用于面部检测 faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') # 创建一个“停止”按钮,用户可以通过点击它来停止视频流 # ================ stopButton = widgets.ToggleButton( value=False, description='Stop', disabled=False, button_style='danger', # 'success', 'info', 'warning', 'danger' or '' tooltip='Description', icon='square' # (FontAwesome names without the `fa-` prefix) ) # 定义显示函数,用于处理视频帧并进行面部检测 # ================ def view(button): # 如果你使用的是CSI摄像头 需要取消注释 picam2 这些代码,并注释掉 camera 这些代码 # 因为新版本的 OpenCV 不再支持 CSI 摄像头(4.9.0.80),你需要使用 picamera2 来获取摄像头画面 # picam2 = Picamera2() # 创建 Picamera2 的实例 # picam2.configure(picam2.create_video_configuration(main={"format": 'XRGB8888', "size": (640, 480)})) # 配置摄像头参数 # picam2.start() # 启动摄像头 camera = cv2.VideoCapture(-1) # 创建摄像头实例 #设置分辨率 camera.set(cv2.CAP_PROP_FRAME_WIDTH, 640) camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) display_handle=display(None, display_id=True) # 创建显示句柄用于更新显示的图像 i = 0 avg = None while True: # frame = picam2.capture_array() _, frame = camera.read() # 从摄像头捕获一帧图像 # frame = cv2.flip(frame, 1) # if your camera reverses your image img = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) # 将图像从 RGB 转换为 BGR,因为 OpenCV 默认使用 BGR gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 将图像转换为灰度图,因为面部检测通常在灰度图上进行 # 使用级联分类器进行面部检测 faces = faceCascade.detectMultiScale( gray, scaleFactor=1.2, minNeighbors=5, minSize=(20, 20) ) if len(faces): for (x,y,w,h) in faces: # 遍历所有检测到的面部 cv2.rectangle(frame,(x,y),(x+w,y+h),(64,128,255),1) # 在检测到的面部周围画一个矩形框 _, frame = cv2.imencode('.jpeg', frame) # 将帧编码为 JPEG 格式 display_handle.update(Image(data=frame.tobytes())) if stopButton.value==True: # picam2.close() # 如果是,则关闭摄像头 cv2.release() # 如果是,则关闭摄像头 display_handle.update(None) # 显示“停止”按钮并启动显示函数的线程 # ================ display(stopButton) thread = threading.Thread(target=view, args=(stopButton,)) thread.start()