Real-time Detekcija Objekata sa YOLO i ONNX Runtime u C++

Real-time Detekcija Objekata sa YOLO i ONNX Runtime u C++

Table of Contents

  1. Ključne Tačke
  2. Uvod
  3. Detekcija Objekata u Realnom Vremenu
  4. Zašto YOLO?
  5. Zašto ONNX i ONNX Runtime?
  6. Detekcija Objekata nasuprot Segmentaciji Objekata
  7. Priprema za Rad sa YOLO i ONNX Runtime
  8. Učitavanje YOLO Modela
  9. Predobrada Slika
  10. Kreiranje ONNX Tenzora
  11. Inference
  12. Post-obrada
  13. Često Postavljana Pitanja (FAQ)

Ključne Tačke

  • YOLO (You Only Look Once) je moćan model za detekciju objekata koji omogućava brzu obradu slika u realnom vremenu.
  • ONNX (Open Neural Network Exchange) kao format modela omogućava prenosivost između različitih okvira za mašinsko učenje, olakšavajući integraciju modela napisanih u Pythonu u C++ aplikacije.
  • Ovaj članak pokriva osnovne korake u korišćenju YOLO modela za detekciju objekata sa ONNX Runtime, uključujući pre-processing slika, kreiranje tenzora, inference, i post-processing rezultata.

Uvod

U današnje vreme, primena veštačke inteligencije u analizi slika postaje sve prisutnija. Real-time detekcija objekata je ključna za mnoge oblasti, uključujući autonomna vozila, medicinske aplikacije, i sigurnosne sisteme. Jedan od najefikasnijih modela za ovu svrhu je YOLO (You Only Look Once), koji omogućava da se objekti detektuju u stvarnom vremenu sa visokom preciznošću.

U ovom članku istražujemo kako integrisati YOLO model sa ONNX Runtime u C++ aplikacijama, pružajući čitateljima jasan vodič kroz ključne korake. Ovaj proces uključuje konverziju modela iz Pythona, učitavanje modela, obradu slika te izvođenje detekcije i post-processing rezultata.

Detekcija Objekata u Realnom Vremenu

Detekcija objekata u realnom vremenu je potrebna u raznim primenama. Na primer, autonomna vozila koriste senzore za prepoznavanje stop znakova, pešaka i drugih vozila. U medicini, sistemi za navigaciju tokom operacija mogu koristiti tehnologiju detekcije kako bi optimizovali preciznost i sigurnost. Jasan zajednički zahtjev za sve ove primjene je brzina obrade – model mora reagovati u veoma kratkim vremenskim intervalima.

Na primer, standardna brzina od 30 FPS (frames per second) omogućava samo 33,3 milisekunde za obradu svakog okvira. To znači da su modeli kao što je YOLO, koji mogu postići obrtnu brzinu od 155 FPS, idealni za takve primene.

Zašto YOLO?

YOLO je predstavljen 2016. godine i od tada je prošao kroz različite verzije, s trenutnom dostupnom verzijom od strane Ultralytics. Redovni istraživači su unapređivali ovaj model, održavajući ga relevantnim i laganim za integraciju. YOLO prepoznaje više objekata unutar jedne slike, pružajući informacije o poziciji i tipu objekata. Ovo ga čini izuzetno korisnim za primene koje zahtevaju hitnu reakciju.

Zašto ONNX i ONNX Runtime?

ONNX (Open Neural Network Exchange) je otvoreni format za predstavljanje modela mašinskog učenja koji olakšava prenosivost između različitih okvira. To omogućava korisnicima da razviju i obučavaju modele koristeći PyTorch, a zatim ih lako uvezu u TensorFlow ili, u ovom slučaju, u C++ aplikacije.

ONNX Runtime je optimizovan za brzo izvršenje modela, što ga čini pogodnim za real-time aplikacije. U našem projektu, ONNX je već bio korišćen za druge modele, pa je njegova integracija bila prirodan veliki korak napred.

Detekcija Objekata nasuprot Segmentaciji Objekata

Važno je razlikovati detekciju objekata od segmentacije. Dok detekcija može reći da se nešto nalazi unutar određenog okvira, segmentacija pruža preciznije informacije o tome koje tačno piksele čine taj objekat. U ovom članku fokusiraćemo se na detekciju objekata, dok će segmentacija biti tema u sledećem delu.

Priprema za Rad sa YOLO i ONNX Runtime

Pre nego što krenemo u praktičnu upotrebu, potrebno je izvršiti nekoliko koraka instalacije potrebnih biblioteka za rad sa ONNX Runtime i YOLO modelom.

