sp500/yolo.h File Reference

sp500/yolo.h File Reference#

Mobilint REGULUS: sp500/yolo.h File Reference
Mobilint REGULUS v4.1
SP500 DSP API
yolo.h File Reference

YOLO decode and postprocess on the SP500 DSP. More...

#include <sp500/dsp.h>

Go to the source code of this file.

Data Structures

struct  sp500_yolo_detection
 One detection. 6 floats; the layout of a SP500_YOLO_TASK_DETECT record. More...
struct  sp500_yolo_segmentation
 One segmentation result. 11 floats; the layout of a SP500_YOLO_TASK_SEGMENT record. More...
struct  sp500_yolo_keypoint
 One keypoint of a pose record. More...
struct  sp500_yolo_pose
 One pose result. 57 floats; the layout of a SP500_YOLO_TASK_POSE record. More...
struct  sp500_yolo_params
 Model shape and thresholds. More...
struct  sp500_yolo_raw
 Raw head tensors as separate planes, one set per feature level. More...
struct  sp500_yolo_raw_anchor
 Raw head tensors as one combined tensor per level. SP500_YOLO_HEAD_ANCHOR only. More...
struct  sp500_yolo_output
 Where the results go. More...
struct  sp500_yolo_result
 What a YOLO call produced. More...

Macros

#define SP500_YOLO_LEVELS   3
 Feature levels a YOLO head produces: strides 8, 16 and 32.
#define SP500_YOLO_POSE_KEYPOINTS   17
 Keypoints in a pose record; the fixed COCO 17-point layout.
#define SP500_YOLO_DETECT_RECORD_FLOATS   6
 Floats per record, by task.
#define SP500_YOLO_SEGMENT_RECORD_FLOATS   11
#define SP500_YOLO_POSE_RECORD_FLOATS   57
#define SP500_YOLO_MASK_NONE   0xFFFFFFFFu
 sp500_yolo_segmentation::mask_offset value meaning "no mask stored for this box" - the snapped box was empty, or the mask buffer was full. The detection itself is still valid.
#define SP500_YOLO_MAX_CANDIDATES   1024
 Candidates above the confidence threshold that the DSP ranks. Beyond this many, the surplus is dropped before duplicate removal.

Enumerations

enum  {
  SP500_YOLO_HEAD_ANCHORLESS = 0 ,
  SP500_YOLO_HEAD_ANCHOR = 1 ,
  SP500_YOLO_HEAD_NMSFREE = 2 ,
  SP500_YOLO_HEAD_DFLFREE = 3
}
 Head family; see the table at the top of this file. More...
enum  {
  SP500_YOLO_TASK_DETECT = 0 ,
  SP500_YOLO_TASK_SEGMENT = 1 ,
  SP500_YOLO_TASK_POSE = 2
}
 What the head predicts. More...

Functions

uint32_t sp500_yolo_mask_offset (const sp500_yolo_segmentation *record)
 Mask offset of a segmentation record, decoded from its float slot. Returns SP500_YOLO_MASK_NONE when no mask was stored.
void sp500_yolo_params_init (sp500_yolo_params *params)
 Fill params with the defaults documented above.
void sp500_yolo_raw_init (sp500_yolo_raw *raw)
 Zero raw so every plane reads as unused.
void sp500_yolo_raw_anchor_init (sp500_yolo_raw_anchor *raw)
 Zero raw so every plane reads as unused.
void sp500_yolo_output_init (sp500_yolo_output *output)
 Zero output so every buffer reads as unused.
int32_t sp500_yolo_record_floats (int32_t task)
 Floats in one record of task, or 0 for an unknown task.
uint32_t sp500_yolo_records_bytes (int32_t task, int32_t max_detections)
 Bytes needed by output.records for max_detections records of task, or 0 for invalid arguments.
int32_t sp500_yolo_grid_cells (int32_t img_w, int32_t img_h)
 Grid cells summed over the three levels for a img_w x img_h input: the row count of a decoded anchor-free table. Multiply by anchors_per_level for an anchor head.
