目录
- 目录
- 编译信息
- 说明
- 问题及现象
- 解决方法
编译信息
作者:xzf
创建时间:2022/4/22
更新时间:2022/5/06
说明
工作需要用到opencv旧版本,4.5.0版本。而且需要编译为arm架构系统。并支持解码和GUI。
- cmake版本:3.22.20211110-g4b5fa96
- opencv版本:4.5.0
- Linux版本:#44~20.04.1-Ubuntu SMP Thu Mar 24 16:43:35 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
- 交叉编译工具链。https://releases.linaro.org/components/toolchain/binaries/5.2-2015.11/aarch64-linux-gnu/
正常编译x86_64
编译
官方编译方法:https://docs.opencv.org/4.x/d7/d9f/tutorial_linux_install.html
# 1.下载源码,根据版需要
git clone -b 4.5.0 https://gitee.com/mirrors/opencv.git
# 2.进入源码
cd opencv
# 3.新建编译缓存区,防止源码被污染
mkdir build
# 4.生成makefile
cmake .. -DCMAKE_INSTALL_PREFIX=安装路径
#可能会遇到问题
#出现:CMake Error at cmake/OpenCVCompilerOptions.cmake:21 (else):
#解决办法 在cmake/OpenCVCompilerOptions.cmake:21 注释:else()即可。
# 5.编译make
make -j4
# 6.安装
如果需要GUI界面,需要添加相关依赖。
sudo apt-get install build-essential libavcodec-dev libavformat-dev libjpeg-dev libswscale-dev libtiff5-dev
sudo apt-get install libgtk2.0-dev
sudo apt-get install pkg-config
但是具体缺乏什么依赖,需求再执行cmake..-D..
后查看生产的说明,特别是否开启了GUI GTK+ 2.x YES
,如果是 NO 需要查看缺乏了那些依赖。有些依赖不在也不会报错。
其他命令
指定安装路径(尽量使用此命令,防止被污染系统)
cmake .. -DCMAKE_INSTALL_PREFIX=<安装路径>
支持GUI需要下载GTK2.0,然后重现编译opencv
sudo apt-get install libgtk2.0-dev
直到编译opencv执行cmake命令后,出现上述支持,再编译,使用即可。
支持解码和读取视频
opencv需要打开图片需要包含支持解码ffmpeg,需要下ffmpeg
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev
直到编译opencv执行cmake命令后,出现上述支持,再编译,使用即可。
可能遇到的报错
当需要编译FFmpeg时,在编译低版本的openc可能会报错。比如3.2.0版本
这时可以修改:
在在 opencv-3.2.0/modules/videoio/src/cap_ffmpeg_impl.hpp
里最顶端添加:
#define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22)
#define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER
#define AVFMT_RAWPICTURE 0x0020
参考https://blog.csdn.net/goodxin_ie/article/details/82856008
交叉编译方法
-----------特别注意需要下载交叉编译工具链--------------
官方编译方法:https://docs.opencv.org/4.x/d0/d76/tutorial_arm_crosscompile_with_cmake.html
基本同上,但是由于需要是格外支持的依赖库需要先编译好支持arm架构的opencv库而opencv需要先编译好ffmpeg(包含x264)库和gtk2.0库
编译x264
下载x264:https://www.videolan.org/developers/x264.html
#下载
# wget https://code.videolan.org/videolan/x264/-/archive/master/x264-master.tar.bz2
git clone https://code.videolan.org/videolan/x264.git
#进入库
cd x264
编写脚本
#!/bin/bash
#
# ------------------------------------------------------------
# File name: make_x264.sh
# Version: 1.0
# Author: xzf
# Description: 用于交叉编译x264的脚本
# Date: 2022-04-05
# Usage: sh make_x264.sh
# ------------------------------------------------------------
#获取绝对路径
path=$(dirname $(readlink -f "$0"))
#prefix指定路径
#cross-prefix=在交叉编译工具链的bin文件里的aarch64-linux-gnu-gcc,去掉gcc
./configure --prefix="$path/install" --enable-shared --disable-asm --host=arm-linux --cross-prefix=aarch64-linux-gnu-
执行脚本及安装
#执行脚本
sh make_x264.sh
#编译
make -j4
#安装
make install
检查生成
cd install
file libx264.so.164
#打印信息
libx264.so.164: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=eedfe78583c4b79fff99db4d2c1f3d19c74d4114, with debug_info, not stripped
编译ffmpeg
下载ffmpg:https://github.com/FFmpeg/FFmpeg.g
编写脚本
#!/bin/bash
#
# ------------------------------------------------------------
# File name: make_ffmpeg.sh
# Version: 1.0
# Author: xzf
# Description: 用于交叉编译x264的脚本
# Date: 2022-04-25
# Usage: sh make_ffmpeg.sh
# ------------------------------------------------------------
#获取绝对路径
path=$(dirname $(readlink -f "$0"))
#prefix指定路径
#开启x264 --enable-gpl --enable-libx264
#开启交叉编译 --enable-cross-compile
#指定编译器 --cc=aarch64-linux-gnu-gcc --cxx=aarch64-linux-gnu-g++
#防止安装失败--strip=aarch64-linux-gnu-strip
./configure --prefix="$path/install" --enable-shared --disable-asm --enable-gpl --enable-libx264 --enable-cross-compile --cc=aarch64-linux-gnu-gcc --cxx=aarch64-linux-gnu-g++ --disable-ffmpeg --disable-ffprobe --strip=aarch64-linux-gnu-strip --enable-pic
增加依赖(临时)
export PKG_CONFIG_PATH=/home/xzf/work/Location/dlib/arm-lib/x264/install/lib/pkgconfig
执行脚本及安装
#执行脚本
sh make_ffmpeg.sh
#编译
make -j4
#安装
make install
编译QT源码
说明:本文选择的是5.12.3,其他版本可能会高,5.12.0编译过程会报错,貌似与GCC版本冲突,GCC-8和GCC-9的问题,具体没有深究,使用5.12.3版本没有问题。
下载地址:
- 官方:https://download.qt.io/archive/qt/5.12/
- 清华镜像:https://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/
- 中国科技大学:http://mirrors.ustc.edu.cn/qtproject/archive/qt/
#下载
wget https://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/5.12/5.12.3/single/qt-everywhere-src-5.12.3.tar.xz
#解压
tar -xvf qt-everywhere-src-5.12.3.tar.xz
找到交叉编译链,找到自己的编译器,一般都能找到,根据自己的交叉编译器来。
cd qt-everywhere-src-5.12.3.tar.xz
cd /qtbase/mkspecs
比如现在用的交叉编译器是aarch64-linux-gnu-g++
mkspecs并没有这个,但是有linux-aarch64-gnu-g++
,点进去就是aarch64-linux-gnu-g++
查看qmake.conf
,所以直接用即可或者复制修改名字为aarch64-linux-gnu-g++
,如果没有就新建,复制模板改成合适的交叉编译器。
编写脚本
./configure -prefix ./install \
-opensource \
-confirm-license \
-xplatform aarch64-linux-gnu-g++ \
-no-opengl \
执行脚本及安装
#执行脚本
sh make_ffmpeg.sh
#编译
make -j4
#安装
make install
编译opencv
编写交叉编译链接
直接复制aarch64-gnu.toolchain.cmake
即可,由于目前无需修改,复制即可,若有修改,可以修改,而不改变原来的编译链接。
cp aarch64-gnu.toolchain.cmake aarch64-gnu-ivisionic.toolchain.cmake
编写脚本
cmake .. \
-D CMAKE_BUILD_TYPE=Release \
-D CMAKE_TOOLCHAIN_FILE=../platforms/linux/aarch64-gnu-ivisionic.toolchain.cmake \
-D WITH_QT=ON \
-D WITH_GTK=OFF \
-D WITH_GTK_2_X=OFF \
-D WITH_FFMPEG=ON \
-D BUILD_XLIB=ON \
-D BUILD_TESTS=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_opencv_apps=OFF \
-D OPENCV_GENERATE_PKGCONFIG=ON \
-D OPENCV_FFMPEG_USE_FIND_PACKAGE=ON \
-D OPENCV_FFMPEG_SKIP_BUILD_CHECK=ON \
-D FFMPEG_DIR=/home/xzf/work/Location/dlib/arm-lib/ffmpeg/install \
-D Qt5_DIR=/home/xzf/work/Location/dlib/arm-lib/qt-everywhere-src-5.12.3/install/lib/cmake/Qt5 \
-D Qt5Core_DIR=/home/xzf/work/Location/dlib/arm-lib/qt-everywhere-src-5.12.3/install/lib/cmake/Qt5Core \
-D Qt5Gui_DIR=/home/xzf/work/Location/dlib/arm-lib/qt-everywhere-src-5.12.3/install/lib/cmake/Qt5Gui \
-D Qt5Widgets_DIR=/home/xzf/work/Location/dlib/arm-lib/qt-everywhere-src-5.12.3/install/lib/cmake/Qt5Widgets \
-D Qt5Test_DIR=/home/xzf/work/Location/dlib/arm-lib/qt-everywhere-src-5.12.3/install/lib/cmake/Qt5Test \
-D Qt5Concurrent_DIR=/home/xzf/work/Location/dlib/arm-lib/qt-everywhere-src-5.12.3/install/lib/cmake/Qt5Concurrent \
编写ffmpeg-config.cmake
由于ffmpeg不支持cmake,需要自己编写ffmpeg-config.cmake,以方便opencv查找。在FFMPEG_DIR安装位置同目录下
set(ffmpeg_path "${CMAKE_CURRENT_LIST_DIR}")
message("ffmpeg_path: ${ffmpeg_path}")
set(FFMPEG_EXEC_DIR "${ffmpeg_path}/bin")
set(FFMPEG_LIBDIR "${ffmpeg_path}/lib")
set(FFMPEG_INCLUDE_DIRS "${ffmpeg_path}/include")
# library names
set(FFMPEG_LIBRARIES
${FFMPEG_LIBDIR}/libavformat.so
${FFMPEG_LIBDIR}/libavdevice.so
${FFMPEG_LIBDIR}/libavcodec.so
${FFMPEG_LIBDIR}/libavutil.so
${FFMPEG_LIBDIR}/libswscale.so
${FFMPEG_LIBDIR}/libswresample.so
${FFMPEG_LIBDIR}/libavfilter.so
)
# found status
set(FFMPEG_libavformat_FOUND TRUE)
set(FFMPEG_libavdevice_FOUND TRUE)
set(FFMPEG_libavcodec_FOUND TRUE)
set(FFMPEG_libavutil_FOUND TRUE)
set(FFMPEG_libswscale_FOUND TRUE)
set(FFMPEG_libswresample_FOUND TRUE)
set(FFMPEG_libavfilter_FOUND TRUE)
# library versions, 注意这几个变量,一定要设置为全局CACHE变量
set(FFMPEG_libavutil_VERSION 56.31.101 CACHE INTERNAL "FFMPEG_libavutil_VERSION") # info
set(FFMPEG_libavcodec_VERSION 58.54.100 CACHE INTERNAL "FFMPEG_libavcodec_VERSION") # info
set(FFMPEG_libavformat_VERSION 58.29.100 CACHE INTERNAL "FFMPEG_libavformat_VERSION") # info
set(FFMPEG_libavdevice_VERSION 58.8.100 CACHE INTERNAL "FFMPEG_libavdevice_VERSION") # info
set(FFMPEG_libavfilter_VERSION 7.57.100 CACHE INTERNAL "FFMPEG_libavfilter_VERSION") # info
set(FFMPEG_libswscale_VERSION 5.5.100 CACHE INTERNAL "FFMPEG_libswscale_VERSION") # info
set(FFMPEG_libavresample_VERSION 3.5.100 CACHE INTERNAL "FFMPEG_libswresample_VERSION") # info
set(FFMPEG_FOUND TRUE)
set(FFMPEG_LIBS ${FFMPEG_LIBRARIES})
status(" FFMPEG:" FFMPEG_FOUND THEN "YES (find_package)" ELSE "NO (find_package)")
status(" avcodec:" FFMPEG_libavcodec_VERSION THEN "YES (${FFMPEG_libavcodec_VERSION})" ELSE NO)
status(" avformat:" FFMPEG_libavformat_VERSION THEN "YES (${FFMPEG_libavformat_VERSION})" ELSE NO)
status(" avutil:" FFMPEG_libavutil_VERSION THEN "YES (${FFMPEG_libavutil_VERSION})" ELSE NO)
status(" swscale:" FFMPEG_libswscale_VERSION THEN "YES (${FFMPEG_libswscale_VERSION})" ELSE NO)
status(" avresample:" FFMPEG_libavresample_VERSION THEN "YES (${FFMPEG_libavresample_VERSION})" ELSE NO)
执行脚本及安装
#执行脚本
sh make_ffmpeg.sh
#编译
make -j4
#安装
make install
后记总结
交叉编译opencv解码加显示,并不容易,也不友好,特别某些开发板没有apt install
或者甚至没ldd
的阉割版系统。比如编译 opencv 的 GUI,需要 GTK 或者QT,GTK基本非常难交叉编译,如果能直接install,会比较方便,QT编译容易,但是也不能直接显示,因为没有xcb库,需要编译xcb库才能显示器,或者其他库。本文编译opencv带ffmpeg和Qt,但是直接使用的qt库却不能使用,因为没有xcb,因此,qt链接是链接到开发板自带的qt库。才能完成显示。编译只是为了opencv能支持GUI功能。