Darknet 的编译

YOLO 是基于 Darknet 框架,实现的一个神经网络物体分割识别器(Object Detection)。支持 CPU 和 GPU 运算,可以对各种物体实现分割与识别。

这里有从 CUDA 工具链的配置、OpenCV 的编译、Darknet 的编译全流程记录。

编译和安装比较复杂,一方面是 CUDA 容易配置错,另一方面是 OpenCV 不好编译。

需要一点耐心,和一点摸鱼(编译时间比较久)。

Darknet 官方文档:
Darknet: Open Source Neural Networks in C (pjreddie.com)

整个编译流程如下:

流程 说明
WSL 配置基础工作环境(Ubuntu)
CUDA 安装显卡驱动,和配置 CUDA 编译工具链
cuDNN CUDA 神经网络加速器
OpenCV C++ 编写的视觉图形库
OpenCV-CUDA OpenCV 的 CUDA 加速
Darknet Darknet 框架的编译

快速使用

非常简单,采用纯 CPU 运算,几行命令就能完成编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 安装 Python
sudo apt install python3 python3-pip

# 安装 Python OpenCV
pip install opencv-python

# 下载
git clone https://github.com/pjreddie/darknet.git && cd darknet

mkdir build && cd build

# 配置(禁用 CUDA)
cmake .. -DENABLE_CUDA=OFF

# 编译
cmake --build . --target install --parallel 8

Windows 下可能遇到的问题:如果 opencv-python 安装失败,是因为新版本 Python 没有 OpenCV 的已编译版本,而现有系统上没有编译的结果。省事的话,直接降低 Python 版本,再重新用 pip 安装即可。

参考环境

  1. Windows 11/10(建议)

    推荐采用 Windows + WSL Ubuntu 22.04
    物理机参考内存 16GB+,空间 40GB+

  2. WSL Ubuntu22.04

    不建议用虚拟机,特别是没有显卡直通的

  3. Ubuntu 22.04(可选)

    直接物理机使用 Ubuntu 也可以,需要安装显卡驱动

  4. 流畅的网络

    需要下载的东西非常大,总大小在 8GB 以下

  5. NVIDIA 显卡

    GeForce GTX 660 和 Tesla K10 以上的显卡才能够正常运行
    只是能编译的最低要求,按照这个配置不一定能跑

完整编译流程

目前 YOLO 可以从着两个下:

作者 仓库 备注
pjreddie pjreddie/darknet 原版
AlexeyAB AlexeyAB/darknet: YOLO 优化后,多平台

后面采用 AlexeyAB 的库进行编译和测试:
AlexeyAB/darknet: Neural Networks for Object Detection)

Windows 下编译特别提示!

AlexeyAB 这个库可以在 Windows 下进行编译。

CUDA 12.x - 11.8 CUDA 11.7 - 11.0
Visual Studio 2019 2017

Support Matrix - NVIDIA Docs

如非必要,非常不推荐,容易遇到非常麻烦的事情。建议在虚拟机中编译,避免现有工作环境被破坏。

众所周知,Visual Studio 重装和卸载的唯一办法,就是重装系统。相比于常用作物理机的 Windows,最好是使用当作虚拟机的 Linux 发行版。

WSL

这是最简单的部分了

WSL - The Windows Subsystem for Linux,适用于 Linux 的 Windows 子系统,可以在 Windows 下便捷操作 Linux 系统。

Win + R 运行 PowerShell,确认系统版本:

1
2
# 查看系统 Build 版本
systeminfo | findstr "Build"
架构 最低要求
x86_64 Build 18362
arm64 Build 19041

Win + X 打开“终端管理员”,执行以下命令安装 WSL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 启用虚拟化平台
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform

# 启用 Windows 子系统
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

# 启用 WSL 2
wsl --set-default-version 2

# 安装 Ubuntu-22.04
wsl --install -d Ubuntu-22.04

# WSL 启动!
wsl

CUDA

CUDA - ComputeUnified Device Architecture 计算统一设备架构,是 NVIDIA 的 GPU 运行神经网络所必须的基础包。想要在 WSL 里进行开发,都需要安装 CUDA。

CUDA 和 显卡驱动都需要安装,首先在官网下载显卡驱动:

Official Drivers | NVIDIA

这里只用给 Windows 安装就行了

