Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Tencent Ncnn YOLOv8 OBB Example

From Leeroopedia


Knowledge Sources
Domains Vision, Oriented_Object_Detection
Last Updated 2026-02-09 19:00 GMT

Overview

Concrete tool for oriented bounding box (OBB) detection using YOLOv8 with ncnn.

Description

This example implements YOLOv8 oriented bounding box (OBB) detection using the ncnn inference framework. It detects objects with rotated rectangles that tightly enclose objects at arbitrary angles, supporting 15 DOTAv1 classes commonly used in aerial and satellite imagery. The model produces two output blobs: a detection blob (w=79, h=21504) containing DFL bbox regression coefficients (16x4) and per-class scores (15 classes), and a rotation blob (w=1, h=21504) containing the predicted rotation angle for each box. Input images are preprocessed with letterbox padding to 1024x1024 resolution. This example requires full OpenCV (not simpleocv) for cv::RotatedRect support in the rotated NMS computation.

Usage

Use this example when you need to detect rotated objects using the YOLOv8 architecture, such as vehicles in aerial imagery, buildings in satellite photos, or rotated text regions. This is the YOLOv8 predecessor to the YOLO11 OBB variant.

Code Reference

Source Location

Signature

struct Object
{
    cv::RotatedRect rrect;
    int label;
    float prob;
};

static int detect_yolov8_obb(const cv::Mat& bgr, std::vector<Object>& objects);

static void generate_proposals(int stride, const ncnn::Mat& pred,
                               const ncnn::Mat& pred_angle,
                               float prob_threshold, std::vector<Object>& objects);
static void qsort_descent_inplace(std::vector<Object>& objects);
static void nms_sorted_bboxes(const std::vector<Object>& objects,
                               std::vector<int>& picked, float nms_threshold,
                               bool agnostic = false);

Import

#include "layer.h"
#include "net.h"

I/O Contract

Inputs

Name Type Required Description
image_path const char* Yes Path to input image file

Outputs

Name Type Description
objects std::vector<Object> Detected objects with rotated bounding boxes (cv::RotatedRect), class labels, and confidence scores

Model Files

File Description
yolov8n_obb.ncnn.param YOLOv8-OBB nano model parameter file
yolov8n_obb.ncnn.bin YOLOv8-OBB nano model weight file

Usage Examples

Running the Example

./yolov8_obb image.jpg

Key Code Pattern

ncnn::Net yolov8;
yolov8.opt.use_vulkan_compute = true;

yolov8.load_param("yolov8n_obb.ncnn.param");
yolov8.load_model("yolov8n_obb.ncnn.bin");

const int target_size = 1024;
const float prob_threshold = 0.25f;
const float nms_threshold = 0.45f;

// Letterbox pad to 1024x1024
ncnn::Mat in = ncnn::Mat::from_pixels_resize(bgr.data,
    ncnn::Mat::PIXEL_BGR2RGB, img_w, img_h, w, h);

const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f};
in_pad.substract_mean_normalize(0, norm_vals);

ncnn::Extractor ex = yolov8.create_extractor();
ex.input("in0", in_pad);

ncnn::Mat out0;  // bbox regression + class scores (w=79, h=21504)
ncnn::Mat out1;  // rotation angle (w=1, h=21504)
ex.extract("out0", out0);
ex.extract("out1", out1);

Implementation Details

Preprocessing

Input images are resized while preserving aspect ratio and letterbox padded to 1024x1024 (a multiple of max_stride=32). Pixel values are converted from BGR to RGB and normalized by dividing by 255. The padding fill value is 114.

Output Tensor Layout

The model produces two output tensors:

  • out0 (w=79, h=21504): Contains DFL bbox regression (16x4=64 values) and per-class scores (15 classes) for 21504 candidate boxes across three stride levels (8, 16, 32)
  • out1 (w=1, h=21504): Contains one rotation angle per candidate box

Rotated NMS

Intersection areas between rotated rectangles are computed using cv::rotatedRectangleIntersection followed by cv::contourArea, providing accurate IoU for arbitrarily oriented boxes.

Model Conversion

Models are converted from Ultralytics format using PNNX. The conversion requires modifying the exported Python script to reshape tensors for dynamic input sizes and re-exporting with dual input shapes (1024x1024 and 512x512).

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment