文章目录
前言
实验室所用的Firefly AIO-3399Pro C开发板需要用到OpenCV和FFmpeg来实现视频播放,而OpenCV源码默认编译时,有些选项默认未打开,导致OpenCV无法配合FFmpeg正常使用,故在PC端的Ubuntu系统中交叉编译OpenCV 3.4.10版本和各个软件依赖库,配合Qt在PC端交叉编译,并移植到开发板上实现视频播放等功能。
提示:以下是本篇文章正文内容,因开发环境和文件路径的不同,下面案例仅供参考,需要按照自己的实际情况进行修改方可交叉编译成功。
一、开发部署环境
开发环境 | 软件版本 |
---|---|
PC系统版本 | Ubuntu 18.04LTS |
开发板型号 | Firefly AIO-3399 ProC开发板 (3+16GB) |
开发板操作系统 | Ubuntu 18.04LTS |
开发板固件版本 | AIO-RK3399PROC-UBUNTU18.04-GPT-20200525-1016.img |
交叉编译工具链 | gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu |
OpenCV版本 | 3.4.10 |
Python版本 | Python 3.7.10 |
Qt版本 | 5.12.2 |
Qt Creator版本 | 4.8.2 |
电脑远程软件 | Xshell 6&Xftpd 6 |
依赖库软件 | 软件版本 |
---|---|
nasm | 2.14.02 |
zlib | 1.12.11 |
x264 | 20191217-2245-stable |
libjpeg | jpegsrc.v9d |
libpng | 1.6.34 |
libtiff | 4.0.9 |
ffmpeg | 4.2.4 |
libxvidcore | 1.3.7 |
二、安装前的相关包下载及环境准备
1. Qt交叉编译环境搭建
参考《Firefly AIO-3399ProC开发板与PC端部署Qt5.12.2交叉编译环境》
文章部署Qt交叉编译环境。并部署好gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu交叉编译工具链。
2.安装环境所需依赖包
- 安装编译所需依赖包
user@admin-machine:~$ sudo apt-get update
user@admin-machine:~$ sudo apt-get install build-essential
user@admin-machine:~$ sudo apt install software-properties-common
user@admin-machine:~$ sudo apt-get install cmake git pkg-config
- 安装Python3.7
user@admin-machine:~$ sudo apt update #检查可更新文件
user@admin-machine:~$ sudo apt install software-properties-common #安装可添加源的工具
user@admin-machine:~$ sudo add-apt-repository ppa:deadsnakes/ppa #添加源,否则会无法找到python3.7-dev软件包
user@admin-machine:~$ sudo apt install python3.7-dev -y #安装python3.7
- 配置Python3.7环境
#查看路径python,python3.7路径
user@admin-machine:~$ which python python3.7
/usr/bin/python
/usr/bin/python3.7
user@admin-machine:~$ sudo rm /usr/bin/python
user@admin-machine:~$ sudo rm /usr/bin/python3
#创建python3.7软连接到python&Python3
user@admin-machine:~$ sudo ln -s /usr/bin/python3.7 /usr/bin/python
user@admin-machine:~$ sudo ln -s /usr/bin/python3.7 /usr/bin/python3
#测试Python版本
user@admin-machine:~$ python
Python 3.7.10 (default, Feb 20 2021, 21:17:23)
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
user@admin-machine:~$ python3
Python 3.7.10 (default, Feb 20 2021, 21:17:23)
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
3. 交叉编译OpenCV所需x264、FFmpeg等依赖库
OpenCV的依赖库关系如下图所示:
必须交叉编译的依赖库有zlib、libjpeg、libpng等否则源码编译OpenCV时,会报缺少依赖库的错误,导致编译中断。
以下编译均在PC端的Ubuntu 18.04 LTS系统中编译,所用的交叉编译工具链为gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu
3.1 nasm编译
Netwide Assembler (简称 NASM)是一款基于x86架构的汇编与反汇编软件。它可以用来编写16位(8086、80286等)、32位(IA-32)和64位(x86_64)的程序。 NASM被认为是Linux平台上最受欢迎的汇编工具之一。
- 解压nasm-2.14.02.tar.bz2,打开终端后进入文件夹中,执行:
user@admin-machine:~/compile/nasm-2.14.02$ ./configure --host=arm-linux --prefix=/home/user/compile/nasm-2.14.02/_libs --enable-shared CC=aarch64-linux-gnu-gcc --disable-asm
- 若无报错,编辑文件夹下的Makefile文件,将CC、AR、RANLIB、STRIP改为交叉编译工具的命令后保存。
user@admin-machine:~/compile/nasm-2.14.02$ sudo vim Makefile
#
# Auto-configuring Makefile for the Netwide Assembler.
#
# The Netwide Assembler is copyright (C) 1996 Simon Tatham and
# Julian Hall. All rights reserved. The software is
# redistributable under the license given in the file "LICENSE"
# distributed in the NASM archive.
top_srcdir = .
srcdir = .
objdir = .
prefix = /home/user/complier/opencv_lib
exec_prefix = ${prefix}
bindir = ${exec_prefix}/bin
mandir = ${datarootdir}/man
datarootdir = ${prefix}/share
CC = aarch64-linux-gnu-gcc
CFLAGS = -g -O3 -fwrapv -U__STRICT_ANSI__ -fno-common -Werror=attributes -fvisibility=hidden -W -Wall -pedantic -Wc90-c99-compat -Wno-long-long -Wno-shift-negative-value -Werror=implicit -Werror=missing-braces -Werror=return-type -Werror=trigraphs -Werror=pointer-arith -Werror=missing-prototypes -Werror=missing-declarations -Werror=comment -Werror=vla
CPPFLAGS =
BUILD_CFLAGS = $(CPPFLAGS) $(CFLAGS) -DHAVE_CONFIG_H
INTERNAL_CFLAGS = -I$(srcdir) -I$(objdir) \
-I$(srcdir)/include -I$(objdir)/include \
-I$(srcdir)/x86 -I$(objdir)/x86 \
-I$(srcdir)/asm -I$(objdir)/asm \
-I$(srcdir)/disasm -I$(objdir)/disasm \
-I$(srcdir)/output -I$(objdir)/output
ALL_CFLAGS = $(BUILD_CFLAGS) $(INTERNAL_CFLAGS)
LDFLAGS = -fvisibility=hidden
LIBS =
AR = aarch64-linux-gnu-ar
RANLIB = aarch64-linux-gnu-gcc-ranlib
STRIP = aarch64-linux-gnu-strip
PERL = perl
PERLFLAGS = -I$(srcdir)/perllib -I$(srcdir)
RUNPERL = $(PERL) $(PERLFLAGS)
INSTALL = /usr/bin/install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
NROFF = nroff
ASCIIDOC = false
XMLTO = false
MAKENSIS = makensis
MKDIR = mkdir -p
RM_F = rm -f
RM_RF = rm -rf
LN_S = ln -s
FIND = find
ESC 后输入:wq后保存并退出,执行make和make install即可。
user@admin-machine:~/compile/nasm-2.14.02$ make
user@admin-machine:~/compile/nasm-2.14.02$ make install
- 安装完成后文件夹下的_libs中生成的文件结构如下:
user@admin-machine:~/compile/nasm-2.14.02/_libs$ tree
.
├── bin
│ ├── nasm
│ └── ndisasm
└── share
└── man
└── man1
├── nasm.1
└── ndisasm.1
4 directories, 4 files
3.2 x264编译
H.264是ITU(International Telecommunication Union,国际通信联盟)和MPEG(Motion Picture Experts Group,运动图像专家组)联合制定的视频编码标准。而x264是一个开源的H.264/MPEG-4 AVC视频编码函数库,是最好的有损视频编码器之一。
- 解压x264-snapshot-20191217-2245-stable.tar.bz2,打开终端后进入文件夹中,执行:
#x264编译
user@admin-machine:~/compile/x264-20191217$ ./configure --enable-shared --enable-static --disable-asm --prefix=$PWD/_libs --host=arm-linux --cross-prefix=aarch64-linux-gnu-
- 若无报错,make & make install即可。
user@admin-machine:~/compile/x264-20191217$ make
user@admin-machine:~/compile/x264-20191217$ make install
- 安装完成后文件夹下的_libs中生成的文件结构如下:
user@admin-machine:~/compile/x264-20191217/_libs$ tree
.
├── bin
│ └── x264
├── include
│ ├── x264_config.h
│ └── x264.h
└── lib
├── libx264.a
├── libx264.so -> libx264.so.157
├── libx264.so.157
└── pkgconfig
└── x264.pc
3.3 ZLIB编译
zlib是提供数据压缩用的函式库,由Jean-loup Gailly与Mark Adler所开发。
- 解压zlib-1.2.11.tar.gz,打开终端后进入文件夹中,执行:
#zlib compile
user@admin-machine:~/compile/zlib-1.2.11$ ./configure --prefix=./lib --enable-shared
- 若无报错,编辑文件夹下的Makefile文件,将CC、AR、RANLIB改为交叉编译工具的命令后保存。
user@admin-machine:~/compile/zlib-1.2.11$ sudo vim Makefile
CC=aarch64-linux-gnu-gcc
CFLAGS=-O3 -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN
#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
#CFLAGS=-g -DZLIB_DEBUG
#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
# -Wstrict-prototypes -Wmissing-prototypes
SFLAGS=-O3 -fPIC -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN
LDFLAGS=
TEST_LDFLAGS=-L. libz.a
LDSHARED=aarch64-linux-gnu-gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map
CPP=aarch64-linux-gnu-gcc -E
STATICLIB=libz.a
SHAREDLIB=libz.so
SHAREDLIBV=libz.so.1.2.11
SHAREDLIBM=libz.so.1
LIBS=$(STATICLIB) $(SHAREDLIBV)
AR=aarch64-linux-gnu-gcc-ar
ARFLAGS=rc
RANLIB=aarch64-linux-gnu-gcc-ranlib
LDCONFIG=ldconfig
LDSHAREDLIBC=-lc
TAR=tar
SHELL=/bin/sh
EXE=
ESC 后输入:wq后保存并退出。
- make & make install
user@admin-machine:~/compile/zlib-1.2.11$ make
user@admin-machine:~/compile/zlib-1.2.11$ make install
- 安装完成后文件夹下的_libs中生成的文件结构如下:
user@admin-machine:~/compile/zlib-1.2.11/_lib$ tree
.
├── include
│ ├── zconf.h
│ └── zlib.h
├── lib
│ ├── libz.a
│ ├── libz.so -> libz.so.1.2.11
│ ├── libz.so.1 -> libz.so.1.2.11
│ ├── libz.so.1.2.11
│ └── pkgconfig
│ └── zlib.pc
└── share
└── man
└── man3
└── zlib.3
6 directories, 8 files
3.4 libjpeg 编译
LibJPEG 是一个广泛使用的 JPEG 图像压缩库,用于读取和写入 JPEG图像文件,采用 C 语言开发。
- 解压jpegsrc.v9d.tar.gz,打开终端后进入文件夹中,执行:
user@admin-machine:~/compile/libjpeg$ CC=aarch64-linux-gnu-gcc ./configure --host=arm-linux --prefix=$PWD/_libs --enable-shared --enable-static
- 若无报错,make & make install即可。
user@admin-machine:~/compile/libjpeg$ make
user@admin-machine:~/compile/libjpeg$ make install
- 安装完成后文件夹下的_libs中生成的文件结构如下:
user@admin-machine:~/compile/libjpeg/_libs$ tree
.
├── bin
│ ├── cjpeg
│ ├── djpeg
│ ├── jpegtran
│ ├── rdjpgcom
│ └── wrjpgcom
├── include
│ ├── jconfig.h
│ ├── jerror.h
│ ├── jmorecfg.h
│ └── jpeglib.h
├── lib
│ ├── libjpeg.a
│ ├── libjpeg.la
│ ├── libjpeg.so -> libjpeg.so.9.4.0
│ ├── libjpeg.so.9 -> libjpeg.so.9.4.0
│ ├── libjpeg.so.9.4.0
│ └── pkgconfig
│ └── libjpeg.pc
└── share
└── man
└── man1
├── cjpeg.1
├── djpeg.1
├── jpegtran.1
├── rdjpgcom.1
└── wrjpgcom.1
7 directories, 20 files
3.5 libpng 编译
libpng是官方的PNG参考库。它支持几乎所有PNG功能。libpng可作为ANSIC(C89)源代码提供,并且依赖于zlib 1.0.4 或更高版本。
- 解压libpng-1.6.34.tar.gz,打开终端后进入文件夹中,执行:
user@admin-machine:~/compile/libpng-1.6.34$ cd ./scripts
user@admin-machine:~/compile/libpng-1.6.34/scripts$ sudo cp ./makefile.linux ../makefile
user@admin-machine:~/compile/libpng-1.6.34/scripts$ cd ..
user@admin-machine:~/compile/libpng-1.6.34$ sudo vim makefile
- 将makefile文件对应位置的gcc,ac ar ranlib修改为交叉编译工具链命令,并指定安装路径prefilx和ZIBLIC和ZIBLNC的文件路径。修改为如下内容:
# makefile for libpng.a and libpng16.so on Linux ELF with gcc
# Copyright (C) 1998, 1999, 2002, 2006, 2008, 2010-2014 Greg Roelofs and
# Glenn Randers-Pehrson
# Copyright (C) 1996, 1997 Andreas Dilger
#
# This code is released under the libpng license.
# For conditions of distribution and use, see the disclaimer
# and license in png.h
# Library name:
LIBNAME = libpng16
PNGMAJ = 16
RELEASE = 34
# Shared library names:
LIBSO=$(LIBNAME).so
LIBSOMAJ=$(LIBNAME).so.$(PNGMAJ)
LIBSOREL=$(LIBSOMAJ).$(RELEASE)
OLDSO=libpng.so
# Utilities:
AR_RC=aarch64-linux-gnu-gcc-ar rc
CC=aarch64-linux-gnu-gcc
MKDIR_P=mkdir -p
LN_SF=ln -sf
RANLIB=aarch64-linux-gnu-ranlib
CP=cp
RM_F=/bin/rm -f
# where "make install" puts libpng16.a, libpng16.so*,
# libpng16/png.h, libpng16/pngconf.h, and libpng16/pnglibconf.h
# Prefix must be a full pathname.
prefix=/home/user/compile/libpng-1.6.34/_libs
exec_prefix=$(prefix)
# Where the zlib library and include files are located.
#ZLIBLIB=/usr/local/lib
#ZLIBINC=/usr/local/include
ZLIBLIB=/home/user/compile/zlib-1.2.11/_libs/lib
ZLIBINC=/home/user/compile/zlib-1.2.11/_libs/include
ESC 后输入:wq后保存并退出。
- 修改pngpriv.h文件,将
if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \
注释掉,即改为:
/*# if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \*/
然后添加一行
# if defined(PNG_ARM_NEON) && (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \
后保存修改。若不修改,后续make会出现以下错误:
libpng.a(pngrutil.o):在函数‘png_read_filter_row’中:
pngrutil.c:(.text+0x951c):对‘png_init_filter_functions_neon’未定义的引用
collect2: 错误: ld 返回 1
makefile:133: recipe for target 'pngtest-static' failed
make: *** [pngtest-static] Error 1
make: *** 正在等待未完成的任务....
- make & make install
user@admin-machine:~/compile/libpng-1.6.34$ make -j4
user@admin-machine:~/compile/libpng-1.6.34$ make install
cp png.h pngconf.h pnglibconf.h /home/user/compile/libpng-1.6.34/lib/include/libpng16
chmod 644 /home/user/compile/libpng-1.6.34/_libs/include/libpng16/png.h /home/user/compile/libpng-1.6.34/_libs/include/libpng16/pngconf.h /home/user/compile/libpng-1.6.34/_libs/include/libpng16/pnglibconf.h
(cd /home/user/compile/libpng-1.6.34/_libs/include; ln -sf libpng16 libpng; ln -sf libpng16/* .)
cp libpng.a /home/user/compile/libpng-1.6.34/_libs/lib/libpng16.a
chmod 644 /home/user/compile/libpng-1.6.34/_libs/lib/libpng16.a
(cd /home/user/compile/libpng-1.6.34/_libs/lib; ln -sf libpng16.a libpng.a)
cp libpng16.so.16 /home/user/compile/libpng-1.6.34/_libs/lib/libpng16.so.16.34
chmod 755 /home/user/compile/libpng-1.6.34/_libs/lib/libpng16.so.16.34
(cd /home/user/compile/libpng-1.6.34/_libs/lib; \
ln -sf libpng16.so.16.34 libpng16.so; \
ln -sf libpng16.so libpng.so)
cp libpng.pc /home/user/compile/libpng-1.6.34/_libs/lib/pkgconfig/libpng16.pc
chmod 644 /home/user/compile/libpng-1.6.34/_libs/lib/pkgconfig/libpng16.pc
(cd /home/user/compile/libpng-1.6.34/_libs/lib/pkgconfig; ln -sf libpng16.pc libpng.pc)
cp libpng.3 /home/user/compile/libpng-1.6.34/_libs/man/man3
cp libpngpf.3 /home/user/compile/libpng-1.6.34/_libs/man/man3
cp png.5 /home/user/compile/libpng-1.6.34/_libs/man/man5
cp libpng-config /home/user/compile/libpng-1.6.34/_libs/bin/libpng16-config
chmod 755 /home/user/compile/libpng-1.6.34/_libs/bin/libpng16-config
(cd /home/user/compile/libpng-1.6.34/_libs/bin; ln -sf libpng16-config libpng-config)
- 安装完成后文件夹下的_libs中生成的文件结构如下:
user@admin-machine:~/compile/libpng-1.6.34/_libs$ tree
.
├── bin
│ ├── libpng16-config
│ └── libpng-config -> libpng16-config
├── include
│ ├── libpng -> libpng16
│ ├── libpng16
│ │ ├── pngconf.h
│ │ ├── png.h
│ │ └── pnglibconf.h
│ ├── pngconf.h -> libpng16/pngconf.h
│ ├── png.h -> libpng16/png.h
│ └── pnglibconf.h -> libpng16/pnglibconf.h
├── lib
│ ├── libpng16.a
│ ├── libpng16.so -> libpng16.so.16.34
│ ├── libpng16.so.16.34
│ ├── libpng.a -> libpng16.a
│ ├── libpng.so -> libpng16.so
│ └── pkgconfig
│ ├── libpng16.pc
│ └── libpng.pc -> libpng16.pc
└── man
├── man3
│ ├── libpng.3
│ └── libpngpf.3
└── man5
└── png.5
9 directories, 18 files
3.6 libtiff编译
该软件支持标签图像文件格式(TIFF),这是一种用于存储图像数据的广泛使用的格式。发行版中包括一个libtiff库,用于读写TIFF;一小部分工具集,用于在UNIX系统上进行TIFF映像的简单操作;以及库和工具上的文档。还包括由他人提供的一小部分与TIFF相关的UNIX软件。
- 解压tiff-4.0.9.tar.gz,打开终端后进入文件夹中,执行:
user@admin-machine:~/compile/tiff-4.0.9$ ./configure CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ --host=arm-linux --prefix=$PWD/_libs --enable-shared --enable-static
- 若无报错,make & make install即可。
user@admin-machine:~/compile/tiff-4.0.9$ make
user@admin-machine:~/compile/tiff-4.0.9$ make install
3.7 FFmpeg编译
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。
- 解压ffmpeg-4.2.4.tar.xz,打开终端后进入文件夹中,执行:
user@admin-machine:~/compile/ffmpeg-4.2.4$ ./configure --enable-shared --enable-static --prefix=$PWD/_libs --cross-prefix=aarch64-linux-gnu- --arch=arm64 --target-os=linux --enable-gpl --enable-ffmpeg --enable-libx264 --extra-cflags=-I/home/user/compile/x264-20191217/_libs/include --extra-ldflags=-L/home/user/compile/x264-20191217/_libs/lib
- 若无报错,make & make install即可。
user@admin-machine:~/compile/ffmpeg-4.2.4$ make
user@admin-machine:~/compile/ffmpeg-4.2.4$ make install
- 安装完成后文件夹下的_libs中生成的文件结构如下:
user@admin-machine:~/compile/ffmpeg-4.2.4/_libs$ tree
.
├── bin
│ ├── ffmpeg
│ └── ffprobe
├── include
│ ├── libavcodec
│ │ ├── ac3_parser.h
│ │ ├── adts_parser.h
│ │ ├── avcodec.h
│ │ ├── avdct.h
│ │ ├── avfft.h
│ │ ├── d3d11va.h
│ │ ├── dirac.h
│ │ ├── dv_profile.h
│ │ ├── dxva2.h
│ │ ├── jni.h
│ │ ├── mediacodec.h
│ │ ├── qsv.h
│ │ ├── vaapi.h
│ │ ├── vdpau.h
│ │ ├── version.h
│ │ ├── videotoolbox.h
│ │ ├── vorbis_parser.h
│ │ └── xvmc.h
│ ├── libavdevice
│ │ ├── avdevice.h
│ │ └── version.h
│ ├── libavfilter
│ │ ├── avfilter.h
│ │ ├── buffersink.h
│ │ ├── buffersrc.h
│ │ └── version.h
│ ├── libavformat
│ │ ├── avformat.h
│ │ ├── avio.h
│ │ └── version.h
│ ├── libavutil
│ │ ├── adler32.h
│ │ ├── aes_ctr.h
│ │ ├── aes.h
│ │ ├── attributes.h
│ │ ├── audio_fifo.h
│ │ ├── avassert.h
│ │ ├── avconfig.h
│ │ ├── avstring.h
│ │ ├── avutil.h
│ │ ├── base64.h
│ │ ├── blowfish.h
│ │ ├── bprint.h
│ │ ├── bswap.h
│ │ ├── buffer.h
│ │ ├── camellia.h
│ │ ├── cast5.h
│ │ ├── channel_layout.h
│ │ ├── common.h
│ │ ├── cpu.h
│ │ ├── crc.h
│ │ ├── des.h
│ │ ├── dict.h
│ │ ├── display.h
│ │ ├── downmix_info.h
│ │ ├── encryption_info.h
│ │ ├── error.h
│ │ ├── eval.h
│ │ ├── ffversion.h
│ │ ├── fifo.h
│ │ ├── file.h
│ │ ├── frame.h
│ │ ├── hash.h
│ │ ├── hdr_dynamic_metadata.h
│ │ ├── hmac.h
│ │ ├── hwcontext_cuda.h
│ │ ├── hwcontext_d3d11va.h
│ │ ├── hwcontext_drm.h
│ │ ├── hwcontext_dxva2.h
│ │ ├── hwcontext.h
│ │ ├── hwcontext_mediacodec.h
│ │ ├── hwcontext_qsv.h
│ │ ├── hwcontext_vaapi.h
│ │ ├── hwcontext_vdpau.h
│ │ ├── hwcontext_videotoolbox.h
│ │ ├── imgutils.h
│ │ ├── intfloat.h
│ │ ├── intreadwrite.h
│ │ ├── lfg.h
│ │ ├── log.h
│ │ ├── lzo.h
│ │ ├── macros.h
│ │ ├── mastering_display_metadata.h
│ │ ├── mathematics.h
│ │ ├── md5.h
│ │ ├── mem.h
│ │ ├── motion_vector.h
│ │ ├── murmur3.h
│ │ ├── opt.h
│ │ ├── parseutils.h
│ │ ├── pixdesc.h
│ │ ├── pixelutils.h
│ │ ├── pixfmt.h
│ │ ├── random_seed.h
│ │ ├── rational.h
│ │ ├── rc4.h
│ │ ├── replaygain.h
│ │ ├── ripemd.h
│ │ ├── samplefmt.h
│ │ ├── sha512.h
│ │ ├── sha.h
│ │ ├── spherical.h
│ │ ├── stereo3d.h
│ │ ├── tea.h
│ │ ├── threadmessage.h
│ │ ├── timecode.h
│ │ ├── time.h
│ │ ├── timestamp.h
│ │ ├── tree.h
│ │ ├── twofish.h
│ │ ├── tx.h
│ │ ├── version.h
│ │ └── xtea.h
│ ├── libpostproc
│ │ ├── postprocess.h
│ │ └── version.h
│ ├── libswresample
│ │ ├── swresample.h
│ │ └── version.h
│ └── libswscale
│ ├── swscale.h
│ └── version.h
├── lib
│ ├── libavcodec.a
│ ├── libavcodec.so -> libavcodec.so.58.54.100
│ ├── libavcodec.so.58 -> libavcodec.so.58.54.100
│ ├── libavcodec.so.58.54.100
│ ├── libavdevice.a
│ ├── libavdevice.so -> libavdevice.so.58.8.100
│ ├── libavdevice.so.58 -> libavdevice.so.58.8.100
│ ├── libavdevice.so.58.8.100
│ ├── libavfilter.a
│ ├── libavfilter.so -> libavfilter.so.7.57.100
│ ├── libavfilter.so.7 -> libavfilter.so.7.57.100
│ ├── libavfilter.so.7.57.100
│ ├── libavformat.a
│ ├── libavformat.so -> libavformat.so.58.29.100
│ ├── libavformat.so.58 -> libavformat.so.58.29.100
│ ├── libavformat.so.58.29.100
│ ├── libavutil.a
│ ├── libavutil.so -> libavutil.so.56.31.100
│ ├── libavutil.so.56 -> libavutil.so.56.31.100
│ ├── libavutil.so.56.31.100
│ ├── libpostproc.a
│ ├── libpostproc.so -> libpostproc.so.55.5.100
│ ├── libpostproc.so.55 -> libpostproc.so.55.5.100
│ ├── libpostproc.so.55.5.100
│ ├── libswresample.a
│ ├── libswresample.so -> libswresample.so.3.5.100
│ ├── libswresample.so.3 -> libswresample.so.3.5.100
│ ├── libswresample.so.3.5.100
│ ├── libswscale.a
│ ├── libswscale.so -> libswscale.so.5.5.100
│ ├── libswscale.so.5 -> libswscale.so.5.5.100
│ ├── libswscale.so.5.5.100
│ └── pkgconfig
│ ├── libavcodec.pc
│ ├── libavdevice.pc
│ ├── libavfilter.pc
│ ├── libavformat.pc
│ ├── libavutil.pc
│ ├── libpostproc.pc
│ ├── libswresample.pc
│ └── libswscale.pc
└── share
├── ffmpeg
│ ├── examples
│ │ ├── avio_dir_cmd.c
│ │ ├── avio_reading.c
│ │ ├── decode_audio.c
│ │ ├── decode_video.c
│ │ ├── demuxing_decoding.c
│ │ ├── encode_audio.c
│ │ ├── encode_video.c
│ │ ├── extract_mvs.c
│ │ ├── filter_audio.c
│ │ ├── filtering_audio.c
│ │ ├── filtering_video.c
│ │ ├── http_multiclient.c
│ │ ├── hw_decode.c
│ │ ├── Makefile
│ │ ├── metadata.c
│ │ ├── muxing.c
│ │ ├── qsvdec.c
│ │ ├── README
│ │ ├── remuxing.c
│ │ ├── resampling_audio.c
│ │ ├── scaling_video.c
│ │ ├── transcode_aac.c
│ │ ├── transcoding.c
│ │ ├── vaapi_encode.c
│ │ └── vaapi_transcode.c
│ ├── ffprobe.xsd
│ ├── libvpx-1080p50_60.ffpreset
│ ├── libvpx-1080p.ffpreset
│ ├── libvpx-360p.ffpreset
│ ├── libvpx-720p50_60.ffpreset
│ └── libvpx-720p.ffpreset
└── man
├── man1
│ ├── ffmpeg.1
│ ├── ffmpeg-all.1
│ ├── ffmpeg-bitstream-filters.1
│ ├── ffmpeg-codecs.1
│ ├── ffmpeg-devices.1
│ ├── ffmpeg-filters.1
│ ├── ffmpeg-formats.1
│ ├── ffmpeg-protocols.1
│ ├── ffmpeg-resampler.1
│ ├── ffmpeg-scaler.1
│ ├── ffmpeg-utils.1
│ ├── ffprobe.1
│ └── ffprobe-all.1
└── man3
├── libavcodec.3
├── libavdevice.3
├── libavfilter.3
├── libavformat.3
├── libavutil.3
├── libswresample.3
└── libswscale.3
18 directories, 208 files
3.8 libxvidcore编译
Xvid(以前称为XviD)是一种开源MPEG-4视频编解码器,实现了对MPEG-4简单配置文件,高级简单配置文件和高级视频编码标准。它是用C语言编写的,具有针对质量和速度的汇编程序优化(包括i386的MMX,SSE和3Dnow代码以及PowerPC的AltiVec),并且特别针对存储和归档目的进行了脱机,多遍压缩的优化。
- 解压 xvidcore-1.3.7.tar.gz,打开终端后进入文件夹中,执行:
user@admin-machine:$ cd /home/user/compile/xvidcore-1.3.7/xvidcore/build/generic/
./configure --prefix=$PWD/_libs --disable-assembly
- 修改该文件夹下的platform.inc中的CC为交叉编译工具链
user@admin-machine:~/compile/xvidcore-1.3.7/xvidcore/build/generic$ sudo vim platform.inc
# Compiler
# ============================================================================
CC=aarch64-linux-gnu-gcc
SPECIFIC_CFLAGS=-fPIC -DHAVE_PTHREAD
ALTIVEC_CFLAGS=
CFLAGS=-Wall -O2 -fstrength-reduce -finline-functions -ffast-math -fomit-frame-pointer
LDFLAGS=
# =============================================================
ESC 后输入:wq后保存并退出。
- make & make install编译安装
user@admin-machine:~/compile/xvidcore-1.3.7/xvidcore/build/generic$ make
user@admin-machine:~/compile/xvidcore-1.3.7/xvidcore/build/generic$ make install
- 安装完成后文件夹下的_libs中生成的文件结构如下:
user@admin-machine:~/compile/xvidcore-1.3.7/_libs$ tree
.
├── include
│ └── xvid.h
└── lib
├── libxvidcore.a
├── libxvidcore.so -> libxvidcore.so.4.3
├── libxvidcore.so.4 -> libxvidcore.so.4.3
└── libxvidcore.so.4.3
2 directories, 5 files
3.9 将各软件的依赖库复制到交叉编译工具链文件路径下
- 将3.1-3.7节中各软件包生成的依赖库文件复制到交叉编译工具链文件路径下,以x264为例:
user@admin-machine:~/compile/x264-20191217/_libs$ sudo cp -r ./lib/ /opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/
user@admin-machine:~/compile/x264-20191217/_libs$ sudo cp -r ./incude/ /opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/
FFmpeg、libjpeg等的复制操作与之类似。
- 复制完成后,进/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib文件夹,检查链接库是否均为ARM架构的文件。
user@admin-machine:/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib$ file *
gcc: directory
libavcodec.a: current ar archive
libavcodec.so: symbolic link to libavcodec.so.58.54.100
libavcodec.so.58: symbolic link to libavcodec.so.58.54.100
libavcodec.so.58.54.100: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f717d7feed92ef79256df1b7ebe1d60509f00e65, stripped
libavdevice.a: current ar archive
libavdevice.so: symbolic link to libavdevice.so.58.8.100
libavdevice.so.58: symbolic link to libavdevice.so.58.8.100
libavdevice.so.58.8.100: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=ce6f80cfd6ddb657727e36f1bfddbbfbcba8f241, stripped
libavfilter.a: current ar archive
libavfilter.so: symbolic link to libavfilter.so.7.57.100
libavfilter.so.7: symbolic link to libavfilter.so.7.57.100
libavfilter.so.7.57.100: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=fa9e52d6b6bb1260ac0f9978e85cfd7000c12c1c, stripped
libavformat.a: current ar archive
libavformat.so: symbolic link to libavformat.so.58.29.100
libavformat.so.58: symbolic link to libavformat.so.58.29.100
libavformat.so.58.29.100: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=c9616380bf06e4d09e1c3fbd363f829e3351be57, stripped
libavutil.a: current ar archive
libavutil.so: symbolic link to libavutil.so.56.31.100
libavutil.so.56: symbolic link to libavutil.so.56.31.100
libavutil.so.56.31.100: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=5e648f1c3850f44a78d7ba92123fccc592fc0eeb, stripped
libcc1.so: symbolic link to libcc1.so.0.0.0
libcc1.so.0: symbolic link to libcc1.so.0.0.0
libcc1.so.0.0.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=9fe3b1d6c8946e1966c95dfd0d287263abc3435a, stripped
libgmp.a: current ar archive
libgmpxx.a: current ar archive
libjpeg.a: current ar archive
libjpeg.la: libtool library file, ASCII text
libjpeg.so: symbolic link to libjpeg.so.9.4.0
libjpeg.so.9: symbolic link to libjpeg.so.9.4.0
libjpeg.so.9.4.0: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=d990d2ecbea5c1ff78e8eb802e77d5df6439d743, with debug_info, not stripped
libmpc.a: current ar archive
libmpfr.a: current ar archive
libpng16.a: current ar archive
libpng16.so: symbolic link to libpng16.so.16.34
libpng16.so.16.34: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=5536d208849ab426956ed9ec73965d20040322b0, with debug_info, not stripped
libpng.a: symbolic link to libpng16.a
libpng.so: symbolic link to libpng16.so
libpostproc.a: current ar archive
libpostproc.so: symbolic link to libpostproc.so.55.5.100
libpostproc.so.55: symbolic link to libpostproc.so.55.5.100
libpostproc.so.55.5.100: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=4798fc2642fe09eaef5b2b03c1769dbd5f34281e, stripped
libswresample.a: current ar archive
libswresample.so: symbolic link to libswresample.so.3.5.100
libswresample.so.3: symbolic link to libswresample.so.3.5.100
libswresample.so.3.5.100: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=fead8371cacca4ac37e4e88884f672f159035805, stripped
libswscale.a: current ar archive
libswscale.so: symbolic link to libswscale.so.5.5.100
libswscale.so.5: symbolic link to libswscale.so.5.5.100
libswscale.so.5.5.100: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=8b7f0116299e8347d6df0fa5bca28ccc581470bd, stripped
libtiff.a: current ar archive
libtiff.la: libtool library file, ASCII text
libtiff.so: symbolic link to libtiff.so.5.3.0
libtiff.so.5: symbolic link to libtiff.so.5.3.0
libtiff.so.5.3.0: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=7fc15db14e04b778b9784ba383819227ce34e59f, with debug_info, not stripped
libtiffxx.a: current ar archive
libtiffxx.la: libtool library file, ASCII text
libtiffxx.so: symbolic link to libtiffxx.so.5.3.0
libtiffxx.so.5: symbolic link to libtiffxx.so.5.3.0
libtiffxx.so.5.3.0: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=7f88a2d639f1a17f7e6a15317da3a2ffc27f708c, with debug_info, not stripped
libx264.a: current ar archive
libx264.so: symbolic link to libx264.so.157
libx264.so.157: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=278766e50b44ea00b9f18d30c3292765338a6990, with debug_info, not stripped
libxvidcore.a: current ar archive
libxvidcore.so: symbolic link to libxvidcore.so.4.3
libxvidcore.so.4: symbolic link to libxvidcore.so.4.3
libxvidcore.so.4.3: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=0cb5f71001f2dc8f322a46941fdb1d7ecfec4f47, with debug_info, not stripped
libz.a: current ar archive
libz.so: symbolic link to libz.so.1.2.11
libz.so.1: symbolic link to libz.so.1.2.11
libz.so.1.2.11: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=5d86358d79f0a958135e5bb6f086b25817ed2ebb, with debug_info, not stripped
pkgconfig: directory
3.10 配置动态链接库
3.8节步骤完成后,/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib/pkgconfig/路径下的文件结构如下:
── pkgconfig
├── libavcodec.pc
├── libavdevice.pc
├── libavfilter.pc
├── libavformat.pc
├── libavutil.pc
├── libjpeg.pc
├── libpng16.pc
├── libpng.pc -> libpng16.pc
├── libpostproc.pc
├── libswresample.pc
├── libswscale.pc
├── libtiff.pc
├── x264.pc
└── zlib.pc
- 需修改文件中perfix等路径,并配置动态链接库,以zlib.pc为例:
user@admin-machine:/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib/pkgconfig$ sudo vim zlib.pc
prefix=/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu
exec_prefix=${prefix}
libdir=${prefix}/lib
sharedlibdir=${libdir}
includedir=${prefix}/include
Name: zlib
Description: zlib compression library
Version: 1.2.11
Requires:
Libs: -L${libdir} -L${sharedlibdir} -lz
Cflags: -I${includedir}
ESC 后输入:wq后保存并退出,按此步骤将所有.pc文件中的路径均修改为对应路径。
- 运行
sudo vim /etc/bash.bashrc
在最后一行添加如下
PKG_CONFIG_PATH=/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib/pkgconfig:$PKG_CONFIG_PATH
export PKG_CONFIG_PATH
ESC 后输入:wq后保存并退出,随后运行source ~/.bashrc激活生效。
- 添加动态库加载路径。以zlib为例:
user@admin-machine:~$ sudo vim /etc/ld.so.conf.d/zlib.conf
/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib
ESC 后输入:wq后保存并退出,随后运行sudo ldconfig
激活生效。
按此方法添加libavcodec、x264、libjpeg等的动态库加载路径后,重启PC使其生效。
- 验证各依赖包动态链接库是否生效,若出现以下路径,则表明动态链接库生效。
user@admin-machine:~$ pkg-config --libs --cflags zlib
-I/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/include -L/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib -lz
user@admin-machine:~$ pkg-config --libs --cflags x264
-I/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/include -L/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib -lx264
user@admin-machine:~$ pkg-config --libs --cflags libavcodec
-I/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/include -L/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib -lavcodec
user@admin-machine:~$ pkg-config --libs --cflags libjpeg
-I/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/include -L/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib -ljpeg
...
至此,OpenCV交叉编译所需的依赖库及编译环境配置完成。
三、交叉编译OpenCV 3.4.10
- 解压opencv-3.4.10.zip,进文件夹中执行以下操作:
user@admin-machine:~/opencv/opencv-3.4.10$ sudo mkdir release
user@admin-machine:~/opencv/opencv-3.4.10$ cd ./release
user@admin-machine:~/opencv/opencv-3.4.10/release$ sudo mkdir install
- 新建toolchain.cmake文件,配置交叉编译工具链,并设置OPENCV_ENABLE_PKG_CONFIG ON(OpenCV 3.4默认关闭此项,若不配置,cmake时会导致无法找到FFmpeg的链接库路径)和FFMPEG的文件路径。未编译FFmpeg的程序在开发板上执行时会报下图错误:
@admin-machine:~/opencv/opencv-3.4.10/release$ sudo vim toolchain.cmake
###########user defined#############
set( CMAKE_SYSTEM_NAME Linux )
set( CMAKE_SYSTEM_PROCESSOR arm )
set( CMAKE_C_COMPILER aarch64-linux-gnu-gcc )
set( CMAKE_CXX_COMPILER aarch64-linux-gnu-g++ )
set( OPENCV_ENABLE_PKG_CONFIG ON)
set( FFMPEG_INCLUDE_DIR "/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/include")
set( FFMPEG_LIB_DIR "/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib")
###########user defined#############
set( CMAKE_FIND_ROOT_PATH "/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu" )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
######################################
- 执行cmake,由于项目使用Qt作为GUI设计软件,不使用GTK,故配置WITH_GTK=OFF(PC端不可安装libgtk2.0-dev,会因为软件包支持系统架构不同,导致OpenCV交叉编译时报错)
cmake -D CMAKE_TOOLCHAIN_FILE=toolchain.cmake -D BUILD_opencv_python3=yes -D BUILD_opencv_python2=no -D PYTHON3_EXECUTABLE=/usr/bin/python3.7m -D PYTHON3_INCLUDE_DIR=/usr/include/python3.7m -D PYTHON3_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.7m.so -D PYTHON3_PACKAGES_PATH=/usr/lib/python3/dist-packages -D PYTHON_DEFAULT_EXECUTABLE=/usr/bin/python3.7m -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/home/user/opencv/opencv-3.4.10/release/install -D BUILD_ZLIB=ON -D BUILD_JPEG=ON -D BUILD_PNG=ON -D BUILD_TIFF=ON -D ENABLE_CXX11=ON -D WITH_FFMPEG=ON -D WITH_OPENCL=ON -D WITH_GTK=OFF -D WITH_OPENGL=ON -D WITH_OPENMP=ON -D WITH_PNG=ON ..
打印以下内容:
-- General configuration for OpenCV 3.4.10 =====================================
-- Version control: unknown
--
-- Platform:
-- Timestamp: 2021-04-22T13:25:33Z
-- Host: Linux 5.4.0-66-generic x86_64
-- Target: Linux arm
-- CMake: 3.10.2
-- CMake generator: Unix Makefiles
-- CMake build tool: /usr/bin/make
-- Configuration: RELEASE
--
-- CPU/HW features:
-- Baseline: NEON FP16
-- requested: DETECT
-- disabled: VFPV3 NEON
--
-- C/C++:
-- Built as dynamic libs?: YES
-- C++11: YES
-- C++ Compiler: /opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++ (ver 7.5.0)
-- C++ flags (Release): -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winit-self -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -fvisibility=hidden -fvisibility-inlines-hidden -fopenmp -O3 -DNDEBUG -DNDEBUG
-- C++ flags (Debug): -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winit-self -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -fvisibility=hidden -fvisibility-inlines-hidden -fopenmp -g -O0 -DDEBUG -D_DEBUG
-- C Compiler: /opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc
-- C flags (Release): -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Winit-self -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -fvisibility=hidden -fopenmp -O3 -DNDEBUG -DNDEBUG
-- C flags (Debug): -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Winit-self -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -fvisibility=hidden -fopenmp -g -O0 -DDEBUG -D_DEBUG
-- Linker flags (Release): -Wl,--gc-sections -Wl,--as-needed
-- Linker flags (Debug): -Wl,--gc-sections -Wl,--as-needed
-- ccache: NO
-- Precompiled headers: NO
-- Extra dependencies: dl m pthread rt
-- 3rdparty dependencies:
--
-- OpenCV modules:
-- To be built: calib3d core dnn features2d flann highgui imgcodecs imgproc ml objdetect photo shape stitching superres ts video videoio videostab
-- Disabled: world
-- Disabled by dependency: -
-- Unavailable: cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev java js python2 python3 viz
-- Applications: tests perf_tests apps
-- Documentation: NO
-- Non-free algorithms: NO
--
-- GUI:
-- OpenGL support: NO
--
-- Media I/O:
-- ZLib: build (ver 1.2.11)
-- JPEG: build-libjpeg-turbo (ver 2.0.4-62)
-- WEBP: build (ver encoder: 0x020f)
-- PNG: build (ver 1.6.37)
-- TIFF: build (ver 42 - 4.0.10)
-- JPEG 2000: build (ver 1.900.1)
-- HDR: YES
-- SUNRASTER: YES
-- PXM: YES
--
-- Video I/O:
-- DC1394: NO
-- FFMPEG: YES
-- avcodec: YES (ver 58.54.100)
-- avformat: YES (ver 58.29.100)
-- avutil: YES (ver 56.31.100)
-- swscale: YES (ver 5.5.100)
-- avresample: NO
-- GStreamer: NO
-- libv4l/libv4l2: NO
-- v4l/v4l2: linux/videodev2.h
--
-- Parallel framework: OpenMP
--
-- Trace: YES (with Intel ITT)
--
-- Other third-party libraries:
-- Lapack: NO
-- Custom HAL: YES (carotene (ver 0.0.1))
-- Protobuf: build (3.5.1)
--
-- OpenCL: YES (no extra features)
-- Include path: /home/user/opencv/opencv-3.4.10/3rdparty/include/opencl/1.2
-- Link libraries: Dynamic load
--
-- Python 3:
-- Interpreter: /usr/bin/python3.7m (ver 3.7.10)
-- Libraries: NO
-- numpy: NO (Python3 wrappers can not be generated)
-- install path: -
--
-- Python (for build): /usr/bin/python3.7m
--
-- Install to: /home/user/opencv/opencv-3.4.10/build/install
-- -----------------------------------------------------------------
--
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/opencv/opencv-3.4.10/build
- 修改生成的CMakeCache.txt文件,配置CMAKE_CXX_FLAGS:STRING= 和CMAKE_C_FLAGS:STRING= 的路径,否则会报以下错误:
[ 62%] Building CXX object modules/dnn/CMakeFiles/opencv_dnn.dir/src/layers/eltwise_layer.cpp.o
/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: warning: libavcodec.so.58, needed by ../../lib/libopencv_videoio.so.3.4.10, not found (try using -rpath or -rpath-link)
/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: warning: libavformat.so.58, needed by ../../lib/libopencv_videoio.so.3.4.10, not found (try using -rpath or -rpath-link)
/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: warning: libavutil.so.56, needed by ../../lib/libopencv_videoio.so.3.4.10, not found (try using -rpath or -rpath-link)
/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: warning: libswscale.so.5, needed by ../../lib/libopencv_videoio.so.3.4.10, not found (try using -rpath or -rpath-link)
../../lib/libopencv_videoio.so.3.4.10:对‘av_init_packet@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_get_riff_video_tags@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_get_mov_video_tags@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_find_decoder@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_find_decoder_by_name@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_frame_alloc@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_get_name@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_malloc@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avio_open@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_alloc_context@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_sub_q@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_network_init@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_flush_buffers@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_find_encoder@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘sws_getContext@LIBSWSCALE_5’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_write_frame@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_close_input@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_seek_frame@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘sws_freeContext@LIBSWSCALE_5’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_dict_set@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘sws_scale@LIBSWSCALE_5’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_packet_unref@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_dict_parse_string@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_frame_get_buffer@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_freep@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_find_stream_info@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_read_frame@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_free_context@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_register_all@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_free@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_guess_sample_aspect_ratio@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_encode_video2@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_new_stream@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_frame_unref@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_write_trailer@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_bsf_get_by_name@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_dict_get@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_bsf_free@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_open_input@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_lockmgr_register@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_bsf_send_packet@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_bsf_alloc@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_log_set_level@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_rescale_q@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_image_get_buffer_size@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_open2@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_guess_format@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_image_fill_arrays@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_bsf_receive_packet@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘sws_getCachedContext@LIBSWSCALE_5’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_codec_get_tag@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_log_set_callback@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_opt_set@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_decode_video2@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_codec_get_id@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_write_header@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_parameters_copy@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_pix_fmt_to_codec_tag@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_mallocz@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_find_input_format@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_guess_codec@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_dict_free@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avio_close@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_frame_free@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_bsf_init@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_close@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_get_context_defaults3@LIBAVCODEC_58’未定义的引用
collect2: 错误: ld 返回 1
apps/visualisation/CMakeFiles/opencv_visualisation.dir/build.make:99: recipe for target 'bin/opencv_visualisation' failed
#大约在278行和302行左右
user@admin-machine:~/opencv/opencv-3.4.10/release$ sudo vim CMkeCacche.txt
...
//Flags used by the compiler during all build types.
CMAKE_CXX_FLAGS:STRING=-Wl,-rpath-link=/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib
...
//Flags used by the compiler during all build types.
CMAKE_C_FLAGS:STRING=-Wl,-rpath-link=/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib
...
ESC 后输入:wq后保存并退出。执行make & make install 即可。
user@admin-machine:~/opencv/opencv-3.4.10/release$ make -j6
user@admin-machine:~/opencv/opencv-3.4.10/release$ make install
耐心等待几十分钟。
- 若无报错,再配置OpenCV的动态链接库路径。配置方法和上文3.8节类似,修改lib/pkgconfig下的opencv.pc,新建openc.conf文件,然后测试opencv的动态链接库是否生效,如下所示:
user@admin-machine:~$ pkg-config --libs --cflags opencv
-I/home/user/opencv/opencv-3.4.10/release/install/include/opencv -I/home/user/opencv/opencv-3.4.10/release/install/include -L/home/user/opencv/opencv-3.4.10/release/install/lib -lopencv_dnn -lopencv_highgui -lopencv_ml -lopencv_objdetect -lopencv_shape -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_videoio -lopencv_imgcodecs -lopencv_features2d -lopencv_video -lopencv_photo -lopencv_imgproc -lopencv_flann -lopencv_core
四、测试OpenCV是否可以交叉编译
user@admin-machine:$ cd /home/user/opencv/opencv-3.4.10/samples/cpp/example_cmake
#改CMakeLists.txt,指定OpenCVConfig.cmake opencv-config.cmake的安装路径,否则编译会报错
user@admin-machine:~/opencv/opencv-3.4.10/samples/cpp/example_cmake$sudo vim CMakeLists.txt
# cmake needs this line
cmake_minimum_required(VERSION 2.8)
# Define project name
project(opencv_example_project)
# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
#新增以下行,指定OpenCV__DIR的路径
set(OpenCV_DIR /home/user/opencv/opencv-3.4.10/release/install/share/OpenCV)
find_package(OpenCV REQUIRED)
# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
if(CMAKE_VERSION VERSION_LESS "2.8.11")
# Add OpenCV headers location to your include paths
include_directories(${OpenCV_INCLUDE_DIRS})
endif()
# Declare the executable target built from your sources
add_executable(opencv_example example.cpp)
# Link your application with OpenCV libraries
target_link_libraries(opencv_example PRIVATE ${OpenCV_LIBS})
user@admin-machine:~/opencv/opencv-3.4.10/samples/cpp/example_cmake$ aarch64-linux-gnu-g++ example.cpp -o example -lpthread -lrt `pkg-config --libs --cflags opencv` -Wl,-rpath-link=/home/user/opencv/opencv-3.4.10/release/install/lib
user@admin-machine:~/opencv/opencv-3.4.10/samples/cpp/example_cmake$ file *
CMakeLists.txt: ASCII text
example: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=3e5ea3912e81c33c10592ce628b1250a65f6e457, with debug_info, not stripped
example.cpp: C++ source, ASCII text
Makefile: makefile script, ASCII text
- 将生成的example可执行文件复制到开发板的任意路径,执行
sudo chmod +x example
,配置可执行权限,./example
运行后如下图所示:
- Qt中编写一段程序,交叉编译后复制到开发板上,测试USB摄像头的视频播放和播放本地mp4视频,如下列图所示:
Qt中的项目pro文件配置的动态链接库路径图:
总结
交叉编译OpenCV过程十分繁琐,需要一步步按照依赖关系处理,由于OpenCV的Python接口依赖numpy,暂时还没找到交叉编译numpy支持OpenCV的Python接口的方法,后续再进行进一步测试。
本文主要参考的文章:
《Ubuntu16.04交叉编译openCV》
《Ubuntu 14.04 LTS下使用arm-linux-gcc交叉编译OpenCV 2.4.9》
《arm-himix200-linux交叉编译opencv4.1》
《虚拟机交叉编译openCV详细步骤及bug解决详解》
《Toybrick TB-RK3399ProD《在Ubuntu18.04下基于RK3399交叉编译工具交叉编译libx264和ffmpeg》》
《交叉编译libpng报错:configure: error: zlib not installed》
《常用库之五:libtiff的交叉编译》
《Firefly AIO-3399ProC开发板与PC端部署Qt5.12.2交叉编译环境》
等。