目录
安装准备
检查编译器
安装OpenCV编译的依赖项
下载OpenCV源码
下载CMake
编译配置
编译器说明
参考链接
安装准备
使用的各个程序的版本内容如下:
类别 | 软件名称 | 软件版本 |
虚拟机 | VMware | VMware-workstation-full-15.5.0-14665864 |
操作系统 | Ubuntu | 16.04.6 LTS |
编译器 | arm-linux-gnueabihf-gcc | / |
CMAKE | Cmake | 3.18.0-Linux-x86_64 |
源码 | OpenCV源码 | opencv-3.4.10 |
检查编译器
在Ubuntu的命令行中执行以下命令,检查交叉编译器的版本:
arm-linux-gnueabihf-gcc -v arm-linux-gnueabihf-g++ -v |
如果输出显示有error,说明还没有安装交叉编译器。
输入以下指令进行安装,注意编译器以hf结尾,不要与其他编译器件混淆:
sudo apt-get install gcc-arm-linux-gnueabihf sudo apt-get install g++-arm-linux-gnueabihf |
安装完成后,再次检查交叉编译器的版本,如果有下图的输出,则代表安装完成:
编译器arm-linux-gnueabihf-gcc容易与arm-linux-gnueabi-gcc相混肴(后者缺少hf),两者的区别在于适用的架构不同,arm-linux-gnueabihf-gcc适用于armhf架构,arm-linux-gnueabi-gcc适用于armel架构, armel和armhf这两种架构的区别在对待浮点运算采取了不同的策略(zynq 7000是armhf架构):
gcc的选项-mfloat-abi有三种值soft,softfp,hard(其中后两者都要求arm里有fpu浮点运算单元,soft与后两者是兼容的,但softfp和hard两种模式互不兼容): |
使用arm-linux-gnueabi编译OpenCV动态库,开发板端程序运行时加载OpenCV动态库会出现internal error问题。选错编译器的问题在后期才出现错误提示,因此最好在OpenCV源码的编译阶段就确定编译器选择正确。
安装OpenCV编译的依赖项
执行以下命令,安装OpenCV编译的依赖项
sudo apt-get install build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev |
以下是编译OpenCV非必须的项目,在编译界面增加选项后才可能会提示缺少,根据需要进行安装:
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev |
下载OpenCV源码
OpenCV源码的下载位置可以在OpenCV的官网找到,本文下载的版本为3.4.10:
https://opencv.org/releases/ |
官网打不开的话尝试从github下载:
https://github.com/opencv/opencv/releases/tag/3.4.10 |
下载Source code,下载完成后解压,本文解压至/home/<用户名>/Downloads/opencv/opencv-3.4.10文件夹:
下载CMake
通过以下网址下载Cmake,gui版本操作会更方便一些,本文下载的版本是cmake-3.18.0-Linux-x86_64.tar.gz:
https://cmake.org/download/#previous |
下载完成后解压,本文解压位置在/home/<用户名>/Downloads/opencv/cmake-3.18.0-Linux-x86_64/:
-
编译配置
(1)双击执行/home/<用户名>/Downloads/opencv/cmake-3.18.0-Linux-x86_64/bin目录下的cmake-gui文件,打开cmake图形化编译界面:
在cmake-gui窗口上方“Where is source code”栏中填入opencv源码文件夹,在“Where to build the binaries”栏中填入你期望的存放opencv源码编译文件的build文件夹,本文选择的文件夹为:
源码文件夹:/home/<用户名>/Downloads/opencv/opencv-3.4.10 build文件夹:/home/<用户名>/Downloads/opencv/hf_opencv_build |
(2)点击Cmake窗口左侧的Configure按钮,出现新窗口CMakeSetup:
如果没有出现新窗口,是因为上次编译的缓存还在,点击Cmake窗口左上角File,执行Delete Cache,缓存清楚完成后再次点击Configure按钮即可:
CMakeSetup窗口中修改为第4项Specify options for cross-compiling,点击Next:
(3)参考表格进行填写:
选项 | 填写内容 |
Operating System | Linux |
Processor | arm |
Compilers | C: /usr/bin/arm-linux-gnueabihf-gcc C++: /usr/bin/arm-linux-gnueabihf-g++ |
Target Root | 无强制要求 |
有部分博客的Operating System填写的是arm-linux,经过实践,Cmake无法识别,必须填写Linux。
Target Root在网上并没有统一说法,有填写第三方库的,有填写Compilers的上一级目录的,本文填写的是/usr/bin文件夹。
之后点击Finish即可。
(4)之后会出现OpenCV的配置项:
本文在Search栏中搜索install,修改CMAKE_INSTALL_PREFIX配置项。CMAKE_INSTALL_PREFIX配置项决定了OpenCV库的安装位置,选择自己期望的位置即可。本文选择/home/<用户名>/Downloads/opencv/hf_opencv_install:
继续搜素png。有部分教程要求去掉配置项中PNG相关的选项,否则OpenCV会发生错误,本文没有试验,直接去除了WITH_PNG选项。
继续搜素world。选择该选项会将OpenCV动态库整合,CMAKE_INSTALL_PREFIX目录下的lib文件夹下会生成单独的libopencv_world动态库,而不是一系列分立的OpenCV功能库,由于产品不需要全部的OpenCV功能,后续需要去除部分OpenCV功能库,因此该选项不勾选:
选项配置完成后,点击Generate,等待生成完成。
(5)
生成完成后,打开“Where to build the binaries”文件夹,本文的文件夹为/home/<用户名>/Downloads/opencv/hf_opencv_build。
在文件上右键使用gedit方式打开文件夹下的CMakeCache.txt文件,大约326行找到
CMAKE_EXE_LINKER_FLAGS:STRING= |
将其修改为如下并保存文件:
CMAKE_EXE_LINKER_FLAGS:STRING=-pthread -lrt -ldl |
在/home/<用户名>/Downloads/opencv/hf_opencv_build文件夹中右键打开命令行,执行make指令:
make -j12 //12表示线程数量,CPU性能较差的电脑12可换为更小的数字或不加-j12 |
make没有错误的话,继续执行make install指令:
make install |
make install完成后,可以在CMAKE_INSTALL_PREFIX配置项设定的文件夹下找到编译完成的OpenCV库:
lib/下就是各个.so动态库文件:
-
编译器说明
关于编译配置章节第(3)步中的C/C++编译器,本文在开发时,设想了3种选择,其中前2种可行。
第一种就是本文选择的arm-linux-gnueabihf-gcc,来源是Ubuntu安装的apt-get install 。
第二种是,在Ubuntu系统下安装Vitis 2020.1,安装完成后在下列目录中可以查找到Xilinx Vitis提供的编译器:
/Xilinx/Vitis/2020.1/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-gcc /Xilinx/Vitis/2020.1/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-g++ |
经过验证,使用该编译器也可以成功编译OpenCV。本文没有选择Xilinx Vitis提供的编译器的原因在于,虚拟机空间不足以安装Vitis,因此尝试编译Qt源码时选择的是第一种,之后为了避免潜在的冲突错误,编译OpenCV时同样选择了第一种。有兴趣的读者可以尝试使用Xilinx Vitis提供的编译器来编译Qt源码。
第三种选择是使用petalinux提供的编译器,可惜的是此步骤并未走通。产品使用的image.ub由petalinux提供的编译器编译,而程序和OpenCV动态库由arm-linux-gnueabihf-gcc编译,两者编译器的来源不同,因此是存在不能兼容的可能性的。
按照常规想法,image.ub中的官方库是由petalinux编译而成,如果程序和动态库也使用该编译器,那么可以肯定动态库和Linux系统之间出现冲突的可能性是最低的。
本文使用的petalinux的编译器在sdk.sh的安装位置:
/opt/petalinux/2020.1/sysroots/x86_64-petalinux-linux/usr/bin/arm-xilinx-linux-gnueabi/arm-xilinx-linux-gnueabi-gcc /opt/petalinux/2020.1/sysroots/x86_64-petalinux-linux/usr/bin/arm-xilinx-linux-gnueabi/arm-xilinx-linux-gnueabi-g++ |
根据链接Install Xilinx Tools - Xilinx Wiki - Confluence (atlassian.net):
petalinux编译器arm-xilinx-linux-gnueabi-gcc使用的是软浮点数,同样可用于zynq 7000架构。
之后,petalinux编译器在编译OpenCV时出现了错误,经过了一些尝试后,由于时间关系没有解决这个问题:
本文在项目后期进行回顾时,猜测错误的原因是是petalinux生成sdk.sh时rootfs中未选择ldd选项,有兴趣的读者可以重新生成sdk.sh并尝试能否正确编译OpenCV源码:
如果这petalinux编译器这条线能够走通,好处是显而易见的。
系统镜像、动态库、程序都可以使用petalinux编译的这一套编译工具,不存在冲突问题。
同时,在编译配置章节中,Target Root就可以选择sdk.sh安装目录下的usr/lib/文件夹。假设编译OpenCV时需要第三方库,比如tiff、x264等,只需要在petalinux的rootfs中选择并生成sdk.sh,然后Target Root选择sdk.sh安装目录,编译器选择petalinux编译器即可。如果使用Ubuntu提供的arm-linux-gnueabihf-gcc编译器,那么需要下载第三方库的源码,再手动进行编译,可能需要解决潜在的冲突问题,第三方库较多时,也比较繁琐。
-
参考链接
【1】https://blog.csdn.net/KayChanGEEK/article/details/78552418
【2】
https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842547/Install+Xilinx+Tools?responseToken=05cf01333fed60ac4bb10b91964f07d9b
【3】https://blog.csdn.net/qq_38880380/article/details/80987661