一、编译opencv4.5的步骤
1、安装依赖项
sudo apt update
sudo apt install build-essential cmake git pkg-config \
libjpeg-dev libtiff-dev libpng-dev \
libavcodec-dev libavformat-dev libswscale-dev \
libv4l-dev libxvidcore-dev libx264-dev \
libgtk-3-dev libatlas-base-dev gfortran \
python3-dev python3-numpy \
libdc1394-22-dev libopenblas-dev \
liblapack-dev libhdf5-dev libprotobuf-dev \
protobuf-compiler libgoogle-glog-dev \
libgtest-dev libtbb2 libtbb-dev
2、下载OpenCv源代码
cd ~
git clone -b 4.5.0 https://github.com/opencv/opencv.git
git clone -b 4.5.0 https://github.com/opencv/opencv_contrib.git
3、创建构建目录
cd ~/opencv
mkdir build
cd build
4、使用cmake配置构建
cmake -DOPENCV_EXTRA_MODULES_PATH=~/edcc/opencv_contrib/modules -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local ..
5、编译Opencv
make -j$(nproc)
-j$(nproc)
表示使用所有可用的处理器核心进行并行编译,提高编译速度。
6、安装OpenCv
sudo make install
7、更新库缓存
sudo ldconfig
8、验证安装
import cv2
print(cv2.__version__)
二、出现的问题
错误1
在opencv的构建过程中,在第5步进行编译的时候,出现了下面的问题。
In file included from /mnt/c/Users/AppData/Local/anaconda3/Library/include/hdf5.h:21,
from /home/user/edcc/opencv_contrib/modules/hdf/src/hdf5.cpp:37:
/mnt/c/Users/AppData/Local/anaconda3/Library/include/H5public.h:285:19: error: conflicting declaration ‘typedef long long int ssize_t’
285 | typedef long long ssize_t;
| ^~~~~~~
In file included from /usr/include/stdlib.h:395,
from /usr/include/c++/11/cstdlib:75,
from /usr/include/c++/11/stdlib.h:36,
from /usr/lib/gcc/x86_64-linux-gnu/11/include/mm_malloc.h:27,
from /usr/lib/gcc/x86_64-linux-gnu/11/include/xmmintrin.h:34,
from /usr/lib/gcc/x86_64-linux-gnu/11/include/emmintrin.h:31,
from /home/user/edcc/opencv/modules/core/include/opencv2/core/cv_cpu_dispatch.h:33,
from /home/user/edcc/opencv/modules/core/include/opencv2/core/cvdef.h:343,
from /home/user/edcc/opencv/modules/core/include/opencv2/core.hpp:52,
from /home/user/edcc/opencv_contrib/modules/hdf/src/precomp.hpp:38,
from /home/user/edcc/opencv_contrib/modules/hdf/src/hdf5.cpp:35:
/usr/include/x86_64-linux-gnu/sys/types.h:108:19: note: previous declaration as ‘typedef __ssize_t ssize_t’
108 | typedef __ssize_t ssize_t;
| ^~~~~~~
make[2]: *** [modules/hdf/CMakeFiles/opencv_hdf.dir/build.make:76: modules/hdf/CMakeFiles/opencv_hdf.dir/src/hdf5.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:3615: modules/hdf/CMakeFiles/opencv_hdf.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
这个问题是,两份头文件中对‘ssize_t’的定义出现了冲突,一份头文件是在windows环境下,另一份头文件是在wsl环境下的Ubuntu中。
问题:
为什么在wsl环境下Ubuntu中conda独立的环境下进行编译,会涉及到windows下的内容?
/mnt/c/Users/AppData/Local/anaconda3/Library/include/hdf5.h:22,
这个路径是在windows下的conda中
/home/user/opencv_contrib/modules/hdf/src/hdf5.cpp:37:
这个路径是在wsl环境下建立的一个ubuntu环境中
原因:
一个原因是,在 WSL(Windows Subsystem for Linux)环境中编译时引用 Windows 路径的问题,通常与以下几个因素有关:
1. 环境变量配置:
编译过程中,特别是使用 CMake、Makefile 或其他构建工具时,环境变量(特别是 PATH、C_INCLUDE_PATH 和 CPLUS_INCLUDE_PATH)的配置可能会包含 Windows 的路径。这会导致编译器优先查找 Windows 下的库或头文件。
1. 检查和修改环境变量:
在 WSL 环境中,确保没有设置指向 Windows 的环境变量。可以通过命令行检查:
echo $PATH
下面是检查的结果
echo $PATH
/home/user/anaconda3/envs/edcc/bin:/home/user/anaconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/mnt/c/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.8/bin:/mnt/c/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.8/libnvvp:/mnt/c/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.8/extras/CUPTI/lib64:/mnt/c/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.8/cudnn/bin:/mnt/c/Program Files/Microsoft MPI/Bin:/mnt/c/WINDOWS/system32:/mnt/c/WINDOWS:/mnt/c/WINDOWS/System32/Wbem:/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0:/mnt/c/WINDOWS/System32/OpenSSH:/mnt/c/Program Files/nodejs:/mnt/c/Program Files/Microsoft OLE DB Provider for DB2/System:/mnt/c/Program Files/PuTTY:/mnt/c/Program Files (x86)/NetSarang/Xshell 7:/mnt/c/Users/gjmhs4/Downloads/adb&&fastboot:/mnt/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/mnt/c/Program Files/CMake/bin:/mnt/c/Program Files (x86)/Windows Kits/10/Windows Performance Toolkit:/mnt/c/Program Files/Docker/Docker/resources/bin:/mnt/c/Program Files/NVIDIA Corporation/Nsight Compute 2021.1.0:/mnt/c/Users/gjmhs4/AppData/Local/anaconda3:/mnt/c/Users/gjmhs4/AppData/Local/anaconda3/Library/mingw-w64/bin:/mnt/c/Users/gjmhs4/AppData/Local/anaconda3/Library/usr/bin:/mnt/c/Users/gjmhs4/AppData/Local/anaconda3/Library/bin:/mnt/c/Users/gjmhs4/AppData/Local/anaconda3/Scripts:/mnt/c/Users/gjmhs4/AppData/Local/Continuum/anaconda3:/mnt/c/Users/gjmhs4/AppData/Local/Continuum/anaconda3/Library/mingw-w64/bin:/mnt/c/Users/gjmhs4/AppData/Local/Continuum/anaconda3/Library/usr/bin:/mnt/c/Users/gjmhs4/AppData/Local/Continuum/anaconda3/Library/bin:/mnt/c/Users/gjmhs4/AppData/Local/Continuum/anaconda3/Scripts:/mnt/c/Users/gjmhs4/AppData/Local/Microsoft/WindowsApps:/mnt/c/Program Files/JetBrains/PyCharm Community Edition 2022.1.2/bin:/mnt/c/Users/gjmhs4/AppData/Roaming/npm:/mnt/c/Users/gjmhs4/Downloads/bazel-5.4.1-windows-x86_64:/mnt/c/Users/gjmhs4/AppData/Local/Programs/Microsoft VS Code/bin:/mnt/c/Users/gjmhs4/AppData/Local/Programs/Git/cmd:/mnt/d/Downloads/platform-tools:/mnt/c/Users/gjmhs4/AppData/Roaming/Programs/Zero Install:/snap/bin
(edcc) user@DLJDM85M3:~/edcc/opencv/build$ echo $C_INCLUDE_PATH
这个/mnt/c/Program Files的路径就是在windows下的路径
理论解决办法:
为了去除环境变量中指向 Windows 下的路径,您可以按照以下步骤进行操作:
1、打开您的 Linux shell 或终端。
2、运行以下命令编辑您的环境变量文件(例如 .bashrc 或 .bash_profile):
nano ~/.bashrc
或
nano ~/.bash_profile
3、在打开的文件中,找到包含 Windows 路径的环境变量行。
4、将行的开头添加一个 #,将其注释掉。这将禁用该环境变量。
5、使用 Ctrl + X 保存并退出 Nano 编辑器。
6、运行 source ~/.bashrc 来使更改生效。
完成上述步骤后,Windows 路径将不再包含在您的环境变量中,从而避免了编译时引用 Windows 下的内容。
实际解决办法:
在打开的~/.bashrc文件中,并没有发现指向windows的路径
由于您提供的 ~/.bashrc 片段中没有直接显示 Windows 路径,通常这些路径是通过 export PATH 语句添加的。您需要在 .bashrc 文件中查找是否有 export PATH 相关的行,并将这些与 /mnt/c/ 开头的路径从 PATH 中移除。
若没有此类行,您可以手动创建一个新的 export PATH 行,但保留您想要保留的路径,类似于以下的方式:
把上面通过echo $PATH中显示出来的路径中,关于windows部分的路径去除,然后添加到.bashrc文件中。
export PATH="/home/user/anaconda3/envs/edcc/bin:/home/user/anaconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/snap/bin"
具体步骤:
1、使用 nano ~/.bashrc 打开 .bashrc 文件。
2、在文件中查找前面提到的带有 /mnt/c/ 的路径。
3、将这些行删除或注释掉。
4、如果需要,添加一行来设置 PATH,如上所示。
5、保存并退出 Nano(使用 Ctrl + X,然后选择 Y 确认保存)。
6、运行 source ~/.bashrc 来使更改生效。
根据您的情况,在将新的 export PATH 行添加到 .bashrc 文件时,通常最好将其放在文件的末尾。此行将确保您定义的路径被添加到系统的 $PATH 变量中,并且放在这个文件的末尾通常是一个很好的做法,因为这样不会干扰其他环境设置,并且能够保持整洁和清晰。
错误2
在解决头文件冲突的问题之后,再次进行编译出现了下面的问题
/home/user/edcc/opencv/modules/gapi/test/gapi_async_test.cpp: In member function ‘virtual void opencv_test::gtest_case_output_args_lifetime_::callback<gtest_TypeParam_>::TestBody()’:
/home/user/edcc/opencv/modules/gapi/test/gapi_async_test.cpp:448:26: error: ‘sleep_for’ is not a member of ‘std::this_thread’
448 | std::this_thread::sleep_for(std::chrono::milliseconds{2});
| ^~~~~~~~~
make[2]: *** [modules/gapi/CMakeFiles/opencv_test_gapi.dir/build.make:286: modules/gapi/CMakeFiles/opencv_test_gapi.dir/test/gapi_async_test.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
原因是
C++标准不匹配:std::this_thread::sleep_for 函数是 C++11 及以上版本的函数。如果您的编译选项未设置为使用 C++11 或更高版本,就会出现这个错误。
原来的cmake命令是
cmake -DOPENCV_EXTRA_MODULES_PATH=~/edcc/opencv_contrib/modules -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local ..
改为
cmake -DOPENCV_EXTRA_MODULES_PATH=~/edcc/opencv_contrib/modules -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_CXX_STANDARD=11 ..
然后再make -j8进行编译
错误3
又出现了同样的错误,
通过Google查找解决方案,
https://github.com/linuxdeepin/developer-center/issues/2314
然后降低了gcc版本,原先版本是11.4.0,降为10版本
然后再重新构建Opencv,构建成功。
解决问题的心得:感觉提出问题比解决问题更重要。提问的过程就是发现问题症结的过程,可能一个表象问题有不同的解决方案,但是究竟用哪一个还得对症下药。
20241014