一、总体架构
本文主要是使用树莓派自带的csi摄像头,搭配上opencv4.10.0进行物体的识别。本文使用的环境是python3.7.3,环境不一样有可能安装的opencv的过程也会很不一样,但是python的环境我们可以自己自行安装。
二、树莓派系统的安装
本文使用了树莓派官方给的镜像烧录软件Raspberry Pi Imager来烧录镜像,该软件的下载地址是:
https://www.raspberrypi.com/software/
打开之后我们选择raspberry pi4。
然后选择Raspberry Pi OS(other),选择Legacy,64-bit,为什么要选择64位的系统呢,因为在opencv中通常会用到大量的图像处理的过程的,所以用64位的系统可以大大加快我们处理的速度。作者建议你们最好不要下载在烧录软件一开始的那个镜像,那个镜像是Bookworm的,有些是和opencv的依赖包是不适配的,所以会导致一系列的问题,你甚至连依赖包可能都不能下载完整,所以还是选择稳定一点的镜像比较好。
在下载之前,该烧录软件会让你设置你的WiFi用户名还有ssh的东西,设置完之后就等待烧录完成。
使用ssh登录树莓派。
使用MobaXterm开发工具就可以使用ssh连接树莓派了,MobaXterm是一个强大的开发工具,他提供了多种的连接方式,也提供了 X-server,X-server可以
三、opencv的安装
3.1 换源
3.1.1 查看系统的版本
你系统的版本决定了你后面换源的时候所要换成的源,如果你的系统是bookworm的,但是你却放了个buster的源,这样系统在你sudo update的时候就会报错说你的源并不适用于arm64的架构,所以首先我们要先看系统的版本。
lsb_release -a
此处可见我的操作系统的版本是bullseye,确定了版本之后就可以开始换源了。
3.1.2 给树莓派换源
sudo nano /etc/apt/sources.list
将里面的东西全部删掉或者注释掉,换成清华或者阿里云的源,本文使用的是清华源。
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free
deb-src http://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-backports main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bullseye-security main contrib non-free
替换之后就是这样子了。
然后再替换下面这个。
sudo nano /etc/apt/sources.list.d/raspi.list
deb http://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ bullseye main
deb-src http://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ bullseye main
替换完如下图。
要特别注意你自己树莓派的操作系统的版本,如果不是bullseye的话,请自行更换,其实就是将bullseye换成你自己的操作系统的版本。
3.2 更换Python的环境
3.2.1 查看Python的版本
使用python --version查看你当前python的版本,如果是3.8以上的python,作者建议你还是把他换掉,换成3.8以下的版本,因为3.9版本的很多bug,而且有很多时候可能会和opencv在某些东西上会不适配,所以为了不必要的麻烦,作者还是建议你们将python的版本换成3.8以下的,作者的python的版本是3.9.2的,所以我将安装python3.7.3,python3.7.3的版本比较稳定,作者选择这个版本来作为opencv的运行环境。
python --version
3.2.2 编译安装python3.7.3
首先要更新一下,这步很重要,不更新的话很可能会报错。
sudo apt update
下载依赖项
sudo apt install build-essential libssl-dev zlib1g-dev libncurses5-dev libncursesw5-dev libreadline-dev libsqlite3-dev libgdbm-dev libdb5.3-dev libbz2-dev libexpat1-dev liblzma-dev tk-dev
下载python3.7.3的安装包
cd /usr/src
sudo wget https://www.python.org/ftp/python/3.7.3/Python-3.7.3.tgz
下完之后,进行编译安装
sudo tar xzf Python-3.7.3.tgz
cd Python-3.7.3
sudo ./configure --enable-optimizations
sudo make altinstall
最后一步一定要注意,一定要用 altinstall,不然你系统现有版本的python的版本会被覆盖的,所以要用altinstall防止现有版本的python被覆盖了。编译安装的过程时间可能会有点长,所以请耐心等待。
完成编译之后,检查是否成功安装:
python3.7 --version
通过以下命令检查当前 Python 3.7 的实际路径,以确认是哪个版本被配置到了
which python3.7
到此,你的python3.7.3版本就成功安装到树莓派系统上了。
3.3 创建虚拟环境
在安装opencv之前,我们最好是在一个虚拟环境中来运行,虚拟环境可以隔离项目依赖,防止不同项目间的库版本冲突。例如说你另外一个项目是需要python3.9的,但是opencv只需要python3.7的,这样就产生了冲突,所以做好是使用虚拟环境来运行opencv。
安装虚拟环境管理包
sudo apt install python3-venv
创建虚拟环境,这里最好是用python3.7这样明确的python环境来创建,不然可能会把你系统的python3.9误认为是用他创建虚拟环境,导致错误。
python3.7 -m venv opencvENV #你自己想要起的名字
创建完之后也可以检查一下虚拟环境的python版本是否是python3.7
如果遇到了创建虚拟环境失败,例如下图,可以试试以下的办法。
- 直接创建,跳过pip,后续再自己安装,python3.7 -m venv --without-pip opencvENV
2.看看你自己系统的python是哪个版本,如果是3.7.3的话,将其替换回3.9的,再创建。(作者也不知道为什么用了这个方法就创建成功了,有点奇怪)
然后就是激活虚拟环境了。
source opencvENV/bin/activate
如果想退出虚拟环境的话,就使用以下命令。
deactivate
激活虚拟环境之后,会在你主机名前面会出现你虚拟环境的名字,说明虚拟环境设置成功。
3.4 安装opencv
此处下载使用了清华源作为加速,用官方的源下载太慢了。
pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
如果报此错误,就更新一下pip,因为pip版本太老了,导致有些依赖不匹配。
pip install --upgrade pip setuptools
再次尝试安装opencv。
运行以下命令,验证是否能成功导入opencv。
python -c "import cv2; print(cv2.__version__)"
现在已经成功安装了 OpenCV 4.10.0!可以正常使用 OpenCV 进行开发了。
四、opencv案例测试
4.1 打开树莓派的摄像头
使用raspi-config命令来打开树莓派的系统配置,在里面将树莓派的摄像头enable。
sudo raspi-config
打开之后就是这样的界面,然后选择Interface Options
然后将Legacy Camera 打开就行,打开之后就直接重启树莓派就可以应用了。
4.2 摄像头测试
安装摄像头的过程略,其实就是把有颜色的那面排线朝向网口那边就行了。下面介绍两个测试你的摄像头是否能用的方法,没有兴趣或者确定自己摄像头能用的读者可直接跳过。
4.2.1 通过libcamera来测试
如果想测试一下摄像头的显示是否正常的话,你可以用libcamera来测试一下是否能正常显示,但是要注意,现在的摄像头的驱动都是新的,所以要去修改一些东西,使树莓派系统使用新的摄像头驱动。
sudo nano /boot/config.txt
找到这段语句,将start_x=1屏蔽掉,再在文件的最后加入gpu_mem=128这段话,将树莓派重启sudo reboot之后,就可以开始测试摄像头是否能用了。
执行libcamera-hello,就可以成功测试到你的摄像头是否能用了,此时在mobaxterm的x-server上,会显示出你当时的摄像头所显示出来的东西。
libcamera-hello
当使用回opencv的时候,需要把 start_x=1给放出来,因为目前树莓派使用的摄像头驱动是新的驱动,而opencv现在还是使用的旧驱动,所以这两者之间就产生了冲突,简而言之就是可以每次只能使用其中一个,另外一个就用不了,所以取舍一下就把libcamera给舍弃掉了。
4.2.2 通过vcgencmd get_camera来测试
修改config.txt文件,在文件的最后面加入gpu_mem=128。
sudo nano /boot/config.txt
sudo reboot
重启完之后,运行以下命令,检查树莓派是否识别到了摄像头。
vcgencmd get_camera
如果成功识别到了,就会显示出以下的东西,要注意的是,如果把start_x=1给屏蔽了,这几个都是会显示为0的,也就是没有识别到摄像头,原因也是像上面说的一样,驱动不一样,所以导致无法识别到摄像头的存在。
4.3 案例测试
4.3.1 安装pyzbar库
在虚拟环境中使用pip命令来安装pyzbar库。
pip install pyzbar
4.3.2 程序编写
本文所写的案例是识别二维码的,当在虚拟环境中运行py代码的时候,树莓派的csi摄像头会启动来识别到二维码。
首先先创建一个用来放代码的文件夹。
sudo mkdir -p myprojects
然后在此文件夹下可以直接创建一个py文件来放程序。
sudo nano read.py
程序的完整代码如下:
二维码检测代码。
# coding:utf8
import cv2
import pyzbar.pyzbar as pyzbar
def decodeDisplay(image, image1):
barcodes = pyzbar.decode(image)
for barcode in barcodes:
# 提取条形码的边界框的位置
# 画出图像中条形码的边界框
(x, y, w, h) = barcode.rect
cv2.rectangle(image1, (x, y), (x + w, y + h), (0, 0, 255), 2)
# 条形码数据为字节对象,所以如果我们想在输出图像上
# 画出来,就需要先将它转换成字符串
barcodeData = barcode.data.decode("utf-8")
barcodeType = barcode.type
# 绘出图像上条形码的数据和条形码类型
text = "{} ({})".format(barcodeData, barcodeType)
cv2.putText(image1, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX,
.5, (0, 0, 125), 2)
# 向终端打印条形码数据和条形码类型
print("[INFO] Found {} barcode: {}".format(barcodeType, barcodeData))
return image1
def detect():
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("[ERROR] Could not open video device")
return
while True:
# 读取当前帧
ret, img = cap.read()
if not ret or img is None:
print("[ERROR] Failed to capture image")
break
# 转为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
im = decodeDisplay(gray, img)
key = cv2.waitKey(5)
cv2.namedWindow('image', 0)
cv2.resizeWindow('image', 700, 500)
cv2.imshow("image", im)
if key == 27: # ESC 键退出
break
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
detect()
写完代码之后,就可以直接运行该文件了。
python read.py
执行之后,在x-server可以看到当前的画面,此时你把一个二维码放上去,就可以识别出来了。
由于二维码里面有隐私信息,所以我就不把识别出来的东西放出来了,总之就是就是会提示你识别到二维码了。
五、人脸识别
cd ~/openENV/myprojects
把文件clone下来。
git clone https://gitee.com/jeebus/Facial_Recognition.git
cd Facial_Recognition
首先可以试着检测一下摄像头,这时会出现一个灰色的,一个正常显示的。
python simpleCamTest.py
这时候你的摄像头是翻转的,需要在代码中修改或者反转你自己的摄像头。
最后运行人脸识别的代码。
python faceDetection.py
如果想要修改摄像头翻转的话,就要进入代码中修改。
sudo nano faceDetection.py
将一开始代码中的 img = cv2.flip(img,-1) 将那个 -1 改成1,就可以解决摄像头翻转的问题了。
再次运行程序,就能正常显示了。
他不仅能够直接使用人脸识别的案例,他还可以自己训练自己的模型,就是使用那个01_face_dataset.py程序来采集你自己想要识别的人脸,他会采集30张照片,随后使用02_face_training.py就可以训练你自己的模型了,最后使用03_face_recognition.py就可以识别你刚刚采集的人脸了,这里作者就不演示了,请读者自行去试试。
六、结语
现在这个只是 一个简单的人脸识别的案例,后续读者可以自己训练模型或者在opencv的官方库里面找一些案例来试着运行,opencv的官方库的地址如下:
opencv/samples/python at 4.x · opencv/opencv · GitHub
里面有用python程序写的一些案例,例如说边缘检测什么的,后续更多的功能就交给读者去开发了。