1
2
3
4
5
6
7
# 这里不一定对,需要手动去官网下载

# 在Linux 上安装(不要在 WSL 里面安装)
#wget "https://us.download.nvidia.com/XFree86/Linux-x86_64/535.86.05/NVIDIA-Linux-x86_64-535.86.05.run"

# 安装
#sudo sh NVIDIA-Linux-x86_64-535.86.05.run

CUDA 在 Linux 和 Windows 安装都比较简单,直接用选择对应系统版本安装即可:
CUDA Toolkit Downloads | NVIDIA Developer

Ubuntu deb 包参考大小:4.03GB,必须安装
Windows exe 包参考大小:3.16GB,可以不安装

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
# 这里不一定对,需要手动去官网下载

# runfile (local) 的方式下载,环境崩了好切换
#wget https://developer.download.nvidia.com/compute/cuda/12.2.1/local_installers/cuda_12.2.1_535.86.10_linux.run
#sudo sh cuda_12.2.1_535.86.10_linux.run

# keyring 方式
wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-keyring_1.1-1_all.deb

# 安装 cuda 的 密钥环
sudo dpkg -i cuda-keyring_1.1-1_all.deb

# 更新
sudo apt-get update

# 安装 cuda
sudo apt-get -y install cuda-12.1
# 这里必须 12.1,截至目前 cuDNN 只支持到这里
# 如果不清楚 cuDNN 适合的版本,可以一个个试

### 检查 CUDA 版本
#cat /usr/local/cuda/include/cuda.h | grep CUDA_VERSION

# 检查 CUDA 版本,以及 GPU 连接、运行状态
nvidia-smi
# 推荐用这个命令测试 CUDA 是否成功配置,显卡是否成功连上

# 这个是 cuda_11.5 的
#apt install nvidia-cuda-toolkit

WSL2 里面安装必须采用 Ubuntu 系统,具体的文档详见:

厂商 地址
Microsoft Enable NVIDIA CUDA on WSL 2 - Microsoft Learn
NVIDIA NVIDIA GPU Accelerated Computing on WSL 2

一般建议安装 Windows 版本的和 Linux -> WSL-Ubuntu 版本的 CUDA,确保两边都能吃上饭。

故障排除

除非操作失误,基本上遇不上故障

切换 CUDA 版本

如果安装错了版本,可以通过以下方法修改 CUDA 版本。

1
2
3
4
5
6
7
8
# 删除软链接
sudo rm /usr/local/cuda

# 链接到
sudo ln -s /usr/local/cuda-12.1 /usr/local/cuda

# 查看当前 cuda toolkits 版本
/usr/local/cuda/bin/nvcc --version

默认配置的是 /usr/local/cuda 这个软连接,作为 cuda 运行库的一切,换句话说,直接改这个软链接的指向就能修改运行时的 CUDA 版本

GPU 监视软件

这里的两个软件都是全平台支持的,其中 nvidia-smi 是只要安装了 CUDA,就能运行。因此也是测试 GPU 是否正常连接的命令。

nvidia-smi

参考输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
> nvidia-smi
Mon Aug 7 23:01:51 2023
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 530.30.02 Driver Version: 536.67 CUDA Version: 12.2 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 NVIDIA GeForce RTX xxx On | 00000000:01:00.0 On | Off |
| 0% 41C P8 17W / xxxW | xxxxxMiB / xxxxMiB | 1% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+

这里会显示具体的显卡型号,连上几张显示几张。

也可以看到当前正在使用的 CUDA 版本。

可以新开一个窗口/分屏,运行以下命令,实现刷新查看

1
watch -n 1 nvidia-smi
nvitop
1
pip install nvitop

参考输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> nvitop
Mon Aug 07 23:12:15 2023
╒═════════════════════════════════════════════════════════════════════════════╕
│ NVITOP 1.0.0 Driver Version: 536.67 CUDA Driver Version: 12.2 │
├───────────────────────────────┬──────────────────────┬──────────────────────┤
│ GPU Name Persistence-M│ Bus-Id Disp.A │ Volatile Uncorr. ECC │
│ Fan Temp Perf Pwr:Usage/Cap│ Memory-Usage │ GPU-Util Compute M. │
╞═══════════════════════════════╪══════════════════════╪══════════════════════╪════════════════════╕
│ 0 GeForce RTX xxxx On │ 00000000:01:00.0 On │ N/A │ MEM: ▉ 9.5% │
│ 0% 41C P8 xxxW / xxW │ xxxMiB / xxxxxxGiB │ 4% Default │ UTL: ▍ 4% │
╘═══════════════════════════════╧══════════════════════╧══════════════════════╧════════════════════╛
[ CPU: █▌ 3.1% ] ( Load Average: 0.12 0.04 0.14 )
[ MEM: ███ 5.9% ] [ SWP: ▏ 0.0% ]