1. Instalacija potrebnih biblioteka

Da bismo koristili ONNX Runtime i OpenCV, potrebno je instalirati sledeće:

2. Konverzija YOLO Modela u ONNX Format

Prvi korak u našoj aplikaciji je konvertovanje YOLO modela iz Pythona u ONNX format. Ovo se može uraditi jednostavno pomoću Ultralytics biblioteke.

from ultralytics import YOLO

model = YOLO('/path/to/yolo11n.pt')
model.eval()
model.export(format='onnx', simplify=True)

Ovo će generisati ONNX fajl koji se može učitati u našoj C++ aplikaciji.

Učitavanje YOLO Modela

Nakon što smo dobili ONNX model, sledeći korak je učitavanje modela i priprema za inference.

#include <onnxruntime_cxx_api.h>

Ort::Session LoadYoloModel(const Ort::Env& env, const std::string& model_path) {
    Ort::SessionOptions yolo_session_options;
    Ort::Session yolo_model_session(env, model_path.c_str(), yolo_session_options);
    return yolo_model_session;
}

U ovom kodu, LoadYoloModel funkcija kreira sesiju koja nam omogućava da izvršimo model.

Predobrada Slika

Slika koju ćemo obraditi mora biti u formatu koji YOLO očekuje. Treba je resize-ovati na dimenzije 640x640, normalizovati pixel vrednosti, i promjeniti raspored boja iz BGR (kako OpenCV učitava slike) u RGB (kako YOLO očekuje).

cv::Mat LoadImage(const std::string& image_path) {
    cv::Mat image = cv::imread(image_path);
    cv::Mat resized_image;
    LetterBox(image, resized_image, cv::Size(640, 640));
    return cv::dnn::blobFromImage(resized_image, 1.0 / 255.0, cv::Size(640, 640), cv::Scalar::all(0), true, false, CV_32F);
}

Ova funkcija uzima putanju do slike, učitava je, menja njene dimenzije i formatira za dalju obradu.

Kreiranje ONNX Tenzora

Nakon pripreme slike, možemo je pretvoriti u ONNX tenzor.

Ort::Value BlobToONNXTensor(const cv::Mat& blob) {
    std::vector<int64_t> tensor_shape = {1, 3, 640, 640};
    Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
    return Ort::Value::CreateTensor<float>(memory_info, (float*)(blob.data), 3 * 640 * 640, tensor_shape.data(), tensor_shape.size());
}

Ova funkcija kreira ONNX tenzor koji model može obraditi u sledećem koraku.

Inference

Sada kada imamo tenzor za unos, možemo pokrenuti inference metod.

std::vector<Ort::Value> output = yolo_model_session.Run(Ort::RunOptions{nullptr}, input_names, &input_tensor, 1, output_names, 1);

Ovaj poziv izvršava model i vraća predikcije koje ćemo dalje obraditi.

Post-obrada

S obzirom da YOLO model predlaže više bounding box-a, važno je filtrirati one koji imaju nisku pouzdanost.

std::vector<YoloBoundingBox> ProcessYoloOutput(const cv::Mat& raw_boxes, const cv::Size& original_shape) {
    // Logika za filtriranje i scaling box-ova
}

Ova funkcija će obraditi rezultate i vratiti relevantne informacije o detektovanim objektima.

Često Postavljana Pitanja (FAQ)

1. Kako mogu koristiti YOLO za video detekciju? YOLO se može lako primeniti na video snimke tako što ćete proći kroz svaki okvir videa i primeniti iste metode opisane u ovom članku.

2. Koje su prednosti korištenja ONNX? ONNX omogućava prenosivost između različitih okvira mašinskog učenja, što olakšava obuku i integraciju modela.

3. Da li mogu prilagoditi YOLO model na vlastiti dataset? Da, možete obučiti YOLO model koristeći vlastiti dataset, a zatim izvesti model u ONNX format za korišćenje u vašim C++ aplikacijama.

4. Kakva je razlika između detekcije objekata i segmentacije? Detekcija objekata identifikuje gde se objekat nalazi u slici, dok segmentacija određuje tačne piksele koji čine objekat.

5. Mogu li koristiti CUDA za ubrzavanje? Da, korišćenje CUDA na NVIDIA GPU-u značajno može ubrzati proces inference pri radu sa YOLO modelom.

U nastavku se nalazi repo sa svim primerima koda koji su obrađeni u ovom članku, koji se može koristiti kao osnova za dalje eksperimente i projekte vezane za detekciju objekata.

Back to blog