OpenCV在Arm-Linux上的安装

原本以为就是一行 sudo apt-get 的事,,是我太年轻。

环境配置

交叉编译

麻烦,但是速度快,如果你已经有工具链了的话。
一点也不麻烦, 速度还很快, 在一些性能较弱的平台上也只能通过交叉编译来实现OpenCV的安装。
当然也有坑, 回来再填。

hf?
none?

工具链的安装

如果有工具链的话 可以忽略此步骤
当然 如果没有官方的工具链 在后面的lib配置会很难受。
我用的是启划科技的A83T开发板,其官方工具链需要先编译Linux-QT或者Ubuntu源码才能安装。
先不说一遍译就是一个晚上,还TM编译失败…所以我就用了通用ARM工具链。

1
2
sudo apt-get install gcc-arm-linux-gnueabi
sudo apt-get install g++-arm-linux-gnueabi

安装完之后 可以用

1
2
arm-linux-gnueabi-gcc
arm-linux-gnueabi-g++

去召唤(注意拼写变化)

对应工具链位置为

1
2
/usr/bin/arm-linux-gnueabi-gcc
/usr/bin/arm-linux-gnueabi-g++

然后安装cmake-gui

1
2
sudo apt-get install cmake
sudo apt-get install cmake-qt-gui

然后用cmake-gui运行

其余的GUI配置方面和这篇帖子差不多,但是其他配置如CMAKE的lib配置和他不一样。
https://blog.csdn.net/sanallen/article/details/81227182

然后配置lib位置
我这里是

1
/home/qihua/桌面/CQA83TLinux_Qt5.8.0_bv3/buildroot-2017.02.3/output/host/usr/arm-buildroot-linux-gnueabihf/sysroot

至于OpenCV的安装选项,下文有提到。

开发板编译

首先安装依赖库

1
sudo apt-get install build-essential checkinstall git cmake libfaac-dev libjack-jackd2-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libsdl1.2-dev libtheora-dev libva-dev libvdpau-dev libvorbis-dev libx11-dev libxfixes-dev libxvidcore-dev texi2html yasm ruby zlib1g zlib1g.dev libgstreamer0.10-0 libgstreamer0.10-dev gstreamer0.10-tools gstreamer0.10-plugins-base libgstreamer-plugins-base0.10-dev gstreamer0.10-plugins-good gstreamer0.10-plugins-ugly gstreamer0.10-plugins-bad gstreamer0.10-ffmpeg

尽管上文中包含了zlib1g zlib1g.dev
但是有时候还是会出现不认zlib的情况。(下文有提到)

然后找一个没有权限的非关键位置下载和解压OpenCV源代码 我这里用的homecd ~
rz 这个功能需要安装lrzsz,然后输入rz之后就可以从电脑传输OpenCV源代码压缩包。这句话的本质就是传输OpenCV压缩包到开发板。
tar -zxvf OpenCV.tar.gz 这一步具体文件名视具体情况而定。
cd opencv 文件名要求同上。
mkdir build 下面几句话就不用变了
cd build
cmake .. 亲测 无论是老版本(3.2.0)还是新版本(4.3.0)都可以直接按照默认配置进行cmake。

OpenCV 4.3.0以及以前直接 cmake .. 即可

OpenCV 4.5.0 cmake时需注意, 需要手动开启pkg-config生成opencv4.pc

1
cmake -DCMAKE_BUILD_TYPE=Release -DOPENCV_GENERATE_PKGCONFIG=ON -DCMAKE_INSTALL_PREFIX=/usr/local ..

然后make -jn注意jn是指以几核心多线程编译 默认单核 量力而行 不只是要考虑CPU 还需要考虑 RAM。1G RAM建议使用-j4。当然这个数量尽量不要超过你的(核心数-1)
其实开大也没事 就是中途会因为爆RAM编译失败。失败也没事 再输入一遍make即可继续编译。

对于OpenCV 4.3.0 可能会出现如下报错

踩坑

1.缺少zlib依赖

遇到如下错误时:

1
2
Built target opencv_dnn
Makefile:160: recipe for target 'all' failed