sp500_status sp500_yolo_head_for_model (const char *model_name, int32_t *head)
 Head family for a model name, so you do not have to memorise the table.
sp500_status sp500_yolo_decode (int32_t head, int32_t task, const sp500_yolo_raw *raw, const sp500_yolo_params *params, sp500_yolo_output *output, sp500_yolo_result *result)
 Decode a split-plane head and remove duplicates, in one DSP call.
sp500_status sp500_yolo_decode_anchor (int32_t task, const sp500_yolo_raw_anchor *raw, const sp500_yolo_params *params, sp500_yolo_output *output, sp500_yolo_result *result)
 Decode an anchor head and remove duplicates, in one DSP call. ::SP500_YOLO_HEAD_ANCHOR only.
sp500_status sp500_yolo_postprocess (int32_t head, int32_t task, const sp500_buffer *decoded, int32_t num_rows, const sp500_yolo_params *params, sp500_yolo_output *output, sp500_yolo_result *result)
 Select detections from an already-decoded anchor table.

Detailed Description

YOLO decode and postprocess on the SP500 DSP.

A YOLO network does not return boxes. It returns a grid of raw numbers, one vector per candidate location - 8400 candidates for a 640x640 anchor-free head, 25200 for an anchor-based one. Turning those numbers into a list of detections is the postprocess: decode the coordinates, drop candidates below the confidence threshold, and remove duplicates. Each call below does all of that in a single DSP round trip.

Head families
YOLO generations encode boxes and remove duplicates differently, so pick the family your network belongs to. sp500_yolo_head_for_model() maps a model name onto one; the table is:
Family Box encoding Duplicates Tasks Models
::SP500_YOLO_HEAD_ANCHORLESS DFL, 4 x 16 logits per-class NMS detect, segment, pose v3u, v5u, v8, v9, GELAN, 11, 12
::SP500_YOLO_HEAD_ANCHOR anchor offsets + objectness per-class NMS detect, segment v3, v5, v7
::SP500_YOLO_HEAD_NMSFREE DFL, 4 x 16 logits dual top-k detect v10
::SP500_YOLO_HEAD_DFLFREE 4 direct distances dual top-k detect, segment, pose 26

The u suffix matters: YOLOv3u and YOLOv5u are retrained with an anchor-free DFL head and belong to ::SP500_YOLO_HEAD_ANCHORLESS, not to the anchor family that plain YOLOv3 and YOLOv5 use.

Two entry points per family
Results
output->records receives result->count fixed-size records. Cast the buffer to sp500_yolo_detection, sp500_yolo_segmentation or sp500_yolo_pose according to the task; sp500_yolo_records_bytes() sizes it. Box coordinates are pixels in the NETWORK INPUT frame - if you letterboxed the source, map them back with the scale and padding sp500_letterbox() returned.
Example
p.num_classes = 80;
out.records = sp500_buffer_wrap(dets, sizeof dets);
raw.box[0] = sp500_buffer_wrap(box_p3, box_p3_bytes);
raw.cls[0] = sp500_buffer_wrap(cls_p3, cls_p3_bytes);
// ... levels 1 and 2 ...
if(sp500_yolo_decode(SP500_YOLO_HEAD_ANCHORLESS, SP500_YOLO_TASK_DETECT,
&raw, &p, &out, &r) == SP500_OK)
{
for(uint32_t i = 0; i < r.count; ++i) { use(&dets[i]); }
}
@ SP500_OK
Definition dsp.h:87
sp500_status sp500_dsp_open(uint32_t timeout_ms)
Attach to the DSP. Must succeed before any other DSP call.
sp500_buffer sp500_buffer_wrap(void *data, uint32_t size)
Wrap memory you already own. The call stages one copy in each direction; nothing is taken over and no...
Definition dsp.h:302
One detection. 6 floats; the layout of a SP500_YOLO_TASK_DETECT record.
Definition yolo.h:119
Where the results go.
Definition yolo.h:258
sp500_buffer records
Definition yolo.h:261
Model shape and thresholds.
Definition yolo.h:174
int32_t num_classes
Definition yolo.h:177
int32_t max_detections
Definition yolo.h:178
Raw head tensors as separate planes, one set per feature level.
Definition yolo.h:221
sp500_buffer box[SP500_YOLO_LEVELS]
Definition yolo.h:224
sp500_buffer cls[SP500_YOLO_LEVELS]
Definition yolo.h:226
What a YOLO call produced.
Definition yolo.h:274
uint32_t count
Definition yolo.h:275
sp500_status sp500_yolo_decode(int32_t head, int32_t task, const sp500_yolo_raw *raw, const sp500_yolo_params *params, sp500_yolo_output *output, sp500_yolo_result *result)
Decode a split-plane head and remove duplicates, in one DSP call.
@ SP500_YOLO_TASK_DETECT
Definition yolo.h:110
void sp500_yolo_raw_init(sp500_yolo_raw *raw)
Zero raw so every plane reads as unused.
void sp500_yolo_params_init(sp500_yolo_params *params)
Fill params with the defaults documented above.
void sp500_yolo_output_init(sp500_yolo_output *output)
Zero output so every buffer reads as unused.

