第三十八節、windows下yolo v4運行環境搭建


yolo v4源碼是開源的,在github上可以下載,並且有很詳細的使用說明,本文只是針對windows下環境的安裝進行介紹。

一、環境搭建

本節將進行windows下環境的搭建,我們將需要安裝下面各個軟件,並且需要注意安裝的軟件是有版本要求的:

Requirements for Windows, Linux and macOS
CMake >= 3.18: https://cmake.org/download/
Powershell (already installed on windows): https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell
CUDA >= 10.2: https://developer.nvidia.com/cuda-toolkit-archive (on Linux do Post-installation Actions)
OpenCV >= 2.4: use your preferred package manager (brew, apt), build from source using vcpkg or download from OpenCV official site (on Windows set system variable OpenCV_DIR = C:\opencv\build - where are the include and x64 folders image)
cuDNN >= 8.0.2 https://developer.nvidia.com/rdp/cudnn-archive (on Linux follow steps described here https://docs.nvidia.com/deeplearning/sdk/cudnn-install/index.html#installlinux-tar , on Windows follow steps described here https://docs.nvidia.com/deeplearning/sdk/cudnn-install/index.html#installwindows)
GPU with CC >= 3.0: https://en.wikipedia.org/wiki/CUDA#GPUs_supported
Visual Studio 2017 or 2019

1.1 安裝opencv

官網下載地址:https://opencv.org/releases/,下載速度較慢。

國內鏡像:https://www.raoyunsoft.com/opencv/

這里我直接下載最新的版本:opencv-4.5.5-vc14_vc15.exe

下載完成之后,雙擊直接解壓,這里我解壓到E:\Program Files路徑下:

安裝完成后,我們打開E:\Program Files\opencv:

然后我們配置環境變量,【此電腦】->【屬性】->【高級系統設置】->【環境變量】:

在系統變量中添加以下數據:

OpenCV_DIR   E:\Program Files\opencv\build

再進入系統變量里的Path,添加如下數據:

E:\Program Files\opencv\build\x64\vc15\lib
E:\Program Files\opencv\build\x64\vc15\bin

1.2 安裝Visual Studio

官網下載地址:https://visualstudio.microsoft.com/zh-hans/downloads/

安裝的組件只需要“使用C++的桌面開發”,如果之前沒有安裝過,下載社區版本安裝即可,這里我們選擇Visual Studio 2017或者2019。
由於我之前已經安裝了Visual Studio 2019所以就不重復安裝了。

1.3 安裝cuda

如果你使用的是NVIDIA顯卡,cuda安裝步驟參考windows和ubuntu下深度學習theano環境搭建 

 NVIDIA驅動版本與CUDA版本對應關系https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html

1.4 安裝cuDNN

如果你使用的是NVIDIA顯卡,cuDNN安裝步驟參考windows和ubuntu下深度學習theano環境搭建 

官方安裝指導手冊:https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html.

1.5 安裝cmake

cmake官方下載地址:https://cmake.org/download/,下載速度比較慢;

國內下載鏡像:https://cmake.org/files/

要求cmake>= 3.18,這里我下載cmake-3.23.0-rc4-windows-x86_64.msi。雙擊直接安裝,這里我安裝到E:\Program Files\CMake。

下載完成后安裝得到以下文件:

進入bin文件夾,這個cmake-gui就是我們要用程序:

二、源碼下載

2.1 git下載源碼

git是代碼版本管理工具,由於yolo v4源碼是放在github倉庫中的,我們需要從git上下載源碼,下載方式有兩種:

  • 通過git 直接下載代碼;
  • 到github上手動下載源碼;

如果使用git下載,我們需要安裝git工具:https://www.git-scm.com/download/

安裝成功后,假設我想將源碼下載到路徑:G:\人工智能\深度學習\36.目標檢測\官方庫,進入該路徑下,右鍵:

 輸入如下命令,開始下載源碼:

git clone https://github.com/AlexeyAB/darknet.git

下載完成后,可以在當前路徑看到:

2.2 環境變量配置

在系統變量Path中加入下載的darknet的位置:

G:\人工智能\深度學習\36.目標檢測\官方庫\darknet\build\darknet\x64

2.3 下載權重文件yolov4.weights

鏈接:https://pan.baidu.com/s/1koPg1amOlqIw5bLwv4Id_Q
提取碼:1234

將下載后的yolov4.weights文件放在darknet文件夾下:

將下載后的yolov4.cfg文件放在darknet/cfg文件夾下。

三、編譯程序

3.1 使用cmake配置源碼

由於cmake不支持中文路徑,因此我將下載的yolo v4源碼剪切到G盤根路徑下。同時記得修改系統環境變量。

打開CMake,配置:

  • 源代碼路徑:G:/darknet;
  • 構建目標文件路徑:G:/darknet;

點擊左下角Configure,然后第一項選擇我們安裝的 Visual Studio 2019,第二項平台選擇x64:

 

3.2 關閉CUDA

如果沒有GPU,第一次編譯的時候會出現如下錯誤:

cuda找不到,只好取消勾選不用GPU:

 

再次點擊Configure,配置成功,會輸出如下信息:

Darknet_VERSION: 0.2.5.4
vcpkg not found, toolchain not defined, using integrated libs on win32
Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.18363.
Looking for pthread.h
Looking for pthread.h - not found
Found Threads: TRUE  
Found PThreads4W: G:/darknet/3rdparty/pthreads/lib/pthreadVC2.lib  
PThreads4W_DLL_DIR: G:/darknet/3rdparty/pthreads/include/../bin
PThreads4W_DEBUG_DLL_DIR: G:/darknet/3rdparty/pthreads/include/../debug/bin
OpenCV ARCH: x64
OpenCV RUNTIME: vc15
OpenCV STATIC: OFF
Found OpenCV: E:/Program Files/opencv/build (found version "4.5.5") 
Found OpenCV 4.5.5 in E:/Program Files/opencv/build/x64/vc15/lib
You might need to add E:\Program Files\opencv\build\x64\vc15\bin to your PATH to be able to run your applications.
Found Stb: G:/darknet/3rdparty/stb/include  
Found OpenMP_C: -openmp (found version "2.0") 
Found OpenMP_CXX: -openmp (found version "2.0") 
Found OpenMP: TRUE (found version "2.0")  
ZED SDK not enabled, since it requires CUDA
Configuring done

需要注意的是如果沒有GPU的話,圖片可以識別分類沒問題,但是視頻識別沒有用GPU就特別慢,像播放幻燈片一樣。

3.3 編譯代碼

點擊生成和打開項目:

 之后會自動打開vs,選擇x64和Release,點擊生成,這時生成文件即可:

將會輸出如下編譯信息:

已啟動生成…
1>------ 已啟動生成: 項目: ZERO_CHECK, 配置: Debug x64 ------
1>Checking Build System
2>------ 已啟動生成: 項目: dark, 配置: Debug x64 ------
3>------ 已啟動生成: 項目: darknet, 配置: Debug x64 ------
2>Building Custom Rule G:/darknet/CMakeLists.txt
2>用於 x64 的 Microsoft (R) C/C++ 優化編譯器 19.29.300372>版權所有(C) Microsoft Corporation。保留所有權利。
2>cl /c /IG:\darknet\include /IG:\darknet\src /IG:\darknet\3rdparty\stb\include /I"E:\Program Files\opencv\build\include" /IG:\darknet\3rdparty\pthreads\include /Zi /W1 /WX- /diagnostics:column /Od /Ob0 /D _WINDLL /D _MBCS /D WIN32 /D _WINDOWS /D LIB_EXPORTS=1 /D USE_CMAKE_LIBS /D OPENCV /D _CRT_RAND_S /D NOMINMAX /D _USE_MATH_DEFINES /D _CRT_SECURE_NO_WARNINGS /D _TIMESPEC_DEFINED /D "CMAKE_INTDIR=\"Debug\"" /D dark_EXPORTS /Gm- /EHsc /RTC1 /MDd /GS /fp:fast /Zc:wchar_t /Zc:forScope /Zc:inline /GR /openmp /Fo"dark.dir\Debug\\" /Fd"dark.dir\Debug\vc142.pdb" /external:env:EXTERNAL_INCLUDE /external:W1 /Gd /TP /wd4013 /wd4018 /wd4028 /wd4047 /wd4068 /wd4090 /wd4101 /wd4113 /wd4133 /wd4190 /wd4244 /wd4267 /wd4305 /wd4477 /wd4996 /wd4819 /errorReport:prompt G:\darknet\src\yolo_v2_class.cpp G:\darknet\src\http_stream.cpp G:\darknet\src\image_opencv.cpp
2>yolo_v2_class.cpp
3>Building Custom Rule G:/darknet/CMakeLists.txt
3>用於 x64 的 Microsoft (R) C/C++ 優化編譯器 19.29.300373>版權所有(C) Microsoft Corporation。保留所有權利。
3>cl /c /IG:\darknet\include /IG:\darknet\src /IG:\darknet\3rdparty\stb\include /I"E:\Program Files\opencv\build\include" /IG:\darknet\3rdparty\pthreads\include /Zi /W1 /WX- /diagnostics:column /Od /Ob0 /D _MBCS /D WIN32 /D _WINDOWS /D USE_CMAKE_LIBS /D OPENCV /D _CRT_RAND_S /D NOMINMAX /D _USE_MATH_DEFINES /D _TIMESPEC_DEFINED /D "CMAKE_INTDIR=\"Debug\"" /Gm- /EHsc /RTC1 /MDd /GS /fp:fast /Zc:wchar_t /Zc:forScope /Zc:inline /GR /openmp /Fo"darknet.dir\Debug\\" /Fd"darknet.dir\Debug\vc142.pdb" /external:env:EXTERNAL_INCLUDE /external:W1 /Gd /TC /wd4013 /wd4018 /wd4028 /wd4047 /wd4068 /wd4090 /wd4101 /wd4113 /wd4133 /wd4190 /wd4244 /wd4267 /wd4305 /wd4477 /wd4996 /wd4819 /errorReport:prompt G:\darknet\src\darknet.c G:\darknet\src\activation_layer.c G:\darknet\src\activations.c G:\darknet\src\art.c G:\darknet\src\avgpool_layer.c G:\darknet\src\batchnorm_layer.c G:\darknet\src\blas.c G:\darknet\src\box.c G:\darknet\src\captcha.c G:\darknet\src\cifar.c G:\darknet\src\classifier.c G:\darknet\src\coco.c G:\darknet\src\col2im.c G:\darknet\src\compare.c G:\darknet\src\connected_layer.c G:\darknet\src\conv_lstm_layer.c G:\darknet\src\convolutional_layer.c G:\darknet\src\cost_layer.c G:\darknet\src\cpu_gemm.c G:\darknet\src\crnn_layer.c G:\darknet\src\crop_layer.c G:\darknet\src\dark_cuda.c G:\darknet\src\data.c G:\darknet\src\deconvolutional_layer.c G:\darknet\src\demo.c G:\darknet\src\detection_layer.c G:\darknet\src\detector.c G:\darknet\src\dice.c G:\darknet\src\dropout_layer.c G:\darknet\src\gaussian_yolo_layer.c G:\darknet\src\gemm.c G:\darknet\src\getopt.c G:\darknet\src\gettimeofday.c G:\darknet\src\go.c G:\darknet\src\gru_layer.c G:\darknet\src\im2col.c G:\darknet\src\image.c G:\darknet\src\layer.c G:\darknet\src\list.c G:\darknet\src\local_layer.c G:\darknet\src\lstm_layer.c G:\darknet\src\matrix.c G:\darknet\src\maxpool_layer.c G:\darknet\src\network.c G:\darknet\src\nightmare.c G:\darknet\src\normalization_layer.c G:\darknet\src\option_list.c G:\darknet\src\parser.c G:\darknet\src\region_layer.c G:\darknet\src\reorg_layer.c G:\darknet\src\reorg_old_layer.c G:\darknet\src\representation_layer.c G:\darknet\src\rnn.c G:\darknet\src\rnn_layer.c G:\darknet\src\rnn_vid.c G:\darknet\src\route_layer.c G:\darknet\src\sam_layer.c G:\darknet\src\scale_channels_layer.c G:\darknet\src\shortcut_layer.c G:\darknet\src\softmax_layer.c G:\darknet\src\super.c G:\darknet\src\swag.c G:\darknet\src\tag.c G:\darknet\src\tree.c G:\darknet\src\upsample_layer.c G:\darknet\src\utils.c G:\darknet\src\voxel.c G:\darknet\src\writing.c G:\darknet\src\yolo.c G:\darknet\src\yolo_layer.c
3>darknet.c
3>activation_layer.c
3>activations.c
3>art.c
3>avgpool_layer.c
2>http_stream.cpp
3>batchnorm_layer.c
3>blas.c
3>box.c
3>captcha.c
3>cifar.c
3>classifier.c
3>coco.c
3>col2im.c
3>compare.c
3>connected_layer.c
3>conv_lstm_layer.c
3>convolutional_layer.c
3>cost_layer.c
3>cpu_gemm.c
3>crnn_layer.c
3>正在生成代碼...
3>正在編譯...
3>crop_layer.c
3>dark_cuda.c
3>data.c
3>deconvolutional_layer.c
3>demo.c
3>detection_layer.c
3>detector.c
3>dice.c
3>dropout_layer.c
3>gaussian_yolo_layer.c
3>gemm.c
3>getopt.c
3>gettimeofday.c
3>go.c
3>gru_layer.c
3>im2col.c
3>image.c
3>layer.c
3>list.c
3>local_layer.c
3>正在生成代碼...
3>正在編譯...
3>lstm_layer.c
3>matrix.c
3>maxpool_layer.c
3>network.c
3>nightmare.c
3>normalization_layer.c
2>image_opencv.cpp
3>option_list.c
3>parser.c
3>region_layer.c
3>reorg_layer.c
3>reorg_old_layer.c
3>representation_layer.c
3>rnn.c
3>rnn_layer.c
3>rnn_vid.c
3>route_layer.c
3>sam_layer.c
3>scale_channels_layer.c
3>shortcut_layer.c
3>softmax_layer.c
3>正在生成代碼...
3>正在編譯...
3>super.c
3>swag.c
3>tag.c
3>tree.c
3>upsample_layer.c
3>utils.c
3>voxel.c
3>writing.c
3>yolo.c
3>yolo_layer.c
2>正在生成代碼...
3>正在生成代碼...
3>用於 x64 的 Microsoft (R) C/C++ 優化編譯器 19.29.300373>版權所有(C) Microsoft Corporation。保留所有權利。
3>cl /c /IG:\darknet\include /IG:\darknet\src /IG:\darknet\3rdparty\stb\include /I"E:\Program Files\opencv\build\include" /IG:\darknet\3rdparty\pthreads\include /Zi /W1 /WX- /diagnostics:column /Od /Ob0 /D _MBCS /D WIN32 /D _WINDOWS /D USE_CMAKE_LIBS /D OPENCV /D _CRT_RAND_S /D NOMINMAX /D _USE_MATH_DEFINES /D _TIMESPEC_DEFINED /D "CMAKE_INTDIR=\"Debug\"" /Gm- /EHsc /RTC1 /MDd /GS /fp:fast /Zc:wchar_t /Zc:forScope /Zc:inline /GR /openmp /Fo"darknet.dir\Debug\\" /Fd"darknet.dir\Debug\vc142.pdb" /external:env:EXTERNAL_INCLUDE /external:W1 /Gd /TP /wd4013 /wd4018 /wd4028 /wd4047 /wd4068 /wd4090 /wd4101 /wd4113 /wd4133 /wd4190 /wd4244 /wd4267 /wd4305 /wd4477 /wd4996 /wd4819 /errorReport:prompt G:\darknet\src\http_stream.cpp G:\darknet\src\image_opencv.cpp
3>http_stream.cpp
2>用於 x64 的 Microsoft (R) C/C++ 優化編譯器 19.29.300372>版權所有(C) Microsoft Corporation。保留所有權利。
2>cl /c /IG:\darknet\include /IG:\darknet\src /IG:\darknet\3rdparty\stb\include /I"E:\Program Files\opencv\build\include" /IG:\darknet\3rdparty\pthreads\include /Zi /W1 /WX- /diagnostics:column /Od /Ob0 /D _WINDLL /D _MBCS /D WIN32 /D _WINDOWS /D LIB_EXPORTS=1 /D USE_CMAKE_LIBS /D OPENCV /D _CRT_RAND_S /D NOMINMAX /D _USE_MATH_DEFINES /D _CRT_SECURE_NO_WARNINGS /D _TIMESPEC_DEFINED /D "CMAKE_INTDIR=\"Debug\"" /D dark_EXPORTS /Gm- /EHsc /RTC1 /MDd /GS /fp:fast /Zc:wchar_t /Zc:forScope /Zc:inline /GR /openmp /Fo"dark.dir\Debug\\" /Fd"dark.dir\Debug\vc142.pdb" /external:env:EXTERNAL_INCLUDE /external:W1 /Gd /TC /wd4013 /wd4018 /wd4028 /wd4047 /wd4068 /wd4090 /wd4101 /wd4113 /wd4133 /wd4190 /wd4244 /wd4267 /wd4305 /wd4477 /wd4996 /wd4819 /errorReport:prompt G:\darknet\src\activation_layer.c G:\darknet\src\activations.c G:\darknet\src\art.c G:\darknet\src\avgpool_layer.c G:\darknet\src\batchnorm_layer.c G:\darknet\src\blas.c G:\darknet\src\box.c G:\darknet\src\captcha.c G:\darknet\src\cifar.c G:\darknet\src\classifier.c G:\darknet\src\coco.c G:\darknet\src\col2im.c G:\darknet\src\compare.c G:\darknet\src\connected_layer.c G:\darknet\src\conv_lstm_layer.c G:\darknet\src\convolutional_layer.c G:\darknet\src\cost_layer.c G:\darknet\src\cpu_gemm.c G:\darknet\src\crnn_layer.c G:\darknet\src\crop_layer.c G:\darknet\src\dark_cuda.c G:\darknet\src\data.c G:\darknet\src\deconvolutional_layer.c G:\darknet\src\demo.c G:\darknet\src\detection_layer.c G:\darknet\src\detector.c G:\darknet\src\dice.c G:\darknet\src\dropout_layer.c G:\darknet\src\gaussian_yolo_layer.c G:\darknet\src\gemm.c G:\darknet\src\getopt.c G:\darknet\src\gettimeofday.c G:\darknet\src\go.c G:\darknet\src\gru_layer.c G:\darknet\src\im2col.c G:\darknet\src\image.c G:\darknet\src\layer.c G:\darknet\src\list.c G:\darknet\src\local_layer.c G:\darknet\src\lstm_layer.c G:\darknet\src\matrix.c G:\darknet\src\maxpool_layer.c G:\darknet\src\network.c G:\darknet\src\nightmare.c G:\darknet\src\normalization_layer.c G:\darknet\src\option_list.c G:\darknet\src\parser.c G:\darknet\src\region_layer.c G:\darknet\src\reorg_layer.c G:\darknet\src\reorg_old_layer.c G:\darknet\src\representation_layer.c G:\darknet\src\rnn.c G:\darknet\src\rnn_layer.c G:\darknet\src\rnn_vid.c G:\darknet\src\route_layer.c G:\darknet\src\sam_layer.c G:\darknet\src\scale_channels_layer.c G:\darknet\src\shortcut_layer.c G:\darknet\src\softmax_layer.c G:\darknet\src\super.c G:\darknet\src\swag.c G:\darknet\src\tag.c G:\darknet\src\tree.c G:\darknet\src\upsample_layer.c G:\darknet\src\utils.c G:\darknet\src\voxel.c G:\darknet\src\writing.c G:\darknet\src\yolo.c G:\darknet\src\yolo_layer.c
2>activation_layer.c
2>activations.c
2>art.c
2>avgpool_layer.c
2>batchnorm_layer.c
2>blas.c
2>box.c
2>captcha.c
2>cifar.c
2>classifier.c
2>coco.c
2>col2im.c
2>compare.c
2>connected_layer.c
2>conv_lstm_layer.c
2>convolutional_layer.c
2>cost_layer.c
2>cpu_gemm.c
2>crnn_layer.c
2>crop_layer.c
2>正在生成代碼...
2>正在編譯...
2>dark_cuda.c
2>data.c
2>deconvolutional_layer.c
2>demo.c
2>detection_layer.c
2>detector.c
2>dice.c
2>dropout_layer.c
2>gaussian_yolo_layer.c
2>gemm.c
2>getopt.c
2>gettimeofday.c
2>go.c
2>gru_layer.c
2>im2col.c
2>image.c
2>layer.c
3>image_opencv.cpp
2>list.c
2>local_layer.c
2>lstm_layer.c
2>正在生成代碼...
2>正在編譯...
2>matrix.c
2>maxpool_layer.c
2>network.c
2>nightmare.c
2>normalization_layer.c
2>option_list.c
2>parser.c
2>region_layer.c
2>reorg_layer.c
2>reorg_old_layer.c
2>representation_layer.c
2>rnn.c
2>rnn_layer.c
2>rnn_vid.c
2>route_layer.c
2>sam_layer.c
2>scale_channels_layer.c
2>shortcut_layer.c
2>softmax_layer.c
2>super.c
2>正在生成代碼...
2>正在編譯...
2>swag.c
3>正在生成代碼...
2>tag.c
2>tree.c
2>upsample_layer.c
2>utils.c
2>voxel.c
2>writing.c
2>yolo.c
2>yolo_layer.c
2>正在生成代碼...
3>darknet.vcxproj -> G:\darknet\Debug\darknet.exe
2>  正在創建庫 G:/darknet/Debug/darknetd.lib 和對象 G:/darknet/Debug/darknetd.exp
2>dark.vcxproj -> G:\darknet\Debug\darknetd.dll
4>------ 已啟動生成: 項目: uselib, 配置: Debug x64 ------
4>Building Custom Rule G:/darknet/CMakeLists.txt
4>用於 x64 的 Microsoft (R) C/C++ 優化編譯器 19.29.300374>版權所有(C) Microsoft Corporation。保留所有權利。
4>cl /c /IG:\darknet\include /IG:\darknet\src /IG:\darknet\3rdparty\stb\include /I"E:\Program Files\opencv\build\include" /IG:\darknet\3rdparty\pthreads\include /Zi /W1 /WX- /diagnostics:column /Od /Ob0 /D _MBCS /D WIN32 /D _WINDOWS /D USE_CMAKE_LIBS /D _CRT_RAND_S /D NOMINMAX /D _USE_MATH_DEFINES /D OPENCV /D _CRT_SECURE_NO_WARNINGS /D "CMAKE_INTDIR=\"Debug\"" /Gm- /EHsc /RTC1 /MDd /GS /fp:fast /Zc:wchar_t /Zc:forScope /Zc:inline /GR /openmp /Fo"uselib.dir\Debug\\" /Fd"uselib.dir\Debug\vc142.pdb" /external:env:EXTERNAL_INCLUDE /external:W1 /Gd /TP /wd4013 /wd4018 /wd4028 /wd4047 /wd4068 /wd4090 /wd4101 /wd4113 /wd4133 /wd4190 /wd4244 /wd4267 /wd4305 /wd4477 /wd4996 /wd4819 /errorReport:prompt G:\darknet\src\yolo_console_dll.cpp
4>yolo_console_dll.cpp
4>uselib.vcxproj -> G:\darknet\Debug\uselib.exe
5>------ 已啟動生成: 項目: ALL_BUILD, 配置: Debug x64 ------
5>Building Custom Rule G:/darknet/CMakeLists.txt
6>------ 已啟動生成: 項目: INSTALL, 配置: Debug x64 ------
6>-- Install configuration: "Debug"
6>-- Installing: G:/darknet/darknetd.lib
6>-- Installing: G:/darknet/darknetd.dll
6>-- Installing: G:/darknet/include/darknet/darknet.h
6>-- Installing: G:/darknet/include/darknet/yolo_v2_class.hpp
6>-- Installing: G:/darknet/uselib.exe
6>-- Installing: G:/darknet/darknet.exe
6>-- Installing: G:/darknet/share/darknet/DarknetTargets.cmake
6>-- Installing: G:/darknet/share/darknet/DarknetTargets-debug.cmake
6>-- Installing: G:/darknet/share/darknet/DarknetConfig.cmake
6>-- Installing: G:/darknet/share/darknet/DarknetConfigVersion.cmake
========== 生成: 成功 6 個,失敗 0 個,最新 0 個,跳過 0 個 ==========
View Code

