Зчитування меж виявлених об’єктів з вихідних даних моделі
| Поле | Значення |
|---|---|
| Категорія | Моделі та інференс |
| Складність | Середній |
| Орієнтовний час читання | 15-20 minutes |
| Мітки | postprocessing, boxdecode, detection |
Детектор не повертає прямокутні області безпосередньо. Його вихідні дані – це набір карт ознак, які все ще потребують застосування порогу, придушення локальних максимумів і відображення координат, перш ніж їх можна буде інтерпретувати. SimaBoxDecode – це етап постобробки, який виконує всі ці три операції за один оптимізований крок, перетворюючи тензори, отримані в процесі виведення, на остаточні результати у вигляді пікселів вихідного зображення.
У цьому розділі налаштовується процес декодування: вибирається сімейство моделей за допомогою decode_type, встановлюється поріг впевненості, придушуються перекриття за допомогою порогу NMS IoU, а також обмежується вивід за допомогою top_k. Після цього запускається модель і зчитується кількість виявлених об’єктів. У результаті ви отримаєте налаштований конвеєр детектора та кількість виявлень, отриману з його виводу, а також (у розділі «На практиці» нижче) повний формат даних, щоб ви могли самостійно обробляти межі об’єктів у будь-якому середовищі виконання.
Покроковий огляд
Налаштування декодування
Ці параметри визначають як вхідний контракт, так і поведінку постобробки. decode_type (YoloV8 у цьому випадку) визначає шлях декодування для певної родини моделей. Поріг впевненості відкидає слабкі кандидати перед застосуванням NMS; поріг IoU для NMS контролює, наскільки агресивно об’єднуються перекривні рамки; top_k обмежує кінцеву кількість для детермінованого обчислення наступних етапів; а boxdecode_original_width/boxdecode_original_height відображають декодовані координати назад у пікселі вихідного зображення. Рекомендації щодо налаштування кожного з цих параметрів наведено в розділі «На практиці» нижче.
decode_type приймає перелік BoxDecodeType::YoloV8. Значення порогу/NMS/top_k передаються пізніше через stages::BoxDecodeOptions, а не через Model::Options.
simaai::neat::Model::Options opt;
opt.preprocess.color_convert.input_format = simaai::neat::PreprocessColorFormat::BGR;
opt.preprocess.input_max_width = bgr.cols;
opt.preprocess.input_max_height = bgr.rows;
opt.preprocess.input_max_depth = bgr.channels();
opt.decode_type = simaai::neat::BoxDecodeType::YoloV8;
Створення моделі
Створення Model з архіву разом із параметрами прив’язує конфігурацію декодування до моделі, щоб етапи виведення та постобробки, отримані з неї, використовували наведені вище налаштування.
simaai::neat::Model model(model_path, opt);
Запуск попередньої обробки, виведення та декодування
Тут кадр проходить через попередню обробку, виведення MLA та декодер обмежувальних рамок, щоб отримати результат виявлення.
Шлях прокладається поетапно: stages::Preproc генерує вхідний тензор, stages::Infer запускає модель, а stages::BoxDecodeOptions (з параметрами detection_threshold = 0.55, nms_iou_threshold = 0.5, top_k = 100) налаштовує декодування, яке виконується наступним.
simaai::neat::TensorList pre = simaai::neat::stages::Preproc(std::vector<cv::Mat>{bgr}, model);
simaai::neat::Sample infer_samples = simaai::neat::stages::Infer(
simaai::neat::Sample{simaai::neat::sample_from_tensors(pre)}, model);
if (infer_samples.empty())
throw std::runtime_error("infer stage returned no samples");
simaai::neat::Sample infer = infer_samples.front();
simaai::neat::stages::BoxDecodeOptions box(simaai::neat::BoxDecodeType::YoloV8);
(void)box.decode_type;
(void)bgr.cols;
(void)bgr.rows;
box.detection_threshold = 0.55;
box.nms_iou_threshold = 0.5;
box.top_k = 100;
Зчитайте межі
Нарешті, перетворіть вихід декодування на щось, що можна використовувати.
stages::BoxDecodeResults(...) повертає BoxDecodeResultList; вектор boxes першого результату вже розпаковано у формат {x1, y1, x2, y2, score, class_id} і приведено до меж вихідних пікселів, тому decoded.boxes.size() є кількістю виявлених об’єктів.
// BoxDecode parses the "BBOX" tensor into {x1, y1, x2, y2, score, class_id}
// entries clamped to original_width x original_height source pixels.
simaai::neat::BoxDecodeResultList decoded_results =
simaai::neat::stages::BoxDecodeResults(simaai::neat::Sample{infer}, model, box);
if (decoded_results.empty())
throw std::runtime_error("boxdecode result parser returned no results");
const simaai::neat::BoxDecodeResult& decoded = decoded_results.front();