╒══════════════════════════════════════════════════════════════════════════════════════════════════╕
│ Processes: aero@WIN-0CC5KNT6PM5 (WSL) │
│ GPU PID USER GPU-MEM %SM %CPU %MEM TIME COMMAND │
╞══════════════════════════════════════════════════════════════════════════════════════════════════╡
│ No running processes found (in WSL) │
╘══════════════════════════════════════════════════════════════════════════════════════════════════╛
1
watch -n 1 -c gpustat --color

cuDNN

cuDNN 是 NVIDIA 加速神经网络的库,在这里下载:

cuDNN Archive | NVIDIA Developer

下载前必须登录

选择对应系统 Ubuntu22.04 的 Deb 包下载进行安装:

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
# 这里的链接不对,需要手动去官网下载(必须登录)
wget https://developer.download.nvidia.com/compute/cudnn/secure/8.9.3/local_installers/12.x/cudnn-local-repo-ubuntu2204-8.9.3.28_1.0-1_amd64.deb?xxxxx

# 导入包
sudo dpkg -i cudnn-local-repo-ubuntu2204-8.9.3.28_1.0-1_amd64.deb

# 导入密钥
sudo cp /var/cudnn-local-repo-*/cudnn-local-*-keyring.gpg /usr/share/keyrings/

# 导入包
sudo dpkg -i cudnn-local-repo-ubuntu2204-8.9.3.28_1.0-1_amd64.deb

# 更新源
sudo apt-get update

# CUDA 版本,需要核对版本
cuda_version=cuda12.1
# cuDNN 版本,需要核对版本
cudnn_version=8.9.3.28
# 注意,这里不一定能用最新版的 CUDA,cuDNN 的适配可能落后于 CUDA
# 因此,提示找不到 libcudnn8 相关的软件包,一般是版本不适配

# 安装 cuDNN
sudo apt-get install libcudnn8=${cudnn_version}-1+${cuda_version}
sudo apt-get install libcudnn8-dev=${cudnn_version}-1+${cuda_version}
sudo apt-get install libcudnn8-samples=${cudnn_version}-1+${cuda_version}

# 检查 cuDNN 版本
/usr/local/cuda/bin/nvcc --version

输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
> sudo dpkg -i cudnn-local-repo-ubuntu2204-8.9.3.28_1.0-1_amd64.deb
(Reading database ... 181369 files and directories currently installed.)
Preparing to unpack cudnn-local-repo-ubuntu2204-8.9.3.28_1.0-1_amd64.deb ...
Unpacking cudnn-local-repo-ubuntu2204-8.9.3.28 (1.0-1) over (1.0-1) ...
Setting up cudnn-local-repo-ubuntu2204-8.9.3.28 (1.0-1) ...

> /usr/local/cuda/bin/nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2023 NVIDIA Corporation
Built on Tue_Jul_11_02:20:44_PDT_2023
Cuda compilation tools, release 12.2, V12.2.128
Build cuda_12.2.r12.2/compiler.33053471_0

OpenCV

Open Source Computer Vision Library

OpenCV 比较难编译,如果编译失败,应该是依赖库出现问题,建议重装系统
在 Docker 的 Ubuntu 上平均 3 分钟可以完成编译,但是到了 WSL 的老开发环境(用了比较久的环境)上,就容易编译陷入死循环。

安装 OpenCV 后卸载比较麻烦。

官方文档里面的依赖库不是很全,大概率是没法编译的
OpenCV: Installation in Linux

手动编译

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
34
35
36
37
38
39
40
41
42
# 配置源
sudo sed -i "s|archive.ubuntu.com|mirrors.cloud.tencent.com|g" /etc/apt/sources.list

# 更新
sudo apt update