這時我們的目錄下會出現這個文件:

四、運行程序

4.1 識別圖片

在G:\darknet\data路徑下有一個dog.jpg文件:

在G:\darknet路徑下,打開cmd控制台運行如下命令:

./darknet.exe detect cfg\yolov4.cfg yolov4.weights data\dog.jpg

輸出如下:

4.2 攝像頭識別

打開電腦攝像頭識別監控畫面(需要提前開啟攝像頭權限):

./darknet.exe detector demo cfg\coco.data cfg\yolov4.cfg yolov4.weights

如果沒有使用GPU的話,這里識別會分非常卡頓。

4.3 視頻識別

識別視頻(視頻放到data目錄下):

./darknet.exe detector demo cfg\coco.data cfg\yolov4.cfg yolov4.weights .\data\xxx.mp4

五、訓練VOC 2012數據集

5.1 數據集下載

這里以下載Pascal VOC 2012數據集為例,VOC 2012是VOC2007數據集的升級版,每張圖片都有標注,標注的物體包括人、動物(如貓、狗、鳥等)、交通工具(如車、船飛機等)、家具(如椅子、桌子、沙發等)在內的20個類別。

首先下載數據集,下載地址為:http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar

下載完成后,加壓到G:/darknet下,得到一個解壓后,得到一個VOCdevkit文件夾:

