OpenCV\_CUDA環境搭建
Linux
更推薦在Linux上部署,一些深度學習的東西,在Linux上的運行速度要明顯遠遠高於Windows。
如果你沒有空閒硬盤裝Linux了,可以考慮WSL2(在Windows上運行的Linux子系統2),雖有一點點性能損失,但速度也遠遠高於Windows。
WSL2安裝教程Vinci機器人隊Linux入門教程
實體機Linux**>WSL2>>**Windows
關於cv_bridge:最好在安裝ros之前編譯opencv,這樣安裝ros時,cv_bridge就會自己指向已經安裝過的opencv,並且ros不會另外安裝opencv,如此就可以通過find_package指令找到電腦上僅有的cv_bridge和opencv,保證系統環境不被汙染。關於補救辦法,請看常見問題

保證顯卡正常
請確保 英偉達驅動、CUDA、cuDNN 全部安裝成功並且版本正確。
(安裝驅動、CUDA、cuDNN教程:Vinci機器人隊Linux入門教程)
# 检查显卡驱动
nvidia-smi
# 验证CUDA是否安装成功
nvcc -V
# 检查cuDNN版本命令(仅仅只是查了头文件)
cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2
出現下圖這樣的,則你是有英偉達驅動,CUDA以及cuDNN的


安裝依賴項
# Debian系系统
sudo apt install -y libcurl4 build-essential pkg-config cmake-gui \
libopenblas-dev libeigen3-dev libtbb-dev \
libavcodec-dev libavformat-dev \
libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev \
libswscale-dev libgtk-3-dev libpng-dev libjpeg-dev \
libcanberra-gtk-module libcanberra-gtk3-module libv4l-dev python3-dev python3-numpy
# RHEL红帽系系统
bash -c 'sudo dnf install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm'
sudo dnf install -y curl gcc gcc-c++ make cmake cmake-gui \
openblas-devel eigen3-devel tbb-devel \
ffmpeg-libs ffmpeg-devel \
gstreamer1-plugins-base-devel gstreamer1-devel \
gtk3-devel libpng-devel libjpeg-devel \
libc=aanberra-gtk3 libcanberra-devel v4l-utils v4l2loopback openexr-devel python3-dev python3-numpy
下方表格是這些依賴的說明
| 生成 OpenCV 的主要依賴項 |
|---|
| 名稱 |
| 編譯系統 |
| 圖像庫 |
| OpenBLAS |
| Eigen3 |
| Intel TBB |
| FFMPEG |
| GStreamer |
| GTK |
| Video4Linux |
下載OpenCV源碼
https://github.com/opencv/opencv
https://github.com/opencv/opencv\_contrib


# 创建文件夹存放源码
mkdir -p ooppccvv
cd ooppccvv

# 解压源码
unzip ./opencv-4.11.0.zip
unzip ./opencv_contrib-4.11.0.zip

確認一下 opencv 目錄和 opencv-contrib 目錄位於相同的父目錄內,並確認這兩個目錄下都存在 modules 子目錄:(一般不用確認,只要你照著敲我上方的命令,一定沒問題)


CMake編譯
準備工作
# 创建build文件夹用于装CMake生成的内容:
cd opencv-4.11.0
mkdir -p build && cd build

OpenCV使用CMake與Makefile進行編譯,編譯選項較多,詳見(也可以不看,不過不同版本有些CMake編譯選項是不同的):
https://docs.opencv.org/4.10.0/db/d05/tutorial\_config\_reference.html
下方被劃掉的是在OpenCV4.11.0中已經不復存在的參數,但是可能在其他版本的OpenCV中仍有效,請自行用CMake-LAH(不推薦)命令或者CMake-gui(推薦)查看。
| OpenCV4.11.0 CMake常用編譯選項表一覽 |
|---|
| 序號 |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
| 11 |
| 12 |
| 13 |
| 14 |
| 15 |
| 16 |
| 17 |
| 18 |
| 19 |
| 20 |
| 21 |
| 22 |
| 23 |
| 24 |
| 25 |
| 26 |
| 27 |
| 28 |
| 29 |
| 30 |
| 31 |
| 32 |
| 33 |
- 查詢GPU Compute Capability(CUDA_ARCH_BIN參數):
https://developer.nvidia.com/cuda-gpus#collapseOne
進入網站後,
GeForce代表英偉達遊戲系列顯卡,常見的有GTX1080,RTX3080,RTX 4080等。
Jetson代表工控機序列顯卡。