# 编译依赖
sudo apt install -y build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
# 可选用 ninja 进行编译,更快一点
#sudo apt install -y ninja-build
# 若采用 ninja,在后面只需要使用注释掉的,包含 ninja 的命令,不要用包含 cmake 或 make(除了cmake -GNinja )

# OpenCV 源码
git clone https://github.com/opencv/opencv.git && cd opencv

# 查看 OpenCV 版本

# 切换版本
git checkout 4.8.0

mkdir build && cd build
# 出现编译错误可以直接
# rm build -rf
# 然后重新开始这一步

# 配置
cmake ..
#cmake -GNinja ..

# 编译
cmake --build . -j$(nproc)
#ninja -j$(nproc)
# 若在 WSL 中编译,建议关掉所有浏览器,避免出现奇怪问题

# 如果一直编译错误,请不要使用多线程编译
# 这个时候建议用 ninja 来编译
# ninja
# 注意用 ninja 来编译,需要用到上面所有的注释过,包含 ninja 的命令,不要用包含 cmake 或 make(除了cmake -GNinja )

# 安装
sudo make install
#sudo ninja install

故障排除

OpenJPEG

如果出现出现找不到 openjpeg 之类的报错,有两个选择,这里推荐重新编译 openjpeg 的源码,避免出现更多的意外。

直接安装

1
sudo apt install libopenjp2-7 libopenjp2-tools

Installing OpenJPEG on Windows 10, Linux, and MacOS - Harvard Library Imaging Services - Harvard Wiki

手动编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
sudo sed -i "s|archive.ubuntu.com|mirrors.cloud.tencent.com|g" /etc/apt/sources.list

sudo apt install -y git cmake g++ wget unzip

# openjpeg
git clone https://github.com/uclouvain/openjpeg && cd openjpeg

mkdir build && cd build

# 配置
cmake .. -DCMAKE_BUILD_TYPE=Release

# 编译
sudo make -j$(nproc)

# 安装
sudo make install

# 提示 numpy 报错,需要安装以下依赖
#sudo apt liblcms2-dev libtiff-dev libpng-dev libz-dev

# 提示 python 库相关的报错,需要安装 Python
#sudo apt install -y python-is-python3 ffmpeg
#pip2 install numpy

OpenCV-CUDA

带 CUDA 加速的 OpenCV(可选)

这里不是 Darknet 运行所必须的。

前面的 OpenCV 不是这一步的编译依赖,如果要编译带 CUDA 的 OpenCV,务必从这里开始。

CUDA 和 cuDNN 都是这里的关键依赖,务必配置好正确的 CUDA。

需要从 Github 拉取大量文件,请确保网络状况良好。

唯一必要安装的是 python3。只要安装了,cmake 会自动配置好环境变量。

已经到这一步了,别想着卸载 OpenCV 了

手动编译

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# 确认 NVCC 编译器版本
/usr/local/cuda/bin/nvcc --version

# 确认 CUDA 版本
ls -lh /usr/local/cuda

# 确认 lib 版本
ls -lh /usr/local/cuda/lib64

# 如果这里的版本不对,务必回到前面修改 CUDA 版本
# 见:切换 CUDA 版本

# 导入环境变量
export CUDA_PATH=/usr/local/cuda/
export CUDACXX=/usr/local/cuda/bin/nvcc
export PATH=/usr/local/cuda/bin/:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64/

# 配置源
#sudo sed -i "s|archive.ubuntu.com|mirrors.cloud.tencent.com|g" /etc/apt/sources.list

# 更新
#sudo apt update

# 编译依赖
sudo apt install -y build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
# 务必 ninja,cmake 太慢了
sudo apt install -y ninja-build
# cmake 和 make 的多线程容易卡死 WSL

# OpenCV 源码
git clone https://github.com/opencv/opencv.git
# OpenCV 额外模块源码
git clone https://github.com/opencv/opencv_contrib.git

# 查看 opencv 和 opencv_contrib 的版本
git -C opencv_contrib/ tag --sort=-v:refname | head -n 10
git -C opencv_contrib/ tag --sort=-v:refname | head -n 10

# 切换版本
git -C opencv checkout 4.8.0
git -C opencv_contrib checkout 4.8.0

mkdir -p build && cd build
# 出现编译错误可以直接
# rm build -rf
# 然后重新开始这一步