JPEGImages文件夾中包含了PASCAL VOC提供的所有的就jpg圖片,共計17125張,包括了訓練和測試圖片。

這些圖像都以“年份_編號.jpg”格式命名。

圖片的像素尺寸大小不一,但是橫向圖的尺寸大約在500*375左右,縱向圖的尺寸大約在375*500左右,長寬均不會超過512。

對於每一張圖像,都在Annotations文件夾中存放有對應的xml文件。保存着物體框的標注,包括圖片文件名,圖片大小,圖片邊界框等信息。

以2007_000027.xml為例:

<annotation>
    #數據所在的文件夾名
    <folder>VOC2012</folder>
    #圖片名稱
    <filename>2007_000027.jpg</filename>
    <source>
        <database>The VOC2007 Database</database>
        <annotation>PASCAL VOC2007</annotation>
        <image>flickr</image>
    </source>
    #圖片的寬和高
    <size>
        <width>486</width>
        <height>500</height>
        <depth>3</depth>
    </size>
    <segmented>0</segmented>
    <object>
       #類別名
        <name>person</name>
       #物體的姿勢
        <pose>Unspecified</pose>
       #物體是否被部分遮擋 
        <truncated>0</truncated>
       ##是否為難以辨識的物體, 主要指要結合背景才能判斷出類別的物體。雖有標注, 但一般忽略這類物體 跳過難以識別的?
        <difficult>0</difficult>
       #邊界框
        <bndbox>
            <xmin>174</xmin>
            <ymin>101</ymin>
            <xmax>349</xmax>
            <ymax>351</ymax>
        </bndbox>
       #下面的數據是人體各個部位邊界框
        <part>
            <name>head</name>           
            <bndbox>
                <xmin>169</xmin>
                <ymin>104</ymin>
                <xmax>209</xmax>
                <ymax>146</ymax>
            </bndbox>
        </part>
        <part>
            <name>hand</name>
            <bndbox>
                <xmin>278</xmin>
                <ymin>210</ymin>
                <xmax>297</xmax>
                <ymax>233</ymax>
            </bndbox>
        </part>
        <part>
            <name>foot</name>
            <bndbox>
                <xmin>273</xmin>
                <ymin>333</ymin>
                <xmax>297</xmax>
                <ymax>354</ymax>
            </bndbox>
        </part>
        <part>
            <name>foot</name>
            <bndbox>
                <xmin>319</xmin>
                <ymin>307</ymin>
                <xmax>340</xmax>
                <ymax>326</ymax>
            </bndbox>
        </part>
    </object>
