赞
踩
入手 Nano 后发现官方镜像包含的 OpenCV 并不支持 python3。眼看 python2 要退出时代潮流了,这里整理了重新构建 OpenCV 的流程步骤,并简单解释了 JetsonNano+OpenCV+Gstreamer 结构的工作原理。
https://jkjung-avt.github.io/setting-up-nano/
https://github.com/jkjung-avt/jetson_nano
https://jkjung-avt.github.io/opencv-on-nano/
https://www.jetsonhacks.com/2019/04/02/jetson-nano-raspberry-pi-camera/
https://github.com/JetsonHacksNano/CSI-Camera
https://blog.csdn.net/u011337602/article/details/81485246
https://developer.download.nvidia.cn/embedded/L4T/r31_Release_v1.0/Docs/Accelerated_GStreamer_User_Guide.pdf
假如,你的 Nano 是刚刷的镜像,运行环境没有大的改变,那么搭建 OpenCV+Gstreamer 的过程非常简单。
1、当然,首先已经有了一个 Nano,并完成了初始环境的搭建。参考步骤
2、然后,要有一个摄像头,为了节省 USB 接口(用它们的地方出乎想象的多),还是买一个板载摄像头吧,已经测试可用的型号是 IMX-219。参考步骤。
3、值得庆幸的是官方的镜像包含 Gstreamer 不需要重新安装。这里安装的是 opencv-3.4.6 版本,安装步骤非常简单:
$ sudo nvpmodel -m 0 # 把 Nano 性能开到最大模式(10W)
$ sudo jetson_clocks
$ cd ${HOME}/project # 开始安装
$ git clone https://github.com/jkjung-avt/jetson_nano.git
$ cd ${HOME}/project/jetson_nano
$ ./install_opencv-3.4.6.sh
4、安装过程中会遇到卡点:由于网络问题 get-pip.py 以及后面通过 pip 安装依赖包的过程中,都会因为 timeout 而屡屡失败,可以尝试通过修改 ~/.pip/pip.conf
中的 timeout 来避免失败,但是下载速度还是惨不忍睹。参考步骤
wget https://bootstrap.pypa.io/get-pip.py -O $folder/get-pip.py
sudo python3 $folder/get-pip.py
sudo python2 $folder/get-pip.py
sudo pip3 install protobuf
sudo pip2 install protobuf
sudo pip3 install -U numpy matplotlib
sudo pip2 install -U numpy matplotlib
我的解决方案是,复制在安装过程中显示的下载连接,直接下载安装包(可能需要 FanQiang),然后通过 pip3 install numpy-1.17.2.zip
。
5、如果安装过程中发生失败,脚本执行中断,没有关系,重新跑一边就行。如果有心研究,也可以自己复制文件中的脚本,逐行执行。
jetsonnano:~/Jetson-Nano/RoBFang/opencv$ sudo pip3 install -U numpy matplotlib
Collecting numpy
Downloading https://files.pythonhosted.org/packages/ac/36/325b27ef698684c38b1fe2e546e2e7ef9cecd7037bcdb35c87efec4356af/numpy-1.17.2.zip (6.5MB)
1、安装完成后,迫不及待要测试一把,先在命令行分别单独测试:
# 测试摄像头
$ gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM),width=3820, height=2464, framerate=21/1, format=NV12' ! nvvidconv flip-method=2 ! 'video/x-raw,width=960, height=616' ! nvvidconv ! nvegltransform ! nveglglessink -e
# 测试 OpenCV
$ python3 -c 'import cv2; print("python3 cv2 version: %s" % cv2.__version__)'
$ python2 -c 'import cv2; print("python2 cv2 version: %s" % cv2.__version__)'
2、然后,找一个基于 OpenCV 的 识别人脸 的代码试试:
wget https://github.com/JetsonHacksNano/CSI-Camera/archive/master.zip -O CSI-Camera.zip
unzip CSI-Camera.zip
cd CSI-Camera
python3 face_detect.py
这里应该会遇到一个错误,因为检测器的文件路径不对,使用 locate haarcascade_eye.xml
找一下就好。
face_detect.py:
face_cascade = cv2.CascadeClassifier(
"~YourPath~/haarcascade_frontalface_default.xml"
)
eye_cascade = cv2.CascadeClassifier(
"~YourPath~/haarcascade_eye.xml"
)
1、在测试代码中我们可以看到,即使不用 OpenCV,简单实用 gst-launch-1.0
就能展示摄像头拍到的视频。所以,不难理解,它们的关系是:Gstreamer 捕获摄像头的原始视频流数据;OpenCV 以帧(frame)为单位,进行处理(面部识别等)和运算后展现出来。
2、Gstreamer 的 pipeline 是由多个 element 串连起来,数据流从 src 到 sink 参考文档
1# nvarguscamerasrc !
2# 'video/x-raw(memory:NVMM), width=3820, height=2464, framerate=21/1, format=NV12' !
3# nvvidconv flip-method=2 !
4# 'video/x-raw,width=960, height=616' !
5# nvvidconv !
6# nvegltransform !
7# nveglglessink -e
标号 | 角色 | 作用 |
---|---|---|
1 | src element | 通过ARGUS API获取相机数据 |
2 | capabilities | 约定数据源原有格式(3820x2464),NVMM 指定应在连续内存中分配缓冲区 |
3 | common element | 格式转换:垂直翻转图像 |
4 | capabilities | 约定数据输出格式(960x616) |
5 | common element | 格式转换 |
6 | common element | 转换为 EGLimage,EGL 是渲染 API 和原生窗口系统之间的接口 |
7 | end element | 向 X11 桌面系统显示 EGL 视频 |
3、OpenCV 面部识别 代码地址
face_cascade = cv2.CascadeClassifier("~YourPath~/haarcascade_frontalface_default.xml") eye_cascade = cv2.CascadeClassifier("~YourPath~/haarcascade_eye.xml") cap = cv2.VideoCapture(gstreamer_pipeline(), cv2.CAP_GSTREAMER) if cap.isOpened(): cv2.namedWindow("Face Detect", cv2.WINDOW_AUTOSIZE) while cv2.getWindowProperty("Face Detect", 0) >= 0: ret, img = cap.read() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.3, 5) for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) roi_gray = gray[y : y + h, x : x + w] roi_color = img[y : y + h, x : x + w] eyes = eye_cascade.detectMultiScale(roi_gray) for (ex, ey, ew, eh) in eyes: cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2) cv2.imshow("Face Detect", img) keyCode = cv2.waitKey(30) & 0xFF # Stop the program on the ESC key if keyCode == 27: break
函数名 | 作用 |
---|---|
CascadeClassifier | 加载特征分类器(人脸/人眼) |
VideoCapture | 读取视频 |
namedWindow | 新建一个显示窗口 |
getWindowProperty | 窗口是否关闭(返回 -1 为关闭) |
cvtColor | 改变色彩空间 |
rectangle | 画一个矩形 |
face_cascade.detectMultiScale | 检测出图片中所有的人脸 |
eye_cascade.detectMultiScale | 检测出图片中所有的人眼 |
imshow | 把图片显示出来 |
waitKey | 等待按键(ESC) 30ms |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。