# 目前目录结构如下
# HOME - 用户目录
# ├── build - 构建目录 <- 现在在这个里面
# ├── opencv - opencv 源码
# └── opencv_contrib - opencv 扩展模块

# 确定 显卡型号
nvidia-smi -L
# 等下,这也就意味着,不同型号的显卡得编译不同的库
# 这里的 CUDA_ARCH_BIN 需要查询对应显卡编号
# https://developer.nvidia.com/cuda-gpus#collapse4

# 配置
cmake ../opencv \
-GNinja \
-D OPENCV_EXTRA_MODULES_PATH=$(cd ../ && pwd)/opencv_contrib/modules \
-D WITH_CUDA=ON \
-D WITH_CUDNN=ON \
-D OPENCV_DNN_CUDA=ON \
-D BUILD_CUDA_STUBS=ON \
-D CUDA_ARCH_BIN=8.9 \
-D BUILD_opencv_cudaarithm=ON \
-D BUILD_opencv_cudabgsegm=ON \
-D BUILD_opencv_cudacodec=ON \
-D BUILD_opencv_cudafeatures2d=ON \
-D BUILD_opencv_cudafilters=ON \
-D BUILD_opencv_cudaimgproc=ON \
-D BUILD_opencv_cudalegacy=ON \
-D BUILD_opencv_cudaobjdetect=ON \
-D BUILD_opencv_cudaoptflow=ON \
-D BUILD_opencv_cudastereo=ON \
-D BUILD_opencv_cudawarping=ON

# 务必确保 CUDA_ARCH_BIN 填对!
# https://developer.nvidia.com/cuda-gpus#collapse4

# 这里的路径要稍微注意一下
# OPENCV_EXTRA_MODULES_PATH=

# 请不要在 NTFS 文件系统下编译,换句话说,请 cd ~ 回用户目录
# WSL 在 NTFS 文件系统下编译容易遇上 BUG

# 如果有安装到其他地方的需求,可以配置 DCMAKE_INSTALL_PREFIX
# cmake .. -DCMAKE_INSTALL_PREFIX=/<your_perfix>

# 编译
ninja
# 若在 WSL 中编译,建议关掉所有浏览器,避免出现奇怪问题

# 安装
sudo ninja install

故障排除

核查 GPU 情况
1
nvidia-smi -L
CUDA 与 cuDNN 的环境变量
1
2
3
4
export CUDA_PATH=/usr/local/cuda/
export CUDACXX=/usr/local/cuda/bin/nvcc
export PATH=/usr/local/cuda/bin/:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64/
核查 CUDA 环境
1
2
3
4
5
6
#ref: https://medium.com/@juancrrn/installing-cuda-and-cudnn-in-ubuntu-20-04-for-deep-learning-dad8841714d6
git clone https://github.com/NVIDIA/cuda-samples.git

(cd cuda-samples/Samples/1_Utilities/deviceQuery/ && make)

(cd cuda-samples/Samples/1_Utilities/deviceQuery/ && ./deviceQuery)

正常的输出,只要包含这部分:

1
2
3
4
5
  Compute Mode:
< Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 12.2, CUDA Runtime Version = 12.1, NumDevs = 1
Result = PASS
核查 cuDNN 环境
1
2
3
4
5
6
7
8
#ref: https://medium.com/@juancrrn/installing-cuda-and-cudnn-in-ubuntu-20-04-for-deep-learning-dad8841714d6

# 只是这里的依赖
sudo apt install libfreeimage3 libfreeimage-dev

cp -r /usr/src/cudnn_samples_v8/ ./
(cd cudnn_samples_v8/mnistCUDNN && make clean && make)
(cd cudnn_samples_v8/mnistCUDNN && ./mnistCUDNN)

正常的输出,只要包含这部分:

1
Test passed!
编译卡死

首先确认没有在 NTFS 文件系统下编译:

1
2
> pwd
/mnt/c/Users/z0xac

比方说这里就是在 NTFS 文件系统下编译。

除非采用单线程,否则几乎不可能编译通过。

需要先 cd ~ ,回到 Linux 用户的根目录才能正常编译:

1
2
3
> cd ~
> pwd
/home/z0xac
可选编译

如果在编译代码时,在以下任意一个报错 no found