我是3060Laptop(筆記本移動端顯卡,所以找右列的Notebook下方的3060)
如果你是3060(臺式桌面端,則要找左列的3060)
通過圖得知,我的顯卡算力(GPU Compute Capability)為8.6,所以我的CMake的CUDA_ARCH_BIN參數為8.6。
CUDA_ARCH_PTX為BIN的最高值,我只設置了一個BIN,所以最高值就是這個8.6。(只有你要給電腦更換顯卡的情況下,才要給BIN設置多個值,就需要把你要用的顯卡的值全包含在BIN中,而PTX只需要BIN的最高值即可)

- Python3的路徑查詢,請在終端中使用,檢查是否都有結果生成,確保打印出的結果符合預期後再進行下面的CMake生成操作。(不需要記住路徑)
當然你也可以用命令反饋出來的路徑複製出來,這個路徑就是參數的值。
# Python3 C++接口库的路径
python3 -c "import sysconfig; from os.path import join; print(join(sysconfig.get_config_var('LIBDIR'), sysconfig.get_config_var('LDLIBRARY')))"
# Python3 矩阵库头文件的路径
python3 -c "import numpy; print(numpy.get_include())"
# OpenCV 的 Python3 包安装的路径。
python3 -c "import sysconfig; print(sysconfig.get_path('purelib'))"
# Python3 头文件的路径
python3 -c "import sysconfig; print(sysconfig.get_path('include'))"
CMake編譯**(兩種方式選其一)**
因為電腦配置的不同,每個電腦的硬件,軟件(依賴包)等都不同,所以我能跑起來的你不一定一下就能跑成功。
一般很難風調雨順,如果有問題及時去百度,谷歌,OpenCV論壇上找答案。
CMake終端命令方式(不建議,更建議用GUI的方式,這種終端的方式容易出奇奇怪怪的問題)
cmake .. -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DBUILD_SHARED_LIBS=ON \
-DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.11.0/modules \
-DOPENCV_ENABLE_NONFREE=ON \
-DBUILD_TESTS=ON \
-DBUILD_PERF_TESTS=ON \
-DOPENCV_GENERATE_PKGCONFIG=ON \
-DWITH_GTK=ON \
-DWITH_CUDA=ON \
-DENABLE_FAST_MATH=ON \
-DCUDA_FAST_MATH=ON \
-DWITH_CUBLAS=ON \
-DCUDA_ARCH_BIN="8.6" \
-DCUDA_ARCH_PTX="8.6" \
-DCUDA_HOST_COMPILER=/usr/bin/gcc-13 \
-DWITH_CUDNN=ON \
-DOPENCV_DNN_CUDA=ON \
-DWITH_IPP=ON \
-DWITH_TBB=ON \
-DWITH_OPENMP=ON \
-DWITH_PTHREADS_PF=ON \
-DOPENCV_PYTHON3_VERSION=3.12 \
-DPYTHON3_EXECUTABLE=/usr/bin/python3 \
-DPYTHON3_LIBRARY=$(python3 -c "import sysconfig; from os.path import join; print(join(sysconfig.get_config_var('LIBDIR'), sysconfig.get_config_var('LDLIBRARY')))") \
-DPYTHON3_NUMPY_INCLUDE_DIRS=$(python3 -c "import numpy; print(numpy.get_include())") \
-DPYTHON3_PACKAGES_PATH=$(python3 -c "import sysconfig; print(sysconfig.get_path('purelib'))") \
-DPYTHON3_INCLUDE_DIR=$(python3 -c "import sysconfig; print(sysconfig.get_path('include'))") \
-DWITH_OPENGL=ON


