老猿在自己国产统信操作系统的ARM主机上安装OpenCV,遇到了不少坑,在此记录供大家参考。
老猿安装的版本是OpenCV4.3.0,其他版本没用过,应该大部分情况相同。
机器源代码解压目录是/home/openCV
,解压的OpenCV文件在该目录的子目录OpenCV430下,最终编译成功的opencv库安装在/usr/local/opencv430目录下。
进入/home/openCV/OpenCV430
目录,执行命令:cmake .
结果报错,报错信息如下:
administrator@jwp:/home/openCV/OpenCV430$ cmake .
CMake Error at CMakeLists.txt:11 (message):
FATAL: In-source builds are not allowed.
You should create a separate directory for build files.
-- Configuring incomplete, errors occurred!
这说明cmake的执行必须单独建立一个目录才可以,为此在OpenCV文件根目录/home/openCV/OpenCV430
下新建一个子目录来进行cmake执行,为了易记,新建子目录命名为build,这样cmake就能正常执行了。
建立build子目录后,进入该子目录执行上述cmake指令,还是报同样的错误,这是因为上次执行遗留文件导致的,执行指令“rm ../CMakeCache.txt”
删除上层目录其下的文件:CMakeCache.txt 即可,此时可以执行cmake了。
ADE(Automatic Differentiation Engine)是OpenCV中的一个模块,用于自动计算图像处理算法的导数。它可以根据输入和输出之间的关系,自动计算算法的梯度,从而实现自动微分。在OpenCV的编译过程中,如果使用了gapi模块,会自动下载并编译ADE,以支持自动微分功能。
如果机器网络环境无法访问GitHub,则在执行cmake过程会报ADE下载失败,具体问题和解决办法请参考老猿在CSDN的博文《机器环境无法访问GitHub情况下linux安装OpenCV执行cmake无法下载ADE文件v0.1.1f.zip》的介绍。
执行cmake时报错:
Could NOT find JNI (missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY JAVA_INCLUDE_PATH JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH)。
这个错误意味着在执行cmake时,无法找到所需的JNI(Java Native Interface)库和路径。JNI是Java和本地代码(如C++)之间的接口,用于在Java中调用本地代码。对于编译OpenCV来说,如果不需要使用Java来调用OpenCV,这个错误可以忽略,不需要解决。但如果需要使用Java来调用OpenCV,你需要确保安装了Java Development Kit(JDK)并正确配置了相关的环境变量。可以按照以下步骤解决这个错误:
老猿没准备使用Java调用OpenCV,因此该错误就忽略了。
执行cmake时报错:
VTK is not found. Please set -DVTK_DIR in CMake to VTK build directory, or to VTK install subdirectory with VTKConfig.cmake file。
这个错误意味着在执行cmake时,无法找到VTK(Visualization Toolkit)库。VTK是一个用于可视化和图形处理的开源库。对于编译OpenCV来说,如果不需要使用VTK相关的功能,这个错误不会对编译过程产生影响。但如果需要使用VTK相关的功能,就需要解决这个错误才能成功编译OpenCV。
解决这个错误的方法是设置-DVTK_DIR选项,指定VTK的构建目录或VTK安装目录中的VTKConfig.cmake文件。
老猿暂时对VTK不了解,先忽略这个错误了。
在Windows版本的OpenCV中,库文件命名为opencv_worldXXX.lib,其中XXX代表OpenCV的版本号。这是因为Windows下的编译器(如Visual Studio)需要将所有的OpenCV模块链接到一个单独的库文件中,以便于在编译和链接过程中使用。这个单独的库文件包含了OpenCV的所有功能和模块,因此被称为opencv_world.lib。
而在Linux版本的OpenCV中,库文件的命名方式不同。Linux下的编译器使用动态链接库(.so文件)来链接OpenCV的模块,每个模块都有自己的动态链接库文件。这种方式可以减小可执行文件的大小,并且在运行时可以根据需要加载所需的模块。
因此,Windows版本的OpenCV使用单个库文件来包含所有模块,而Linux版本的OpenCV使用多个动态链接库文件来分别包含各个模块。
如果编写好了应用程序,要使用opencv动态库时,动态库名称和文件名的对应关系为:动态库文件名=“lib”+库名+“.so”,如库名为“opencv_core”,则动态库文件名为:“liblopencv_core.so”,其中的库名就是编译时用l指定的库名,如使用opencv_core等库时,编译指令样例如下:
g++ test.cpp -o test -I/usr/local/opencv430/include/opencv4 -L/usr/local/opencv430/lib -lopencv_core -lopencv_highgui -lopencv_imgcodecs
注意:这个指令用了-I和-L参数,实际上可以通过其他设置方法去除这2个参数,具体请参考下面这个问题的解决介绍。
这个问题请参考老猿在CSDN的博文《统信UOS linux下opencv应用编译时的头文件和库文件路径查找设置方法》的介绍。
已经在机器上编译好opencv应用程序test,连接了相关动态库如libopencv_core,执行时报错:
administrator@jwp:~/E_DRIVER/opencv/test$ ./test
./test: error while loading shared libraries: libopencv_core.so.4.3: cannot open shared object file: No such file or directory
administrator@jwp:~/E_DRIVER/opencv/test$
这是因为动态库路径没有设置的,动态库运行时路径设置是由环境变量LD_LIBRARY_PATH来设置,可以在终端上执行如下指令来设置,以老猿机器环境为例:
export LD_LIBRARY_PATH=/usr/local/opencv430/lib
执行成功后再执行测试程序就正常了,不过这种终端方式设置环境变量的方式在终端退出后就失效了,要长期有效就必须在登录用户的shell配置文件中来配置,在统信操作系统的Bash shell环境下,修改在登录用户的主目录下(/home/登录用户名)的隐藏文件.bashrc文件,在其中增加一行:export LD_LIBRARY_PATH=/usr/local/opencv430/lib:$LD_LIBRARY_PATH
即可。
注意:
LD_LIBRARY_PATH和LIBRARY_PATH都是Linux下的环境变量,用于指定共享库的搜索路径。它们的主要区别在于作用范围和优先级。
LD_LIBRARY_PATH是一个运行时环境变量,用于指定程序在运行时搜索共享库的路径。当程序需要加载共享库时,动态链接器会根据LD_LIBRARY_PATH的值来查找共享库。LD_LIBRARY_PATH的值是一个以冒号分隔的路径列表,可以包含绝对路径或相对路径。如果共享库不在标准的搜索路径中,可以将其所在的路径添加到LD_LIBRARY_PATH中。
LIBRARY_PATH是一个编译时环境变量,用于指定编译器在编译时搜索共享库的路径。当编译器在编译过程中需要链接共享库时,会根据LIBRARY_PATH的值来查找共享库。LIBRARY_PATH的值也是一个以冒号分隔的路径列表,可以包含绝对路径或相对路径。如果共享库不在标准的搜索路径中,可以将其所在的路径添加到LIBRARY_PATH中。
在执行编译好的应用程序时,报异常:error: (-2:Unspecified error) The function is not implemented,以老猿的测试案例为例,完整报错信息如下:
administrator@jwp:~/E_DRIVER/opencv/test$ export LD_LIBRARY_PATH=/usr/local/opencv430/lib
administrator@jwp:~/E_DRIVER/opencv/test$ ./test
terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(4.3.0) /home/openCV/OpenCV430/modules/highgui/src/window.cpp:634:
error: (-2:Unspecified error) The function is not implemented.
Rebuild the library with Windows, GTK+ 2.x or Cocoa support.
If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, t
hen re-run cmake or configure script in function 'cvNamedWindow'
已放弃
administrator@jwp:~/E_DRIVER/opencv/test$
碰到这个问题,表明opencv安装前,没有安装好相关依赖的库,这时候只有在先卸载已经安装的opencv,再安装这些依赖库之后,重新执行opencv的安装过程。
应该在进行cmake前执行相关依赖库的安装,具体涉及依赖库包括如下:
sudo apt install build-essential
sudo apt install libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libdc1394-22-dev
apt install libjasper-dev
sudo apt install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev liblapacke-dev
sudo apt install libxvidcore-dev libx264-dev
sudo apt install libatlas-base-dev gfortran
sudo apt install ffmpeg
这里补充说明几点:
1、依赖库的安装必须在执行opencv安装的cmake之前;
2、这里列出了所有应该提前安装的库,但可能有部分库已经存在了,例如ffmpeg在老猿机器上原来就有,另外有部分库可能统信没有,如在老猿机器上安装libjasper-dev就报错:
dministrator@jwp:~/E_DRIVER/opencv/test$ sudo apt install libjasper-dev
请输入密码:
验证成功
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
E: 无法定位软件包 libjasper-dev
libjasper-dev是一个用于处理图像压缩和解压缩的库。它提供了对JPEG-2000图像格式的支持。libjasper-dev库包含了用于开发的头文件和静态库文件。没找到该文件不知道是由于老猿机器硬件的原因还是统信不支持。
我们知道gcc主要用于编译C语言程序,而g++主要用于编译C++语言程序,但gcc也可以编译c++程序。
对于后缀为.cpp的文件,gcc和g++都将其视为C++文件进行编译。
不同的是对于后缀为.c的文件,gcc将其视为C语言文件进行编译,而g++将其视为C++文件进行编译。
由于C++相对于C语言具有更多的功能和特性,因此使用g++来编译.cpp文件可以更好地支持C++的语法和库。
因此也可以尝试使用gcc来编译opencv的应用,但直接将编译指令中的g++改为gcc来执行的话,会报错。
以老猿的测试程序编译为例:
administrator@jwp:~/E_DRIVER/opencv/test$ g++ test.cpp -o test -lopencv_core -lopencv_highgui -lopencv_imgcodecs
administrator@jwp:~/E_DRIVER/opencv/test$ gcc test.cpp -o test -lopencv_core -lopencv_highgui -lopencv_imgcodecs
/usr/bin/ld: /tmp/cc6IVZeh.o: undefined reference to symbol '_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3'
/usr/bin/ld: //lib/aarch64-linux-gnu/libstdc++.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
administrator@jwp:~/E_DRIVER/opencv/test$
这个错误是由于gcc编译代码进行连接时,缺少链接到libstdc++库引起的,stdc++库是C++标准库的一部分,提供了许多用于C++编程的函数和类,包含了C++语言的核心特性。而gcc是不会连接该库的,在使用gcc编译C++代码时,需要手动添加对C++标准库的链接参数-lstdc++。
因此需要将指令进行修改为:
gcc test.cpp -o test -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs -lstdc++
本文详细介绍了在统信UOS的linux操作系统环境下安装opencv库和构建opencv C++应用的编译环境过程中遇到的各种问题,通过解决这些问题,就可以最终成功安装opencv库和执行opencv C++应用的编译和测试了。具体安装步骤请参考老猿在CSDN的博文《信创之国产浪潮电脑+统信UOS操作系统体验11:统信UOS Linux下绕开github下载和编译OpenCV并构建C++应用编译环境的过程详解》的介绍。
如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!
更多关于统信操作系统及opencv的介绍的内容请参考专栏《国产信创之光》的其他文章。
前两个专栏都适合有一定Python基础但无相关知识的小白读者学习,第三个专栏请大家结合《https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python图形图像处理 》的学习使用。
对于缺乏Python基础的同仁,可以通过老猿的免费专栏《https://blog.csdn.net/laoyuanpython/category_9831699.html 专栏:Python基础教程目录)从零开始学习Python。
如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。