嵌入式系统与OpenCV
目录
一、OpenCV 简介
二、嵌入式 OpenCV 的安装方法
1. Ubuntu 系统下的安装
2. 嵌入式 ARM 系统中的安装
3. Windows10 和树莓派系统下的安装
三、嵌入式 OpenCV 的性能优化
1. 介绍嵌入式平台上对 OpenCV 进行优化的必要性。
2. 利用嵌入式开发工具,如优化的 C 语言编译器、软件库和驱动器等进行优化。
3. 通过实验对比 OPENMP、TBB 与多线程在嵌入式上的图像处理加速效果。
四、嵌入式 OpenCV 的应用案例
1. 在树莓派上实现从零开始的嵌入式图像图像处理,包括打开摄像头、编写程序获取并显示实时视频等。
2. 在 Ubuntu 系统下通过 OpenCV 实现点阵汉字的字模读取与显示。
五、嵌入式 OpenCV 的优势
一、OpenCV 简介
OpenCV 是一个功能强大的开源计算机视觉库,具有诸多优势和广泛的应用领域。
优势:
- 跨平台:可以在不同的系统平台上使用,包括 Windows、Linux、Android 和 Mac OS 操作系统。
- 编程语言:用 C++ 语言编写,同时提供 Python、Ruby、MATLAB 等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
- 活跃的开发团队:自 2000 年公开第一个预览版本以来,目前已更新至 OpenCV4.5.3。
- 丰富的 API:完善的传统计算机视觉算法,涵盖主流的机器学习算法,同时添加了对深度学习的支持。
- 开源:以 BSD 许可证授权发行,可以在商业和研究领域中免费使用。
应用领域:
- 增强现实
- 人脸识别
- 手势识别
- 人机交互
- 动作识别
- 运动跟踪
- 物体识别
- 图像分割
- 机器人
- 运动分析
- 机器视觉
- 结构分析
- 汽车安全驾驶等领域。例如在自动驾驶领域,OpenCV 可以通过对车辆周围环境进行实时图像与视频分析,帮助汽车判断道路情况、障碍物等,从而保证行车安全;在医学图像处理领域,OpenCV 可以用于对医学图像(如 MRI、CT 等)进行分析和诊断,为医生提供重要的参考信息。
二、嵌入式 OpenCV 的安装方法
1. Ubuntu 系统下的安装
- 安装环境准备,包括安装 CMake 和依赖环境。
在 Ubuntu 中打开终端的快捷键是 [Ctrl]+[Alt]+[T],然后进行以下操作:
-
- 安装 CMake:sudo apt-get install cmake。
-
- 安装依赖环境:sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg-dev libswscale-dev libtiff5-dev,sudo apt-get install libgtk2.0-dev,sudo apt-get install pkg-config。
- 下载 OpenCV 并解压到 Ubuntu 的 Home 目录下。
从官网下载 Sources 版本的 OpenCV,下载地址为:https://opencv.org/releases/。在 Windows 下载压缩包并解压后,将解压后的文件复制到 Ubuntu 系统的 home 目录下。
- 创建 build 文件,进行 CMake 配置、编译和安装。
-
- 进入 OpenCV 文件并创建 build 文件:在终端中,进入 OpenCV 文件所在目录,假设文件名为 opencv-3.4.11,使用cd opencv-3.4.11命令,然后在该文件夹下新建 build 文件夹,并将操作路径改到 build 下,使用mkdir build和cd build命令。
-
- CMake:输入命令sudo cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local..进行编译参数配置。
-
- 使用 make 创建编译:在 build 文件夹下进行编译,可以使用sudo make -j4或sudo make -j8等命令加快编译速度,这里会等待大概十几分钟,报错的话可以多尝试几次。
-
- 进行安装:使用sudo make install命令进行安装。
- 完成配置,包括更新系统共享链接库和配置 bash。
-
- 用 gedit 打开 /etc/ld.so.conf:sudo gedit /etc/ld.so.conf,在文件中加上一行include /usr/loacal/lib(其中 /usr/loacal/lib 是 OpenCV 安装路径也就是 makefile 中指定的安装路径)。
-
- 更新系统共享链接库:sudo ldconfig。
-
- 配置 bash:修改 bash.bashrc 文件,sudo gedit /etc/bash.bashrc,在文件末尾加入PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig和export PKG_CONFIG_PATH。保存并退出,然后执行如下命令使得配置生效:source /etc/bash.bashrc。
-
- 更新:sudo updatedb。
2. 嵌入式 ARM 系统中的安装
- 使用特定的编译配置进行编译安装。
-
- 安装依赖项:sudo apt update,sudo apt install build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev。
-
- 下载 OpenCV 源代码,从官方网站下载 OpenCV 的源代码,假设下载到用户的主目录(~/)下。
-
- 进行编译配置,例如:./configure --host=arm-linux --without-gtk --without-carbon --without-quicktime --without-1394libs --without-ffmpeg --without-python --without-swig --enable-static --disable-shared --disable-apps CXX=armv4l-unknown-linux-g++ CPPFLAGS=-I/usr/include。
-
- 进行编译:make。
-
- 安装:make install,安装完成后,设置环境变量export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig。
- 编译例程并解决可能出现的问题。
-
- 编译例程,例如:armv4l-unknown-linux-g++ pkg-config --cflags --libs opencv drawing.c -o drawing或者尝试(某些情况下,顺序问题可能引发 undefined reference 错误)arm-linux-g++ drawing.c -o drawing pkg-config --cflags --libs opencv。如果编译出现问题,如缺少开发包,可以根据错误提示进行安装,比如在 Debian 下可以apt-get install libpng2-dev`,或者到相应网站下载安装开发包。
- 配置摄像头驱动和显示。
-
- 以网眼 V2000 为例,内核选项加入 OV511 驱动,并且模块加载。OpenCV 程序中默认设备为/dev/video0,在程序中调用cvCaptureFromCAM函数可以直接获取摄像头,并采集图像。
-
- 直接在要显示的地方调用显示驱动函数。
3. Windows10 和树莓派系统下的安装
- Windows10 下安装 OpenCV3.4.1,配置系统环境变量并编写测试项目。
-
- 安装 OpenCV3.4.1:从官网下载 Windows 版,然后在 path 中添加以下路径:“D:\mydownload\opencv341\opencv\build\x64\vc15\bin”,添加完后需重启电脑。
-
- 基于 VS2017 写一个 OpenCV 调用灰度图片的项目:
-
-
- 添加 C++ 空项目 Project1。
-
-
-
- 右键添加项 test1.cpp。
-
-
-
- 将 debug 调为 X64,接下来都将在 debug 模式下进行配置。
-
-
-
- 配置属性:打开属性管理器,在右侧栏出现属性管理器界面,点开,选择 Debug x64 右键 “属性”,添加包含目录(分别是 include,include\opencv ,include\opencv2,建议三个都添加)、库目录和附加依赖项(手动敲入 opencv_world341d.lib)。
-
-
- 编写测试程序同时显示两张图片:并自动保存改变灰度后的图片到项目工程文件夹中,源码如下:
#include <highgui.hpp>
#include <opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc,char** argv)
{
CvPoint center;
double scale = -3;
IplImage* image = cvLoadImage("d://myworkspace//VisualStudioProjects//lena.jpg");
//引入图片位置argc == 2? cvLoadImage(argv[1]) : 0;
cvShowImage("Image", image);
if (!image) return -1;
center = cvPoint(image->width / 2, image->height / 2);
for (int i = 0; i < image->height; i++)
for (int j = 0; j < image->width; j++)
{
double dx = (double)(j - center.x) / center.x;
double dy = (double)(i - center.y) / center.y;
double weight = exp((dx * dx + dy * dy) * scale);
uchar* ptr = &CV_IMAGE_ELEM(image, uchar, i, j * 3);
ptr[0] = cvRound(ptr[0] * weight);
ptr[1] = cvRound(ptr[1] * weight);
ptr[2] = cvRound(ptr[2] * weight);
}
Mat src; Mat dst;
src = cvarrToMat(image);
cv::imwrite("test.png", src);
cvNamedWindow("test", 1);
imshow("test", src);
cvWaitKey();
return 0;
}
- 树莓派系统下安装 OpenCV3.4.1,与 Ubuntu 安装步骤类似。
-
- 软件源更新:sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev。
-
- 安装 gtk2.0:这一步对应前边最好用清华的源,不然下载容易出错。
-
- 安装 OpenCV:
-
-
- 安装 opencv-python:在终端输入pip3 install opencv-python。
-
-
-
- 安装 opencv-contrib:安装完 opencv-python 后,继续安装 opencv-contrib,需要安装指定版本 4.1.0.25,在终端输入pip3 install opencv-contrib-python==4.1.0.25。如果遇到网络问题,可以在可以科学上网的电脑上用浏览器下载轮子,然后导入树莓派进行本地安装。
-
-
-
- 安装依赖:在终端运行以下命令安装依赖:sudo apt-get install libatlas-base-dev -y,sudo apt-get install libjasper-dev -y,sudo apt-get install libqtgui4 -y,sudo apt-get install python3-pyqt5 -y,sudo apt-get install libqt4-test -y,sudo apt-get install libhdf5-dev -y。
-
-
- 至此,树莓派下的 OpenCV 安装完成,进入 python3 的运行环境,加载import cv2试试。
三、嵌入式 OpenCV 的性能优化
在嵌入式平台上,对 OpenCV 进行优化是至关重要的。随着嵌入式设备在各个领域的广泛应用,如安全监控、工业自动化等,对图像处理的速度和效率要求越来越高。而嵌入式平台通常资源有限,如处理器性能相对较弱、内存容量较小等,这就使得优化 OpenCV 以提高其在嵌入式平台上的性能变得尤为必要。
1. 介绍嵌入式平台上对 OpenCV 进行优化的必要性。
嵌入式设备往往需要实时处理图像数据,以满足各种应用场景的需求。例如,在自动化车辆中,需要快速准确地识别道路情况和障碍物,这对图像处理的速度提出了很高的要求。如果 OpenCV 在嵌入式平台上的性能不佳,可能会导致延迟过高,影响系统的实时性和可靠性。此外,优化 OpenCV 还可以降低嵌入式设备的功耗,延长电池寿命,提高设备的整体性能。
2. 利用嵌入式开发工具,如优化的 C 语言编译器、软件库和驱动器等进行优化。
典型的嵌入式器件通常是系统级芯片(SoC),其中不仅包含 ARM 处理器,还含有多种外设与加速器。为了充分发挥 SoC 的性能,需要利用各种嵌入式开发工具进行优化。例如,优化的 C 语言编译器可以生成更高效的代码,加速常见信号处理任务的优化软件库可以提高图像处理的速度,处理 SoC 中不同模块之间低级互动的驱动器可以提高系统的稳定性和可靠性。此外,还可能包括支持特定厂商协处理器与加速器的特殊工具,这些工具可以进一步提高 OpenCV 在嵌入式平台上的性能。
3. 通过实验对比 OPENMP、TBB 与多线程在嵌入式上的图像处理加速效果。
有研究表明,OPENMP 和 TBB 可以有效对并行处理进行加速,其效果与多线程处理基本持平。例如,在某个嵌入式上的图像处理项目中,通过对比基础 FOR 循环、多线程、原数据相同的 TBB、原数据独立的 TBB、原数据相同的 OPENMP 和原数据独立的 OPENMP 等不同处理方式,对 960*600 的图像进行大尺寸滤波操作。实验结果显示,OPENMP 和 TBB 的优势在于代码编写相对简单,也不用考虑线程数的设置。同时,OPENMP 和 TBB 的基础数据独立与否,对测试速度基本不影响,但为了避免处理结果错误,应尽量保证数据独立性。
在针对 RV1106 平台的交叉编译环境中,虽然原生的交叉编译工具链不支持 OpenMP 功能,但通过从源码编译 openmp 并将编译好的库放入工具链,成功实现了对该交叉编译器 OpenMP 支持的集成。实验发现,随着 OpenMP 线程数从 2 增至 10,加速效果逐步提升;但超过 10 个线程后,加速收益不再明显增加,表明存在一个最优线程数阈值。
此外,NEON + OpenMP 的组合方式在嵌入式开发中也表现出了较好的加速效果。在并行计算量比较小的时候,可以优先使用 NEON 加速。
综上所述,通过利用嵌入式开发工具以及对比不同的加速技术,可以有效地提高 OpenCV 在嵌入式平台上的性能。
四、嵌入式 OpenCV 的应用案例
1. 在树莓派上实现从零开始的嵌入式图像图像处理,包括打开摄像头、编写程序获取并显示实时视频等。
树莓派凭借高度定制化和可玩性,深受科技宅青睐。树莓派能够用来进行多种工作,基于 Linux 的高度开源特性,通过程序员和工程师们的奇思妙想,能够自由组装成多种有趣的项目。
在树莓派上进行图像图像处理具有一定优势。以图像增强类算法为例,树莓派一直是寻找嵌入式平台的不错选择。在树莓派 3 问世之前,存在性能、移植和调试等问题。但树莓派 3 搭载 64 位 A53 处理器后,实时的 640*480 的视频在加上图像处理已经不成问题。
树莓派的安装配置也相对简单。购买时商家会提供很多有用资料,安装过程包括烧录到 SD 卡中、上电开机配置网络、运行特定命令以防止内核被改、执行更新和升级命令、安装中文字体、调整国家和时区等步骤。安装完成后,就可以转入图像处理平台的构建。
对于在树莓派上实现图像图像处理,首先可以安装 Qt 和 OpenCV 的基础库。安装 Qt 可以通过指令sudo apt-get install qt5-default和sudo apt-get install qtcreator。安装 OpenCV 的基础库可以使用sudo apt-get install libopencv-dev,安装后要找到文件路径。在安装过程中可能会遇到一些问题,如 Qt 安装出错和运行错误,可以通过更改编译器等方法解决。安装完成后,将 OpenCV 实际路径添加入 Qt 工程中。
接着,可以进行测试。使用指令raspistill可以获取静态图像,raspivid可以获取动态图像。在 Qt 中,可以通过代码实现开启摄像头和获取显示图像的内容。在测试过程中,可能会遇到 opencv 调用摄像头失败的问题,可以通过查看摄像头所有参数指令ls /dev/video*和v4l2-ctl --info -d /dev/video0 --list-formats-ext查找问题。如果出现权限问题,可以通过chmod修改摄像头的权限来解决。
2. 在 Ubuntu 系统下通过 OpenCV 实现点阵汉字的字模读取与显示。
在 Ubuntu 系统下,通过 OpenCV 实现点阵汉字的字模读取与显示,需要先了解汉字点阵的原理。汉字点阵原理包括汉字编码、点阵字库结构和汉字点阵获取。
汉字编码分为区位码和机内码。区位码是将所有的国标汉字及符号分配在一个 94 行、94 列的方阵中,用区号和位号组合表示一个汉字或符号。机内码是在计算机中表示一个汉字的编码,为了避免与基本 ASCII 码混淆,需要进行一些处理。
点阵字库结构根据字节所表示点的不同分为横向矩阵和纵向矩阵,常用的点阵矩阵有 1212、1414、16*16 三种字库。对于不同的字库,存储方式可能会有所不同,需要注意处理方式。
汉字点阵获取可以通过区位码或机内码来计算。利用区位码获取汉字点阵的计算公式为:点阵起始位置 = ((区码 - 1)*94 + (位码 – 1)) * 汉字点阵字节数。利用机内码获取汉字点阵需要先根据机内码计算出区位码,再使用区位码获取点阵位置。
在实验过程中,首先要明确实验题目,即学习理解汉字的机内码、区位码编码规则和字形数据存储格式,在 Ubuntu 下用 C/C++(或 python) 调用 OpenCV 库编程显示一张图片,并打开一个名为 "logo.txt" 的文本文件,按照名字和学号去读取汉字 24*24 点阵字形字库中对应字符的字形数据,将名字和学号叠加显示在此图片右下位置。
然后创建项目文件夹,将项目需要的文件等放在该文件夹下。创建.cpp 文件,编写代码。代码中需要包含 OpenCV 的头文件,并定义一些函数来绘制汉字和 ASCII 字符。在主函数中,调用put_text_to_image函数,传入图片的路径和文本文件的路径,实现将文本中的名字和学号叠加显示在图片上。
最后进行编译和运行,查看结果。如果一切正常,就可以在图片上看到叠加显示的名字和学号。
五、嵌入式 OpenCV 的优势
- 跨平台性,可在不同系统平台上使用。
OpenCV 具有很强的跨平台性,无论是在传统的桌面操作系统如 Windows、Linux、Mac OS,还是在移动操作系统 Android 和 iOS 上都能良好运行。在嵌入式领域,也能在多种不同的嵌入式系统平台上发挥作用,为开发者提供了极大的便利,使得开发的应用可以在不同的硬件环境下轻松部署。
- 丰富的编程语言接口。
OpenCV 不仅以 C++ 语言编写,还提供了丰富的编程语言接口,包括 Python、Java、MATLAB 等。这使得不同背景的开发者都能轻松上手使用 OpenCV 进行开发。例如,对于熟悉 Python 的开发者来说,可以利用 OpenCV 的 Python 接口快速实现图像处理和计算机视觉任务。
- 活跃的开发团队和不断更新的算法库。
OpenCV 拥有活跃的开发团队,自 2000 年公开第一个预览版本以来,目前已更新至 OpenCV4.5.3。不断更新的算法库确保了 OpenCV 始终能跟上计算机视觉领域的最新发展趋势。开发者可以享受到最新的算法和功能,提高开发效率和应用性能。
- 与其他软件工具的互补性,如与 OpenVX 的关系。
OpenVX 实现了跨平台加速处理,在嵌入式和实时性系统中具有很大的优势。OpenVX 和 OpenCV 并不冲突,它们可以说是互补的。OpenVX 就像一个骨架,包含一些头文件声明了很多宏、枚举、变量类型、函数等等。其目的是方便不同的硬件平台实现相同的接口,实现了计算机视觉处理中性能和能耗方面的优化,特别是在嵌入式和实时应用案例中起到重要作用。在某些场合,配合 OpenCV 的强大功能可以实现更好的效果。