</annotation>
View Code

ImageSets文件夾包括Action Layout Main Segmentation四部分:

Action存放的是人的動作(running、jumping等等);

Layout存放人體部位數據(人的head、hand、feet等等);

Main存放的是圖像物體識別數據,總共分為20類;

Segmentation:存放的是可用於語義分割的數據:

SegmentationClass保存了分割后的標簽圖(2913張png圖片),標注出了每一個像素屬於哪一個類別:

SegmentationObject保存了分割后的標簽圖(759張png圖片),標注出了每一個像素屬於哪一個具體的物體:

其中./scripts/voc_label.py代碼可以給訓練集/驗證集/測試集數據集打標簽,將voc_label.py放到VOCdevkit文件夾下:

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join

sets=[('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007', 'test')]

classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]


def convert(size, box):          # box由實際像素(xmin,xmax,ymin,ymax),轉換成歸一化的(w,y,w,h) 
    dw = 1./(size[0])            # 1/width 單位寬像素長度
    dh = 1./(size[1])            # 1/heigh 單位高像素長度 
    x = (box[0] + box[1])/2.0 - 1   #(xmin + xmax)/2-1
    y = (box[2] + box[3])/2.0 - 1   #(ymin + ymax)/2-1
    w = box[1] - box[0]             # box寬所占像素數
    h = box[3] - box[2]             # box高所占像素數 
    x = x*dw                        # 即歸一化后的中心坐標x
    w = w*dw                        # 即歸一化后的寬
    y = y*dh                        # 即歸一化后中心坐標y
    h = h*dh                        # 即歸一化后的高
    return (x,y,w,h)