Definition in file yolo.h.

Macro Definition Documentation

◆ SP500_YOLO_LEVELS

#define SP500_YOLO_LEVELS   3

Feature levels a YOLO head produces: strides 8, 16 and 32.

Definition at line 79 of file yolo.h.

◆ SP500_YOLO_POSE_KEYPOINTS

#define SP500_YOLO_POSE_KEYPOINTS   17

Keypoints in a pose record; the fixed COCO 17-point layout.

Definition at line 82 of file yolo.h.

◆ SP500_YOLO_DETECT_RECORD_FLOATS

#define SP500_YOLO_DETECT_RECORD_FLOATS   6

Floats per record, by task.

Definition at line 85 of file yolo.h.

◆ SP500_YOLO_SEGMENT_RECORD_FLOATS

#define SP500_YOLO_SEGMENT_RECORD_FLOATS   11

Definition at line 86 of file yolo.h.

◆ SP500_YOLO_POSE_RECORD_FLOATS

#define SP500_YOLO_POSE_RECORD_FLOATS   57

Definition at line 87 of file yolo.h.

◆ SP500_YOLO_MASK_NONE

#define SP500_YOLO_MASK_NONE   0xFFFFFFFFu

sp500_yolo_segmentation::mask_offset value meaning "no mask stored for this box" - the snapped box was empty, or the mask buffer was full. The detection itself is still valid.

Definition at line 92 of file yolo.h.

◆ SP500_YOLO_MAX_CANDIDATES

#define SP500_YOLO_MAX_CANDIDATES   1024

Candidates above the confidence threshold that the DSP ranks. Beyond this many, the surplus is dropped before duplicate removal.

Definition at line 96 of file yolo.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Head family; see the table at the top of this file.

Definition at line 99 of file yolo.h.

◆ anonymous enum

anonymous enum

What the head predicts.

Enumerator
SP500_YOLO_TASK_DETECT 0 

boxes only

SP500_YOLO_TASK_SEGMENT 1 

boxes plus per-box masks

SP500_YOLO_TASK_POSE 2 

boxes plus 17 COCO keypoints

Definition at line 108 of file yolo.h.

Function Documentation

◆ sp500_yolo_head_for_model()

sp500_status sp500_yolo_head_for_model ( const char * model_name,
int32_t * head )

Head family for a model name, so you do not have to memorise the table.

Matching is case-insensitive, ignores -, _, . and spaces, treats the v as optional, and skips a size suffix - so "yolov8n", "YOLOv8-seg", "yolo8" and "yolov8" all resolve to ::SP500_YOLO_HEAD_ANCHORLESS. Generations 3 and 5 exist in both families, and are read as the anchor-free retrained export when the name carries a u right after the generation or at the end: "yolov3u", "yolov3-sppu", "yolov5nu" and "yolov5n6u" are ::SP500_YOLO_HEAD_ANCHORLESS, while "yolov5n" and "yolov5n6" are ::SP500_YOLO_HEAD_ANCHOR. Recognised generations: 3, 5, 7, 8, 9, 10, 11, 12, 26, plus "gelan".

