第 5 節

OpenCV\_CUDA環境搭建

0瀏覽次數0訪問次數--跳出率--平均停留

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
  1. 查詢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的最高值即可)

  1. 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論壇上找答案。

論壇:https://forum.opencv.org/

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方式(推薦,不過太麻煩,但是問題少,且更好找問題)
  1. 打開CMake-GUI:

配置一下這倆路徑

點擊左下角配置,選擇Makefiles

  1. 配置參數

根據上方表格去挨個參數進行配置。填完所有選項後,配置完畢點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

  1. 可能需要配置一下lib的路徑:
vim ~/.bashrc

在最底下加上下方的內容


# 设置 LD_LIBRARY_PATH
export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
  1. 其他的不用配置,開箱即用(可以配置一下pkg-config),

檢查是否安裝成功:

opencv_version

測試OpenCV_CUDA(CMake程序示例)

  1. CMake是一定要掌握的,請看下方文檔學習:CMake C/C++編譯環境配置
  2. 如圖測試完畢:

  1. 下方是實例工程我已上傳至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

或者直接點擊RunStart 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)

Windows

詳見使用OpenCV推理Yolov8模型(C++)

音乐页