1
2
Built target opencv_gapi
Makefile:160: recipe for target 'all' failed

之类的报错,需先检查前面是否出现下列报错

1
2
3
4
5
6
../../lib/libopencv_core.so.3.2.0: undefined reference to `gzeof'
../../lib/libopencv_core.so.3.2.0: undefined reference to `gzrewind'
../../lib/libopencv_core.so.3.2.0: undefined reference to `gzopen'
../../lib/libopencv_core.so.3.2.0: undefined reference to `gzclose'
../../lib/libopencv_core.so.3.2.0: undefined reference to `gzgets'
../../lib/libopencv_core.so.3.2.0: undefined reference to `gzputs'

如果出现,则检查zlib是否存在
whereis zlib
zlib不存在的话 去官网安装zlib
http://www.zlib.net/
存在的话 cmake后面加上下面一句:
-s USE_ZLIB=1

其实大多数recipe for target 'all' failed报错并不是前面那一句 而是前面的undefined

如果未出现undefined 则尝试按照如下网址教程安装依赖ffmepg等依赖。
http://www.ozbotz.org/opencv-installation-2-3-1/

2.磁盘文件系统格式问题

1
2
3
4
5
6
7
8
9
10
[ 26%] Linking CXX shared library ../../lib/libopencv_core.so
CMake Error: cmake_symlink_library: System Error: Function not implemented
CMake Error: cmake_symlink_library: System Error: Function not implemented
modules/core/CMakeFiles/opencv_core.dir/build.make:2281: recipe for target 'lib/libopencv_core.so.4.3.0' failed
make[2]: *** [lib/libopencv_core.so.4.3.0] Error 1
make[2]: *** Deleting file 'lib/libopencv_core.so.4.3.0'
CMakeFiles/Makefile2:1251: recipe for target 'modules/core/CMakeFiles/opencv_core.dir/all' failed
make[1]: *** [modules/core/CMakeFiles/opencv_core.dir/all] Error 2
Makefile:160: recipe for target 'all' failed
make: *** [all] Error 2

我开发板是1+8的配置,8G储存很快就用完了。然后我就把OpenCV放到了内存卡里面去build
然后就出现了这个情况。我去Stackoverflow,Google,OpenCV官网,MSDN上都没有搜到相似度很高的问题。
有的说是权限问题,然后我开放所有权限,sudo也没用。
还有的人说是因为没有关闭CUDA OpenCL等硬件不支持的特性导致的。
然后我就关闭了 CUDA OpenCL OpenGL 试了试,结果还是不行。
然后突然想到昨天备份build的时候 直接cp是无法拷贝的。就突然想到了是文件系统格式的问题。
也就是说 在ext系统下可以正常使用的文件名 在exfat下就不行,然后我就删除了很多东西,把OpenCV拷贝到home目录,问题解决。

3.RAM满了