def convert_annotation(year, image_id):   # 將xml標簽文件數據,進行處理后,並寫入txt文件中
    in_file = open('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id))
    out_file = open('VOCdevkit/VOC%s/labels/%s.txt'%(year, image_id), 'w')
    tree=ET.parse(in_file)       # 解析xml
    root = tree.getroot()        # 獲取根節點
    size = root.find('size')     # 獲取圖片大小 width、height、depth
    w = int(size.find('width').text)
    h = int(size.find('height').text)

    for obj in root.iter('object'):                      # 獲取圖片標注信息
        difficult = obj.find('difficult').text           # 是否是難以識別的 如果是,跳過 
        cls = obj.find('name').text                      # 類別名  
        if cls not in classes or int(difficult)==1:
            continue
        cls_id = classes.index(cls)                      # 類別所對應的id         
        xmlbox = obj.find('bndbox')                      # 邊界框    
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
        bb = convert((w,h), b)                           # 轉換成歸一化之后的(x,y,w,h)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')  # 寫入 class_id x y w h

wd = getcwd() # 獲取當前工作路徑

for year, image_set in sets:
    if not os.path.exists('VOCdevkit/VOC%s/labels/'%(year)):   # 創建標簽文件夾,
        os.makedirs('VOCdevkit/VOC%s/labels/'%(year))
    image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set)).read().strip().split() #獲取所有的用於訓練的圖片文件名列表
    list_file = open('%s_%s.txt'%(year, image_set), 'w')
    for image_id in image_ids:
        list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpg\n'%(wd, year, image_id))
        convert_annotation(year, image_id)    #xml標注文件轉為txt類型標准文件
    list_file.close()

os.system("cat 2007_train.txt 2007_val.txt 2012_train.txt 2012_val.txt > train.txt")
os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt")

大概介紹一下這段程序:

  • 讀取VOCdevkit\VOC2012\ImageSets\Main\train.txt,獲取用來訓練的圖片文件的文件名列表 ,一共5717個;
  • 遍歷這5717個文件名,向./2012_train.txt文件中寫入文件全路徑;同時獲取每個文件的xml標注信息,並進行處理,獲取目標類別,以及歸一化后的邊界框信息,寫入lebal下的文件名.text文件中;
  • 讀取VOCdevkit\VOC2012\ImageSets\Main\val.txt,獲取用來驗證的圖片文件的文件名列表 ,一共5823個;
  • 遍歷這5823個文件名,向./2012_val.txt文件中寫入文件全路徑;同時獲取每個文件的xml標注信息,並進行處理,獲取目標類別,以及歸一化后的邊界框信息,寫入lebal下的文件名.text文件中;

我們需要修改代碼sets:

sets=[('2012', 'train'), ('2012', 'val')]

由於我們是windows系統,因此屏蔽掉最后os.system相關代碼。

我們運行這個程序,需要注意的是這個文件不可以直接運行,因為如果直接運行那么當前程序運行的目錄就是當前文件,此時會找不到VOCdevkit文件夾。因此我們需要在Terminal中運行:

python ./VOCdevkit/voc_label.py

運行完后,在G:\darknet\VOCdevkit\VOC2012\labels下生成11540個文件:

同時在G:\darknet下生成這兩個文件:

將這兩個文件拷貝到G:\darknet\VOCdevkit:

並將名字修改為train.txt、val.txt。

5. 2 配置文件

在G:\darknet\VOCdevkit下創建data文件夾,復制G:\darknet\cfg文件夾下的voc.data到data文件夾下,並根據實際情況修改文件內容(路徑中使用/,不要使用\):

classes= 20
train  = G:/darknet/VOCdevkit/train.txt
valid  = G:/darknet/VOCdevkit/val.txt
names = G:/darknet/VOCdevkit/data/voc.names
backup = G:/darknet/VOCdevkit/backup

復制G:\darknet\data目錄下的voc.name到data文件夾:

aeroplane
bicycle
bird
boat
bottle
bus
car
cat
chair
cow
diningtable
dog
horse
motorbike
person
pottedplant
sheep
sofa
train
tvmonitor

這里存放的是每個標簽的名字。

在G:\darknet\VOCdevkit下創建cfg文件夾,從G:\darknet\cfg下復制一個配置文件作為我們的配置文件,這里我選擇復制yolov4.cfg到G:\darknet\VOCdevkit\cfg文件夾下,yolov4.cfg里面存放的是網絡參數以及網絡結構信息,並進行修改:

  • 將classes=80 改為你的類別數20(一共三處);
  • 改正[filters=255] 為 filters=(classes + 5)x3 =75(位置為查找yolo,每個yolo前的[convolutional]里,注意只修改最接近yolo的那個filters需要修改,一共應該有三處);
  • 修改max_batches=classes*2000,也就是40000;
  • 修改steps為80% 到 90% 的max_batches值  比如max_batches=40000,則steps=32000,36000;