1
2
3
4
5
6
7
8
9
10
11
cudaarithm.hpp
cudabgsegm.hpp
cudacodec.hpp
cudafeatures2d.hpp
cudafilters.hpp
cudaimgproc.hpp
cudalegacy.hpp
cudaobjdetect.hpp
cudaoptflow.hpp
cudastereo.hpp
cudawarping.hpp

就是因为编译的时候没有加可选编译,这些选择默认都是关闭的,需要逐个手动开启。

1
2
3
4
5
6
7
8
9
10
11
-D BUILD_opencv_cudaarithm=ON
-D BUILD_opencv_cudabgsegm=ON
-D BUILD_opencv_cudacodec=ON
-D BUILD_opencv_cudafeatures2d=ON
-D BUILD_opencv_cudafilters=ON
-D BUILD_opencv_cudaimgproc=ON
-D BUILD_opencv_cudalegacy=ON
-D BUILD_opencv_cudaobjdetect=ON
-D BUILD_opencv_cudaoptflow=ON
-D BUILD_opencv_cudastereo=ON
-D BUILD_opencv_cudawarping=ON

部分地方用不上专门的 CUDA 加速库,可以仅采用这一部分配置

1
2
3
4
5
6
7
8
cmake ../opencv \
-GNinja \
-D OPENCV_EXTRA_MODULES_PATH=$(cd ../ && pwd)/opencv_contrib/modules \
-D WITH_CUDA=ON \
-D WITH_CUDNN=ON \
-D OPENCV_DNN_CUDA=ON \
-D BUILD_CUDA_STUBS=ON \
-D CUDA_ARCH_BIN=8.9

注意 CUDA_ARCH_BIN 需要按照说明配置对。

CUDA_ARCH_BIN

关于 CUDA_ARCH_BIN ,可以在 CUDA 网站上找到对应的说明:

CUDA GPUs - Compute Capability | NVIDIA Developer

GPU Compute Capability
GeForce RTX 4090 8.9
GeForce RTX 4080 8.9
GeForce RTX 4070 Ti 8.9
GeForce RTX 3090 Ti 8.6
GeForce RTX 3090 8.6
GeForce RTX 3080 Ti 8.6
GeForce RTX 3080 8.6
GeForce RTX 3070 Ti 8.6
GeForce RTX 3070 8.6
Geforce RTX 3060 Ti 8.6
Geforce RTX 3060 8.6
GeForce GTX 1650 Ti 7.5

在其他语言中调用

python

一般不会有问题的。

1
2
# 确认 Python 中安装的 CUDA 版本
python -c "import cv2 as cv; print(cv.__version__)"
C++

C++ 的测试案例如下:

CMakeLists.txt

1
2
3
4
5
6
7
8
9
10
//ref: https://stackoverflow.com/questions/63455427/fatal-error-opencv2-opencv-modules-hpp-no-such-file-or-directory-include-ope

cmake_minimum_required(VERSION 3.15)
project(opencv_test)

set(CMAKE_CXX_STANDARD 17)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(opencv_test main.cpp)
target_link_libraries(opencvTest ${OpenCV_LIBS})

main.cpp

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
34
35
36
37
38
39
40
#include <iostream>
#include <opencv4/opencv2/opencv.hpp>
#include <opencv4/opencv2/core.hpp>
#include <opencv4/opencv2/imgcodecs.hpp>
#include <opencv4/opencv2/highgui.hpp>
#include <opencv4/opencv2/core/cuda.hpp>
#include <opencv2/cudaimgproc.hpp>

int main() {
cv::Mat image(640, 960, CV_8UC3, cv::Scalar(130, 17, 31));

cv::putText(image, "OpenCV Test Pass",
cv::Point(320, 200),
cv::FONT_HERSHEY_SIMPLEX,
2,
cv::Scalar(23, 114, 180),
2
);

cv::imshow("Input image", image);

cv::Mat img;
cv::cvtColor(image, img, cv::COLOR_BGR2GRAY);

cv::imshow("Gray image", img);

cv::cuda::GpuMat dst, src;
src.upload(img);

cv::Ptr<cv::cuda::CLAHE> ptr_img = cv::cuda::createCLAHE(10.0, cv::Size(4, 4));
ptr_img->apply(src, dst);

cv::Mat result;
dst.download(result);

cv::imshow("Output image", result);
cv::waitKey();

return 0;
}

编译配置运行:

1
2
3
4
5
6
7
8
9
10
11
12
mkdir opencv_test