你可以根據你的需要,按照之前的說明來自行增減或修改這些選項。如果 cmake 命令出錯,往往是缺少依賴項或配置的生成選項不正確所致,可根據提示信息來檢查。如果執行成功,就可以進行編譯(請看Makefiles編譯部分)了:
CMake-GUI方式(推薦,不過太麻煩,但是問題少,且更好找問題)
- 打開CMake-GUI:

配置一下這倆路徑

點擊左下角配置,選擇Makefiles

- 配置參數
根據上方表格去挨個參數進行配置。填完所有選項後,配置完畢點Configure.
在配置參數遇到問題,請看下面的常見問題章節。


你可以根據你的需要,按照之前的說明來自行增減或修改這些選項。如果 cmake 命令出錯,往往是缺少依賴項或配置的生成選項不正確所致,可根據提示信息來檢查。如果執行成功,就可以進行編譯(進行Makefiles編譯)了:


常見問題
####### 無CUDA選項 有時候CMake-GUI只會在編譯後才顯示某些參數(比如只有編譯過WITH_CUDA才會顯示CUDA相關的選項)。
所以你需要先把WITH_CUDA打上勾,再點左下角的config,這樣才會出現和CUDA相關的選項,再把那些選項配置一下。

####### 模組的路徑與命令行方式不同
需要注意的是,這個相對路徑與直接敲CMake命令配置的參數不同,這裡是../opencv_contrib-4.11.0/modules。

####### OPENCV_PYTHON3_VERSION參數的類型錯了 在cmake-gui中不知道為何OPENCV_PYTHON3_VERSION參數的類型成了布爾型。
需要手動改為字符串型數據。

上圖就是問題所在,這裡竟然是個布爾值。
先刪掉該選項。

再重新添加一個該選項。

# 查看python3版本
python3 --version

在下面填上3.12,後面的小版本號不用填。

Makefiles編譯
後面 -j 參數的意義是使用所有 CPU 參與編譯。如果啟用了 CUDA ,生成過程會比較慢,請耐心等待。編譯期間如果出錯往往是編譯器、系統庫、三方庫的版本兼容性問題,找問題的難度偏大。
請在build目錄下進行下方命令。
# 内存小于16GB
make all
# 内存等于16GB
make all -j$(( $(grep -c ^processor /proc/cpuinfo) / 2 ))
# 内存大于32GB
make all -j$(grep -c ^processor /proc/cpuinfo)
# 或者自行规定线程数量(比如16线程)
make all -j16

全核跑編譯

如圖才是真編譯成功,沒有錯誤。

生成結束後,執行以下命令進行安裝:
$(grep -c ^processor /proc/cpuinfo)變量為CPU線程的數量。(這樣可以使CPU全力多線程進行編譯)
# 内存小于16GB
sudo make install
# 内存等于16GB
sudo make install -j$(( $(grep -c ^processor /proc/cpuinfo) / 2 ))
# 内存大于32GB
sudo make install -j$(grep -c ^processor /proc/cpuinfo)
# 或者自行规定线程数量(比如16线程)
sudo make install -j16

無報錯則安裝成功

配置OpenCV環境變量ENV
- 可能需要配置一下lib的路徑:
vim ~/.bashrc
在最底下加上下方的內容
# 设置 LD_LIBRARY_PATH
export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
- 其他的不用配置,開箱即用(可以配置一下pkg-config),
檢查是否安裝成功:
opencv_version

測試OpenCV_CUDA(CMake程序示例)
- CMake是一定要掌握的,請看下方文檔學習:CMake C/C++編譯環境配置
- 如圖測試完畢:

