YOLO Quickstart
| Field | Value |
|---|---|
| Difficulty | Intermediate |
| Estimated Read Time | 15-20 minutes |
| Labels | yolo, detection, mpk |
Concept
This tutorial is the fastest path to run a YOLO-style detector in NEAT and confirm the detection pipeline is wired correctly.
For new users, this chapter provides a practical bridge from "I have a YOLO MPK" to "I can run detection and inspect outputs." It uses explicit preprocess + MLA + boxdecode composition in C++, and the equivalent model-option path in Python.
What this chapter demonstrates:
- Loading a YOLO MPK and preparing image/tensor input.
- Running detection-oriented pipeline stages.
- Validating output kind and field structure.
Use-case guidance:
- First detector bring-up on a new board/runtime.
- Verifying required plugins and model assets are present.
- Establishing a known-good baseline before threshold/NMS tuning.
Reference:
Learning Process
- Resolve YOLO MPK and deterministic image/tensor input.
- Build and run detection path (preprocess + inference + decode).
- Inspect output structure (kind/fields) to validate detector wiring.
- Confirm completion with
CHECK,SIGNATURE, and[OK].
Run
NEAT_EXTRAS_ROOT=<sima-neat-*-Linux-extras>
cd $NEAT_EXTRAS_ROOT/lib/sima-neat/tutorials
./tutorial_v2_012_yolo_quickstart --mpk /path/to/model.tar.gz
Code
tutorials/012_yolo_quickstart/yolo_quickstart.cpp
// YOLO quickstart: compose a full detection Session via node groups.
//
// Usage:
// tutorial_v2_012_yolo_quickstart --mpk /path/to/yolo_v8s.tar.gz --image /path/to.jpg
#include "neat.h"
#include <opencv2/imgcodecs.hpp>
#include <iostream>
#include <stdexcept>
#include <string>
namespace {
bool get_arg(int argc, char** argv, const std::string& key, std::string& out) {
for (int i = 1; i + 1 < argc; ++i) {
if (key == argv[i]) {
out = argv[i + 1];
return true;
}
}
return false;
}
} // namespace
int main(int argc, char** argv) {
try {
std::string mpk, image;
if (!get_arg(argc, argv, "--mpk", mpk) || !get_arg(argc, argv, "--image", image)) {
std::cerr << "Usage: tutorial_v2_012_yolo_quickstart --mpk <path> --image <path>\n";
return 1;
}
cv::Mat bgr = cv::imread(image, cv::IMREAD_COLOR);
if (bgr.empty())
throw std::runtime_error("failed to load image: " + image);
simaai::neat::Model::Options mopt;
mopt.input_max_width = bgr.cols;
mopt.input_max_height = bgr.rows;
mopt.input_max_depth = bgr.channels();
simaai::neat::Model model(mpk, mopt);
// CORE LOGIC
// Explicit detection pipeline: Input -> Preprocess -> MLA -> SimaBoxDecode -> Output.
simaai::neat::Session session;
session.add(simaai::neat::nodes::Input());
session.add(simaai::neat::nodes::groups::Preprocess(model));
session.add(simaai::neat::nodes::groups::MLA(model));
session.add(simaai::neat::nodes::SimaBoxDecode(model, "yolov8", bgr.cols, bgr.rows,
/*score_threshold=*/0.52f,
/*nms_iou_threshold=*/0.5f,
/*top_k=*/100));
session.add(simaai::neat::nodes::Output());
auto run = session.build(bgr, simaai::neat::RunMode::Sync);
auto out = run.push_and_pull(bgr, /*timeout_ms=*/2000);
std::cout << "output_kind=" << static_cast<int>(out.kind) << "\n";
std::cout << "fields=" << out.fields.size() << "\n";
std::cout << "[OK] 012_yolo_quickstart\n";
return 0;
} catch (const std::exception& e) {
std::cerr << "[FAIL] " << e.what() << "\n";
return 1;
}
}