vi CMakeLists.txt
vi main.cpp

mkdir build && cd build

cmake ..

cmake --build .

./opencv_test

异常输出:

1
2
3
4
terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(4.8.0) /root/opencv/modules/core/include/opencv2/core/private.cuda.hpp:106: error: (-216:No CUDA support) The library is compiled without CUDA support in function 'throw_no_cuda'

Aborted

没有 CUDA 支持,需要重新编译 OpenCV 库,后面有一步 sudo ninja install 要记得执行。

正常输出:

1
2
3
4
> make
[ 50%] Building CXX object CMakeFiles/opencvTest.dir/main.cpp.o
[100%] Linking CXX executable opencvTest
[100%] Built target opencvTest

Darknet

根据官方文档,必须配置以下依赖,也就是前面的步骤。

  • CUDA Took kit
  • cuDNN
  • OpenCV

AlexeyAB/darknet: Neural Networks for Object Detection)
实际上如果没有显卡,可以不配置 CUDA,采用纯 CPU 运算,没有安装 OpenCV,也能编译。

到这里已经非常简单了,一般 Darknet 编译都不会出什么问题,即使出问题,都是 CUDA/OpenCV 两个大头有任意一个配置出了问题。

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
34
35
# 确认 NVCC 编译器版本
/usr/local/cuda/bin/nvcc --version

# 确认 CUDA 版本
ls -lh /usr/local/cuda

# 确认 lib 版本
ls -lh /usr/local/cuda/lib64

# 导入环境变量
export CUDA_PATH=/usr/local/cuda/
export CUDACXX=/usr/local/cuda/bin/nvcc
export PATH=/usr/local/cuda/bin/:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64/

# AlexeyAB/darknet
git clone https://github.com/AlexeyAB/darknet && cd darknet

git checkout yolov4
# 取消修改
#git checkout .


mkdir build && cd build
# rm build

cmake ..
# 禁用 CUDA
# cmake .. -DENABLE_CUDA=OFF
# 如果第一次编译不通过,
# 1. 禁用 CUDA 编译一次
# 2. 删除编译目录 build/
# 3. 再带 CUDA 重新编译

cmake --build . --target install --parallel 8

故障排除

找不到 CUDA_PATHCUDACXX,或者是配置了 CUDA_PATHCUDACXX 的环境变量,都是因为 CUDA 和 cuDNN 版本不对。

1
2
3
4
5
6
7
8
9
10
11
12
> cmake ..
Darknet_VERSION: 0.2.5.4
CMake Warning at CMakeLists.txt:99 (message):
vcpkg not found, toolchain not defined, system not win32 so build might
fail


-- CUDA_PATH: /usr/local/cuda/
-- CUDACXX: /usr/local/cuda/bin/nvcc
CMake Error at CMakeLists.txt:148 (message):
CUDA not found, please build explicitly with -DENABLE_CUDA=OFF if you do
not want CUDA.

这里即使配置对了,也显示找不到 CUDA,这是因为 CUDA 和 cuDNN 的版本不匹配。

  • 也有可能是忘记导入环境变量了
  • 或许是 git 最新分支有 bug,需要切换到稳定分支
  • 实在是不行就重装系统吧

测试

Darknet YOLOv4 的测试,在 data/ 下有一部分测试文件

1
2
3
4
5
6
7
8
9
10
# 下载配置
wget https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov4-p6.cfg
# 下载权重
wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-p6.weights

# 测试编译后,图片识别
build/darknet detector test cfg/coco.data yolov4-p6.cfg yolov4-p6.weights data/dog.jpg

# 测试编译后,拉流
build/darknet detector demo cfg/coco.data yolov4-p6.cfg yolov4-p6.weights rtsp://<you_address>

按正常来说会有个弹窗,除非 OpenCV 没有正常安装,或者是权重文件下载出错。

顺带一提 darknet detector 支持的命令行参数,可以在 darknet/src/detector.crun_detector() 函数下找到。

darknet/src/detector.c at master · AlexeyAB/darknet (github.com)

参考资料

【1】:AlexeyAB/darknet: YOLOv4 / Scaled-YOLOv4 / YOLO - Neural Networks for Object Detection (Windows and Linux version of Darknet ) (github.com)
【2】:OpenCV: OpenCV configuration options reference