5.3 訓練

shift+右鍵,G:\darknet路徑下打開 PowerShell 窗口。

當沒有預訓練模型,執行以下代碼:

./darknet.exe detector train VOCdevkit/data/voc.data VOCdevkit/cfg/yolov4.cfg

如果有yolov4預訓練權重yolov4.conv.137:下載路徑鏈接:

./darknet.exe detector train VOCdevkit/data/voc.data VOCdevkit/cfg/yolov4.cfg yolov4.conv.137

軟件開始執行訓練命令,正常會顯示Loss表界面和一個不斷刷新數據的命令行界面; 這里由於我的電腦沒有GPU跑的非常慢,這里我就不演示了。

如果有問題,幾分鍾內就會報錯,一般的錯誤主要是文件找不到或者內存不夠等,請仔細檢查以上步驟的所有文件名和路徑,如果是內存不夠,可以修改cfg配置文件中前幾行中的batch(改小,比如32)和subdivisions(改大,比如32)的數字后,再試。

跑完是這樣的,每訓練 100次會自動保存一次,訓練生成的權重文件在G:\darknet\VOCdevkit\backup目錄下,名字為yolov4-tiny_last.weights:

5.4 預測

訓練結束了,現在可以測試訓練結果了,復制一份剛才訓練的 yolov4-tiny_last.weights保存到VOCdevkit/weights路徑下。

復制yolov4.cfg文件並且重命名為yolov4-test.cfg,修改其中的參數:

batch=1
subdivisions=1

運行以下代碼測試:

./darknet.exe detector test VOCdevkit/data/voc.data VOCdevkit/cfg/yolov4-test.cfg VOCdevkit/weights/yolo.voc.weights  xxx.jpg

六、訓練自己的數據

這里以從網上找到的磁塊的缺陷裂縫檢測的項目為例,具體數據可以參考博客提供軟件環境和工業數據集下載]工業瑕疵缺陷檢測實戰:Windows下基於YOLOv4和OpenCV4深度學習訓練自己的數據集和前端軟件,效果意外的好。樣本數據大致如下圖:

 

6.1 labelImg工具安裝

首先我們要去下載標准工具,labelImg下載鏈接:。labelImg工具適用於圖像檢測的數據集制作,可以直接生成yolo的標注格式。

我們在我們G:/darknet路徑下,使用git下載源碼:

git clone https://github.com/tzutalin/labelImg.git

下載完成后,會在當前路徑看到:

使用開發工具spyder++或者pycharm打開這個項目,要求python版本3.0+:

安裝必要的包,在Terminal下執行如下代碼,安裝比較慢耐心等待:

pip install pyqt5 -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip install lxml -i https://pypi.tuna.tsinghua.edu.cn/simple/
pyrcc5 -o libs/resources.py resources.qrc

然后在Terminal,運行如下命令,打開labelImg程序(或者直接運行labelImg.py里面的main函數):

python labelImg.py

程序界面如下:

 

如果想將python代碼打包生成exe可執行文件,執行如下命令即可:

pip install pyinstaller -i https://pypi.tuna.tsinghua.edu.cn/simple/
pyinstaller --hidden-import=pyqt5 --hidden-import=lxml -F -n "labelImg" -c labelImg.py -p ./libs -p ./

此時會在dist路徑下生成exe文件:

6.2 數據集文件配置

我們在G:\darknet路徑下創建一個文件夾Magnet,文件夾格式如下:

Magnet      
    Annotations       #放入所有的xml文件
    ImageSets    
        Main          #放入train.txt,val.txt文件
JPEGImages #放入所有的訓練圖片文件 labels #放入所有的txt文件,會自動生成此文件夾 TESTImages #放入所有的測試圖片文件
cfg #yolov4網絡配置
data #訓練集數據信息

然后把部分樣本圖片放到G:\darknet\Magnet\JPEGImages路徑下,這里我選取了一共116張用於訓練和驗證圖片。

下面我們在G:\darknet\Magnet下創建一個python文件prepare.py,

"""
預處理工作

@author zy
@since 2022/03/26
"""
import os


def generate_train_and_val_txt():
    '''
    遍歷JPEGImages路徑下所有文件名,並按照4:1,將數據分成訓練集和驗證集
    並把全路徑寫入train.txt,val.txt
    :return:
    '''
    # 獲取當前工作路徑
    pwd = os.getcwd()
    # 訓練集和驗證集圖片所在路徑
    source_folder = os.path.join(pwd, 'JPEGImages')
    # train.txt文件路徑
    train_text = os.path.join(pwd, 'ImageSets/Main/train.txt')
    # val.txt文件路徑
    val_test = os.path.join(pwd, 'ImageSets/Main/val.txt')

    # 判斷文件是否存在,存在刪除
    if os.path.exists(train_text):
        os.remove(train_text)

    # 判斷文件是否存在,存在刪除
    if os.path.exists(val_test):
        os.remove(val_test)

    with open(train_text, 'a') as train_file:
        with open(val_test, 'a') as val_file:
            count = 0
            # 遍歷所有圖片
            for file_name in os.listdir(source_folder):
                file_path = os.path.join(source_folder, file_name)
                count = count + 1
                # 每隔4張選取一張驗證集
                if count % 5 == 0:
                    val_file.write(file_path + '\n')
                else:
                    train_file.write(file_path + '\n')


if __name__ == '__main__':
    generate_train_and_val_txt()

然后運行該程序,會在ImageSets/Main文件夾下生成如下文件:

Main文件夾中的文件分別表示train.txt是訓練集,val.txt是驗證集。