1
2
3
c++: internal compiler error: Killed (program cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.

make -jn的时候 减小线程数即可。
1G RAM 2–3线程即可
2G RAM 5线程没有问题

4.部分架构CPU下默认仓库缺少依赖包

4.1 Unable to locate package libfaac-dev

报错如下:

1
2
sudo apt-get install libfaac-dev
E: Unable to locate package libfaac-dev

找不到faac的原因是faad出来了..
直接安装faad即可

1
apt-get install libfaad-dev

4.2 Unable to locate package gstreamer *(手动正则表达式23333)

报错如下:

1
2
3
4
5
6
sudo apt-get install gstreamer0.10-plugins-ugly gstreamer0.10-plugins-bad gstreamer0.10-ffmpeg
E: Package 'gstreamer0.10-plugins-ugly' has no installation candidate
E: Package 'gstreamer0.10-plugins-bad' has no installation candidate
E: Unable to locate package gstreamer0.10-ffmpeg
E: Couldn't find any package by glob 'gstreamer0.10-ffmpeg'
E: Couldn't find any package by regex 'gstreamer0.10-ffmpeg'

我找到了一个还算不错的解决方法:
https://www.cnblogs.com/sxgloverr1314/p/10541491.html
不是最新版 但是最新版我不会安装 →_→
别选1.1.2版本 会ERROR

4.3 No package ‘libavresample’ found

1
2
sudo apt-get -y install libavresample-dev
sudo apt-get -y install libgphoto2-dev

5.apt-get时缺少依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
sudo apt-get install  libopencore-amrwb-dev libsdl1.2-dev 
Reading package lists... Done
Building dependency tree
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
libsdl1.2-dev : Depends: libcaca-dev but it is not going to be installed
E: Unable to correct problems, you have held broken packages.

上图中缺少 libcaca-dev 需要先安装 libcaca-dev 才行。
然后一环套一环 直到所有都安装完。

6.relocation R_ARM_THM_MOVW_ABS_NC against `a local symbol’ can not be used when making a shared object;

1
2
3
4
5
6
7
8
9
Linking CXX shared library ../../lib/libopencv_videoio.so
/usr/bin/ld: /usr/local/lib/libavformat.a(allformats.o): relocation R_ARM_THM_MOVW_ABS_NC against `a local symbol' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/libavformat.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
modules/videoio/CMakeFiles/opencv_videoio.dir/build.make:418: recipe for target 'lib/libopencv_videoio.so.4.3.0' failed
make[2]: *** [lib/libopencv_videoio.so.4.3.0] Error 1
CMakeFiles/Makefile2:2736: recipe for target 'modules/videoio/CMakeFiles/opencv_videoio.dir/all' failed
make[1]: *** [modules/videoio/CMakeFiles/opencv_videoio.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....

这种报错大概率是ffmpeg不支持fPIC导致的。
可能需要重新安装x264ffmpeg

1.安装x264

ftp://ftp.videolan.org/pub/videolan/x264/snapshots/
然后下载最新版解压

1
2
3
./configure --enable-static
make
sudo make install

即可

2.安装ffmpeg

从官网下载最新源码,解压。
http://ffmpeg.org/
然后

1
2
3
./configure --enable-nonfree --enable-pic --enable-shared
make -j4
sudo make install

即可。
不过ffmpeg编译也很慢 和CV用时差不多。

7.树莓派直接cmake安装后 VideoCapture无法读取视频文件和视频流的问题

cap.open(“Flie or Video Stream”);
cap.isOpened() -> return false;

这种情况就是ffmpeg功能没有被使能的原因

输入

1
cmake -DFFMPEG=1 -DWITH_OPENCL=1 -DOPENCV_GENERATE_PKGCONFIG=ON ..

查看cmake log

1
-- FFMPEG is disabled. Required libraries: libavcodec;libavformat;libavutil;libswscale. Missing libraries: libavcodec;libavformat;libavutil;libswscale

如果是树莓派的话, 这几个依赖都是可以apt直接安装的
eg:

1
apt search libavcodec

然后

1
2
3
4
Sorting... Done
Full Text Search... Done
libavcodec-dev/testing 7:4.1.6-1~deb10u1+rpt1 armhf
FFmpeg library with de/encoders for audio/video codecs - development fi
1
apt-get install libavcodec-dev

然后把所有Missing安装完毕重新cmake即可。

0.其他未知情况

仍然不行的话 可以尝试去Stackoverflow去搜索一下报错内容。
https://stackoverflow.com/

OpenCV安装选项

咕咕咕

安装

1
sudo make install

打包备份

如果你像我一样踩坑被坑三天的话,那我觉得你最好也像我一样给build目录打个包备份一下

1
2
cd .. #退出build目录
tar -czvf /你的目录/OpenCV.tar.gz build

emmm…这个就是我上篇文章说的要做的东西的一部分,但是远远不是全部。

测试

1
g++ input.cpp -o output `pkg-config --cflags --libs opencv4` -std=c++11

有些g++编译器默认不开启C++ 11标准 所以需要手动开启

1
.\output

可能会报错:

1
libopencv_highgui.so.4.3: cannot open shared object file: No such file or directory

此时则需要

1
nano /etc/ld.so.conf.d/opencv4.conf

1
/usr/local/lib

写入进去, 然后

1
ldconfig