Zpracování obrazu I - detekce objektů

V tomto článku se budu věnovat úvodu do implementace algoritmu pro detekci objektů z obrazu nebo videa. Následující informace vycházejí z projektu Darknet/YOLO, krátkou prezentaci můžete najít TED.

Instalace vývojového prostředí

Provedl jsem import projektu do Visual Studia 2017 z projektu Darknet. K jeho kompilaci je třeba:

  • Visual Studio 2017 - použil jsem Community edici (vývojové prostředí C++, Windows SDK 10.x)
  • OpenCV - použil jsem verzi 3.4.3 - stačí rozbalit do adresáře na lokálním disku
  • NVIDIA CUDA Toolkit verzi 10
  • NVIDIA cuDNN - pro CUDA Toolkit 10 - zde pro stažení je nutné se zaregistrovat, po stažení stačí obsah archivu nakopírovat do CUDA Toolkit adresáře, v mém případě "D:\CUDA\v10"

Kompilace projektu Darknet/YOLO

Upravený projekt pro Visual Studio 2017 je ke stažení na GitHUB.

V projektu jsou nastaveny cesty pro kompilaci (Project->Properties->C/C++->General->Additional Include Directories):

  • OpenCV - "D:\OpenCV\opencv34\build\include"
  • NVIDIA CUDA Toolkit v10 - "$(CUDA_PATH)\include", což odkazuje na "D:\CUDA\v10\include"

Cesty pro linkování (Project->Properties->Linker->General->Additional Library Directories):

  • OpenCV - "D:\OpenCV\opencv34\build\x64\vc15\lib"
  • NVIDIA CUDA Toolkit v10 - "$(CUDA_PATH)\lib\x64", což odkazuje na "D:\CUDA\v10\lib\x64"

Visual Studio 2017 - otevření projektu, funkce main() v darknet.c

Spuštění aplikace

Testovací obrázek

Pro test spuštění aplikace a dostupnosti cest se soubory obrázku a konfigurací lze spustit ve vývojovém prostředí (Project->Properties->Debugging->Command Arguments): "imtest ./data/eagle.jpg". Což je ukázkový příklad.

Po spuštění se zobrazí následující obrázek:

Detekce objektů

Následuje příklad s detekcí objektů v obraze. Nastavíme Command Arguments: "detect ./cfg/yolov3.cfg yolov3.weights ./data/dog.jpg"

Což vykoná příkaz: yolo.exe detect ./cfg/yolov3.cfg yolov3.weights ./data/dog.jpg

Soubor s přednaučenými váhami "yolov3.weights" je ke stažení zde.

Po spuštění proběhne v konzoli následující:

layer     filters    size              input                output
    0 conv     32  3 x 3 / 1   608 x 608 x   3   ->   608 x 608 x  32  0.639 BFLOPs
    1 conv     64  3 x 3 / 2   608 x 608 x  32   ->   304 x 304 x  64  3.407 BFLOPs
...
  105 conv    255  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 255  0.754 BFLOPs
  106 yolo
Loading weights from yolov3.weights...Done!
./data/dog.jpg: Predicted in 21.612000 seconds.
dog: 100%
bicycle: 99%
truck: 92%

Projekt je aktuálně kompilovaný jen pro výpočet na CPU, čas pro výpočet na jednom snímku je kolem 20 vteřin (procesor G4600 3.6GHz), což pro vyhodnocení videa by nebylo použitelné. Následující krok je kompilace s využitím NVIDIA karty a CUDA.

Kompilace projektu pro GPU s využitím CUDA

Pro využití jednotky na grafické kartě NVIDIA (v mém případě GTX 1050 TI - 768 CUDA jednotek) k výpočtu je nutné zkompilovat projekt s makrem "GPU". Tu obnáší přídání zdrojových souborů .cu do projektu - zde jsou definovany funkce s jmenem *_gpu, které využívají CUDA API.

Visual Studio 2017 - projekt s využitím CUDA API

Zde je výsledek výpočtu z konzole aplikace:

...
  105 conv    255  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 255  0.754 BFLOPs
  106 yolo
Loading weights from yolov3.weights...Done!
./data/dog.jpg: Predicted in 0.382000 seconds.
dog: 100%
bicycle: 99%
truck: 92%

Tedy s využitím výpočtů na grafické kartě se pohybujeme výpočtovým časem kolem 0,38vteřiny, což by u videa bylo 2,5 snímků/s vyhodnocených.

Další optimalizací je využití makra "CUDNN", zde se už pohybujeme časem kolem 0,14vteřiny, tedy vyhodnocení 7 snímků/s.

Vyhodnocení videa

Pro test videa stačí stáhnout kamerový záznam dopravy.

yolo.exe detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights <video file>
yolo.exe detector demo ./cfg/coco.data cfg/yolov3.cfg yolov3.weights ./data/traffic1.mp4

Snímkování s vyhodnocením lze vidět na pozadí v okně konzole. S použitím hw CPU G4600 + GTX 1050 TI se snímkování pohybuje kolem 7 snímků/s.

Optimalizace

V souboru cfg/yolov3.cfg lze donastavit parametry, abychom optimalizovali ryhlost:

  • subdivisions=64, width=608, height=608 - rychlost 7 snímků/s
  • subdivisions=64, width=416, height=416 - rychlost 12 snímků/s
  • subdivisions=64, width=288, height=288 - rychlost 15 snímků/s

Užitečné odkazy