- 下方是實例工程我已上傳至GitHub供大家下載:(下方示例工程裡的CMake模板不是最新的,可能不如新版功能齊全,不如新版各方面設計的更周到,如果想找最新版模板請看CMake C/C++編譯環境配置)
https://github.com/tungchiahui/opencv\_cuda\_test
# 克隆源码
git clone https://github.com/tungchiahui/opencv_cuda_test.git
# cd进工程
cd opencv_cuda_test
# cd进build目录
cd build
# 进行cmake编译
cmake ..
# 进行make编译+进行make install安装(最大线程)
make install -j$(grep -c ^processor /proc/cpuinfo)
# 给予脚本执行权限
sudo chmod a+x ../script/setup_vinci_emis.bash
sudo chmod a+x ../script/vinci_emis
sudo chmod a+x ../install/.setup.bash
# 执行环境脚本
source ../script/setup_vinci_emis.bash
# 执行demo1二进制程序
../script/vinci_emis run demo1
或者直接點擊Run,Start Debugging或者Run Without Debugging都可以。(已經將launch.json及task.json全部配置好了)(發現bug及時call我,call我之前,請看最新CMake模板是否已經修復了該bug,若未修復,再call我)


測試完畢

常見問題
cmake -jx編譯遇到operator!=或權重weight相關問題
這個問題大多發生在ubuntu20.04或者cuda12.2上,編譯時添加contrib庫,對應ros版本為noetic,opencv版本為4.8.0。
github上的討論:
https://github.com/ros-perception/vision\_opencv/tree/kinetic
根據GitHub中的解決方案,將對應報錯.hpp文件中的相應代碼修改(若只是有一些WARNING那大可不必修改):
114 opencv/modules/dnn/src/cuda4dnn/primitives/normalize_bbox.hpp 中 if (weight != 1.0)改為 if (weight != static_cast<T>(1.0))
124 opencv/modules/dnn/src/cuda4dnn/primitives/region.hpp 中if (nms_iou_threshold > 0)
改為 if (nms_iou_threshold > static_cast<T>(0))
再次編譯
make -j16
ros原裝opencv與自己搭建的opencv_cuda衝突的問題
原因:ros自帶的cv_bridge自動鏈接ros的opencv,而ros自帶的opencv沒有cuda加速,故報錯。
Ubuntu允許多版本 opencv共存,不建議直接卸載opencv,可能導致相關環境異常。
解決方案:額外配置一個版本的cv_bridge進行opencv的鏈接
ROS1
解決方案:
在https://github.com/ros-perception/vision\_opencv/tree/kinetic中下载对应版本的cv\_bridge
先對cv_bridge中的CmakeList.txt進行修改,OpencvDIR對應自己的opencv安裝路徑,並將修改包名:
project(cv_bridge_480)#修改为你的包名,加个版本号就可以
set(OpenCV_DIR "/home/liu/opencv/opencv-4.8.0")
find_package(OpenCV 4.8.0 REQUIRED
COMPONENTS
opencv_core
opencv_imgproc
opencv_imgcodecs
CONFIG
)
修改package.xml中的包名
<name>cv_bridge_480</name>
此時將cv_bridge作為一個ros功能包進行編譯,把包整體複製進你工作空間的src中進行編譯
cp -rf ./cv_bridge ~/Yolo_Tensorrt_Demo/demo01_test/src
catkin_make
然後就可以將cv_bridge作為功能包使用了,在你原本的包CmakeLists中添加
find_package(cv_bridge_480)
package.xml:
<build_depend>cv_bridge_480</build_depend>
<build_export_depend>cv_bridge_480</build_export_depend>
<exec_depend>cv_bridge_480</exec_depend>
到這裡自定義的cv_bridge包就配好了
如果你還想在vscode中使用代碼補全,添加路徑一直到cv_bridge包的include就可以,我這裡是另一個工作空間,都一樣。
"includePath": [
"/home/liu/cv_bridge_ws/src/cv_bridge/include",
"/home/liu/cv_bridge_ws/src/cv_bridge"
]
ROS2
詳見ROS2機器人操作系統教程中CV_Bridge章節.
opencv編譯爆內存的問題
解決方案:採用多核編譯,一般採用make -j16 (這裡16是CPU線程數,可以根據實際情況進行調整)即可解決,cpu線程越多,編譯速度就越快
windows中:
Mingw:
mingw64-make -j16
值得注意的是,mingw並不支持windows上的opencv_contrib編譯,這在configure一開始就會提示
Vs:
https://blog.csdn.net/hollyholly5/article/details/68062513
linux中:
make -j$(grep -c ^processor /proc/cpuinfo)