Parameters
model_nameThe model name, for example "yolo11" or "yolov8n".
headReceives one of the SP500_YOLO_HEAD_* values.
Returns
SP500_OK, or SP500_ERR_INVALID_ARG for a NULL argument or a name that is not recognised - in which case pick the family from the table at the top of this file.

◆ sp500_yolo_decode()

sp500_status sp500_yolo_decode ( int32_t head,
int32_t task,
const sp500_yolo_raw * raw,
const sp500_yolo_params * params,
sp500_yolo_output * output,
sp500_yolo_result * result )

Decode a split-plane head and remove duplicates, in one DSP call.

For ::SP500_YOLO_HEAD_ANCHORLESS, ::SP500_YOLO_HEAD_NMSFREE and ::SP500_YOLO_HEAD_DFLFREE. Use sp500_yolo_decode_anchor() for the anchor family.

Parameters
head::SP500_YOLO_HEAD_ANCHORLESS, ::SP500_YOLO_HEAD_NMSFREE or ::SP500_YOLO_HEAD_DFLFREE.
taskSP500_YOLO_TASK_DETECT, SP500_YOLO_TASK_SEGMENT or SP500_YOLO_TASK_POSE. NMSFREE supports detection only.
rawRaw head planes for all three levels.
paramsModel shape and thresholds. For segmentation also set proto, mask_coeffs, proto_h, proto_w and mask_threshold.
outputResult buffers. records is required; mask is required for segmentation.
resultReceives the record count. May be NULL.
Returns
SP500_OK on success. SP500_ERR_UNSUPPORTED when the family does not implement task, SP500_ERR_INVALID_ARG for a bad or incomplete parameter, SP500_ERR_BUFFER_TOO_SMALL when output.records cannot hold max_detections records, SP500_ERR_NOT_READY, SP500_ERR_TIMEOUT or SP500_ERR_DSP.
Note
A frame with no detection is SP500_OK with result->count == 0.

◆ sp500_yolo_decode_anchor()

sp500_status sp500_yolo_decode_anchor ( int32_t task,
const sp500_yolo_raw_anchor * raw,
const sp500_yolo_params * params,
sp500_yolo_output * output,
sp500_yolo_result * result )

Decode an anchor head and remove duplicates, in one DSP call. ::SP500_YOLO_HEAD_ANCHOR only.

Parameters
taskSP500_YOLO_TASK_DETECT or SP500_YOLO_TASK_SEGMENT. This family has no pose head.
rawOne combined tensor per level.
paramsModel shape and thresholds, plus anchors_per_level and anchors.
outputResult buffers.
resultReceives the record count. May be NULL.
Returns
As sp500_yolo_decode().

◆ sp500_yolo_postprocess()

sp500_status sp500_yolo_postprocess ( int32_t head,
int32_t task,
const sp500_buffer * decoded,
int32_t num_rows,
const sp500_yolo_params * params,
sp500_yolo_output * output,
sp500_yolo_result * result )

Select detections from an already-decoded anchor table.

For networks that decode boxes inside the graph and hand you one table of candidate rows. Works for every family; the family still decides how duplicates are removed and whether rows carry an objectness column.

Parameters
headThe family the network belongs to.
taskThe task the table was produced for.
decodedThe decoded table: num_rows rows of 4 + objectness + num_classes + extra floats, where objectness is 1 for ::SP500_YOLO_HEAD_ANCHOR and 0 otherwise, and extra is mask_coeffs for segmentation or 51 for pose.
num_rowsRows in decoded. Required and must be positive; for a standard head this is sp500_yolo_grid_cells(), times anchors_per_level for the anchor family.
paramsModel shape and thresholds.
outputResult buffers.
resultReceives the record count. May be NULL.
Returns
As sp500_yolo_decode().