然后將這兩個文件復制到G:\darknet\Magnet路徑下。

在G:\darknet\Magnet\data下新建magnet.data,內容如下:

classes= 3
train  = G:/darknet/Magnet/train.txt
valid  = G:/darknet/Magnet/val.txt
names = G:/darknet/Magnet/data/magnet.names
backup = G:/darknet/Magnet/backup

在G:\darknet\Magnet\data下新建magnet.names,內容如下:

rip
gap
label

這里我們定義三類標簽,名字分別為rip、gap、label。

從G:\darknet\cfg下復制一個配置文件作為我們的配置文件,由於我們的樣本和缺陷類別都比較少,所以這里我選擇tiny yolov4,tiny yolov4是簡化版本的yolov4,主要是為了滿足計算能力緊張的開發者使用和學習。tiny yolov4在准確度上會有相當的下降,但是在運算時間上,也會有相當大的提升。

這里我選擇復制yolov4-tiny.cfg到G:\darknet\Magnet\cfg文件夾下,yolov4-tiny.cfg里面存放的是網絡參數以及網絡結構信息,並進行修改:

  • 將classes=80 改為你的類別數3(一共2處);
  • 改正[filters=255] 為 filters=(classes + 5)x3 =24(位置為查找yolo,每個yolo前的[convolutional]里,注意只修改最接近yolo的那個filters需要修改,一共應該有2處);
  • 修改max_batches=classes*2000,也就是6000;
  • 修改steps為80% 到 90% 的max_batches值  比如max_batches=6000,則steps=4800,5400;
  • 修改batch=32,subdivisions=8;

6.3 數據打標簽

給圖片標記缺陷位置和類型:打開labelImg軟件,在labelImg中點擊“打開目錄”打開數據集圖片所在的文件夾為G:\darknet\Magnet\JPEGImages,如下圖:

在labelImg中點擊“改變存放目錄”按鈕,選擇保存標簽數據的路徑為G:\darknet\Magnet\Annotations,如下圖

配置好路徑后,就可以開始標記了,軟件的右下角會目錄下的圖片列表,點擊軟件左側的左右箭頭可以切換下一張圖片查看標記,軟件左下角按鈕可以添加編輯標記。

標簽名字暫時只能用英文,標簽的名字要記住,后面還要用,本項目定義了三類標簽,名字分別為rip、gap、label。

有缺陷的要標記,沒有缺陷的圖片或者不想訓練的圖片,不用標記,每標記完一個圖片,Ctrl + S保存后,會在G:\darknet\Magnet\Annotations下生成相應的標簽文件,嗎,默認是PascalVOC格式,這里以0001.xml為例:

<annotation>
    <folder>JPEGImages</folder>
    <filename>0001.jpg</filename>
    <path>G:\darknet\Magnet\JPEGImages\0001.jpg</path>
    <source>
        <database>Unknown</database>
    </source>
    <size>
        <width>1280</width>
        <height>960</height>
        <depth>1</depth>
    </size>
    <segmented>0</segmented>
    <object>
        <name>gap</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>883</xmin>
            <ymin>401</ymin>
            <xmax>917</xmax>
            <ymax>450</ymax>
        </bndbox>
    </object>
    <object>
        <name>gap</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>879</xmin>
            <ymin>491</ymin>
            <xmax>914</xmax>
            <ymax>540</ymax>
        </bndbox>
    </object>
</annotation>

我們可以通過修改格式將標簽數據直接轉換成YOLO訓練所需要的格式:

這里我們標記完一共生成116個txt文件:

比如0001.txt:

0 0.703125 0.443229 0.026562 0.051042
0 0.700391 0.536979 0.027344 0.051042

然后我們將這些文件直接復制到G:\darknet\Magnet\labels路徑下。

6.4 訓練

shift+右鍵,G:\darknet路徑下打開 PowerShell 窗口。

當沒有預訓練模型,執行以下代碼:

./darknet.exe detector train Magnet/data/magnet.data Magnet/cfg/yolov4-tiny.cfg

如果有tiny yolov4預訓練權重yolov4-tiny.conv.29:下載路徑鏈接:https://pan.baidu.com/s/16b7GpOU50B2YkjriVQl1UQ

./darknet.exe detector train Magnet/data/magnet.data Magnet/cfg/yolov4-tiny.cfg yolov4-tiny.conv.29

跑完是這樣的,每訓練 100次會自動保存一次,訓練生成的權重文件在G:\darknet\Magnet\backup目錄下,名字為yolov4-tiny_last.weights。

6.5 預測

訓練結束了,現在可以測試訓練結果了,復制一份剛才訓練的yolov4-tiny_last.weights保存到Magnet/weights路徑下。

復制yolov4-tiny.cfg文件並且重命名為yolov4-tiny-test.cfg,修改其中的參數:

batch=1
subdivisions=1

運行以下代碼測試:

 ./darknet.exe detector test ./Magnet/data/magnet.data ./Magnet/cfg/yolov4-tiny-test.cfg ./Magnet/weights/yolov4-tiny_last.weights ./Magnet/TESTImages/2002.jpg

參考文章

[1]YOLOv4手把手教程!從配置環境,帶你跑通代碼!

[2]win10 + YOLOv4 + CPU/GPU最全面配置教程

[3]AlexeyAB/darknet 

[4]【機器視覺】YOLOv4 手把手實操:制作數據集、訓練權重、測試

[5][提供軟件環境和工業數據集下載]工業瑕疵缺陷檢測實戰:Windows下基於YOLOv4和OpenCV4深度學習訓練自己的數據集和前端軟件,效果意外的好

[6]fox1986487 / YOLOV4_YOLOV4_TINY

[7](tiny) YOLOv4 詳細訓練指南(附下載鏈接)

[8]Could not locate zlibwapi.dll. Please make sure it is in your library path

[9]https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html#install-zlib-windows

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM