【ZYNQ】基于ZYNQ 7020的OPENCV源码交叉编译

目录

安装准备

检查编译器

安装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与后两者是兼容的,但softfphard两种模式互不兼容)
soft : 不用fpu进行浮点计算,即使有fpu浮点运算单元也不用,而是使用软件模式。
softfp : armel架构(对应的编译器为gcc-arm-linux-gnueabi)采用的默认值,用fpu计算,但是传参数用普通寄存器传,这样中断的时候,只需要保存普通寄存器,中断负荷小,但是参数需要转换成浮点的再计算。
hard : armhf架构(对应的编译器gcc-arm-linux-gnueabihf)采用的默认值,用fpu计算,传参数也用fpu中的浮点寄存器传,省去了转换, 性能最好,但是中断负荷高。

使用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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/767536.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

线性表的合并之求解一般集合的并集问题(单链表)

目录 1问题描述&#xff1a; 2问题分析&#xff1a; 3代码如下&#xff1a; 4运行结果&#xff1a; 1问题描述&#xff1a; 已知两个集合A和B&#xff0c;现要求一个新的集合AAuB。例如&#xff0c;设 A&#xff08;7&#xff0c;5&#xff0c;3&#xff0c;11&#xff09;…

go 基础中的一些坑(2)

类型转换 在 go 语言中&#xff0c;类型转换是显式的&#xff0c;不会自动转换 go 复制代码 func main(){ i : 100 var f float64 f float64(i) } string 转换成 int 需要借助 strconv 包 使用 strconv.Atoi 函数将 string 转换成 int&#xff0c;转换后它会输出两个值&…

基于Matlab的血管图像增强算法,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

设计数据库之外部模式:数据库的应用

Chapter5&#xff1a;设计数据库之外部模式&#xff1a;数据库的应用 笔记来源&#xff1a;《漫画数据库》—科学出版社 设计数据库的步骤&#xff1a; 概念模式 概念模式(conceptual schema)是指将现实世界模型化的阶段进而&#xff0c;是确定数据库理论结构的阶段。 概念模…

大模型日报2024-03-23

微软生成式AI入门课程 摘要: 微软推出18堂生成式AI基础课程&#xff0c;适合初学者。课程内容丰富&#xff0c;涵盖理论与实操&#xff0c;使用Jupyter Notebook编写&#xff0c;详见官方教程链接。 DarkGPT&#xff1a;基于GPT-4的OSINT助手 摘要: DarkGPT是一个基于GPT-4-200…

k8s笔记27--快速了解 k8s pod和cgroup的关系

k8s笔记27--快速了解 k8s pod和 cgroup 的关系 介绍pod & cgroup注意事项说明 介绍 随着云计算、云原生技术的成熟和广泛应用&#xff0c;K8S已经成为容器编排的事实标准&#xff0c;学习了解容器、K8S技术对于新时代的IT从业者显得极其重要了。 之前在文章 docker笔记13–…

node.js中常用的命令及示例

node.js中常用的命令及示例&#xff1a; 启动Node.js REPL&#xff08;Read-Eval-Print Loop&#xff09;nodec此命令将启动Node.js的交互式命令行环境&#xff0c;允许你编写并立即执行JavaScript代码。 运行JavaScript文件 node script.js运行名为script.js的JavaScript文件…

【Web APIs】事件高级

目录 1.事件对象 1.1获取事件对象 1.2事件对象常用属性 2.事件流 1.1事件流的两个阶段&#xff1a;冒泡和捕获 1.2阻止事件流动 1.3阻止默认行为 1.4两种注册事件的区别 3.事件委托 1.事件对象 1.1获取事件对象 事件对象&#xff1a;也是一个对象&#xff0c;这个对象里…

apache2.4设置完一个VirtualHost后,所有的域名和IP地址都变成访问这个VirtualHost的解决办法

apache2.4设置完一个VirtualHost&#xff08;如www.example.com&#xff09;后&#xff0c;所有的域名&#xff08;如localhost&#xff09;和IP地址都变成访问这个VirtualHost。 默认的DocumentRoot /var/www/html无效了。 解决办法&#xff1a;在/etc/httpd/conf.d/&#xf…

电子电器架构 —— 诊断数据DTC具体故障篇

电子电器架构 —— 诊断数据DTC起始篇 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师 (Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶,喝完再挣扎…

算法---前缀和练习-2(和为k的子数组)

和为k的子数组 1. 题目解析2. 讲解算法原理3. 编写代码 1. 题目解析 题目地址&#xff1a;点这里 2. 讲解算法原理 创建一个无序映射&#xff08;哈希表&#xff09; hash&#xff0c;用于统计前缀和的出现次数。初始时&#xff0c;将前缀和为 0 的次数设为 1&#xff0c;表示…

Spark重温笔记(三):Spark在企业中为什么能这么强?——持久化、Checkpoint机制、共享变量与内核调度原理全攻略“

Spark学习笔记 前言&#xff1a;今天是温习 Spark 的第 3 天啦&#xff01;主要梳理了 Spark 核心数据结构&#xff1a;RDD(弹性分布式数据集)&#xff0c;包括RDD持久化&#xff0c;checkpoint机制&#xff0c;spark两种共享变量以及spark内核调度原理&#xff0c;希望对大家有…

牛客题霸-SQL篇(刷题记录二)

本文基于前段时间学习总结的 MySQL 相关的查询语法&#xff0c;在牛客网找了相应的 MySQL 题目进行练习&#xff0c;以便加强对于 MySQL 查询语法的理解和应用。 由于涉及到的数据库表较多&#xff0c;因此本文不再展示&#xff0c;只提供 MySQL 代码与示例输出。 以下内容是…

HarmonyOS应用开发实战 - Api9 拍照、拍视频、选择图片、选择视频、选择文件工具类

鸿蒙开发过程中&#xff0c;经常会进行系统调用&#xff0c;拍照、拍视频、选择图库图片、选择图库视频、选择文件。今天就给大家分享一个工具类。 1.话不多说&#xff0c;先展示样式 2.设计思路 根据官方提供的指南开发工具类&#xff0c;基础的拍照、拍视频、图库选照片、选…

使用Python进行自动化测试Selenium与PyTest的结合【第150篇—自动化测试】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 使用Python进行自动化测试&#xff1a;Selenium与PyTest的结合 在软件开发中&#xff0c;自…

线程与进程的爱恨情仇???

线程与进程的爱恨情仇&#xff1f;&#xff1f;&#xff1f; 一&#xff1a;有了进程&#xff0c;为什么还需要线程&#xff1f;&#xff1f;&#xff1f;二:线程三:线程和进程的区别与联系四:创建线程or创建进程 一&#xff1a;有了进程&#xff0c;为什么还需要线程&#xff…

css盒子模型及浮动

内容(content)、内边距(padding)、边框(border)、外边距(margin) oder:1px solid red; 边框的粗细 边框的样式&#xff08;虚线还是实线&#xff09; 边框的颜色 border中也有一些属性可以直接调某一个方向上的边框的粗细&#xff0c;样式&#xff0c;颜色 border-left\bord…

2024/3/24 LED点阵屏

显示原理&#xff1a; 类似矩阵键盘&#xff0c;逐行or逐列扫描 74HC595是串行 寄存器 感觉就是三转八寄存器 并行&#xff1a;同时输出&#xff1b;串行&#xff1a;一位一位输出 先配置74HC595&#xff0c;重新进行位声明 sbit RCKP3^5; //RCLK sbit SCKP3^6; …

芒果YOLOv8改进116:即插即用:集中特征金字塔Centralized Feature Pyramid 高效涨点改进

💡🚀🚀🚀本博客 改进源代码改进 适用于 YOLOv8 按步骤操作运行改进后的代码即可 该专栏完整目录链接: 芒果YOLOv8深度改进教程 🚀🚀🚀 文章目录 一、Centralized Feature Pyramid论文理论部分 + YOLOv8代码改进论文创新论文贡献论文网络部分实验对比2. YOLOv8 …

淘宝|天猫|京东|1688主流电商平台的实时数据返回接口|附Python实例

导读&#xff1a;随着淘宝/天猫直通车功能升级&#xff0c;很多功能越来越白盒化&#xff0c;越来越简化&#xff0c;更方便用户的操作&#xff0c;只需一键即可看出淘宝/天猫直通车存在的问题。淘宝/天猫直通车千人千面后有了实时数据工具&#xff0c;下面通过一个案例告诉大家…