Skip to main content
Associate
July 11, 2026
Question

STM32MP257F-DK SSD MobileNet Object Detection: nn_post_proc() fails with official Model Zoo ONNX models + DCMIPP 300*300 stream configuration

  • July 11, 2026
  • 1 reply
  • 43 views

Hi ST Team,

We are developing a custom Qt 6 + OpenGL object detection application on the STM32MP257F-DK using OpenSTLinux 6.6, X-LINUX-AI, and the ONNX Runtime (stai_mpu) backend.

Our application architecture is based on the official ST object detection example. We use the same stai_mpu_wrapper and ssd_mobilenet_pp.hpp post-processing implementation from the stai_mpu_object_detection example, while replacing the GTK/Cairo UI with our own Qt/OpenGL application.

Application Architecture

  • Board: STM32MP257F-DK

  • OS: OpenSTLinux 6.6

  • AI Backend: ONNX Runtime (libstai_mpu_ort.so.6)

  • Camera: libcamera + DCMIPP

  • Display: Qt 6 + OpenGL (Wayland/Weston)

  • Camera Pipeline:

    • Viewfinder stream → RGB565 → OpenGL live preview

    • AI stream → RGB888 → STAI inference

  • Inference: stai_mpu_wrapper::RunInference()

  • Post-processing: Official ssd_mobilenet_pp.hpp from the ST stai_mpu_object_detection example.

 

1. DCMIPP camera configuration issue

Our AI model requires a 300×300 RGB888 input, so we configured:

cfg_npu.size.width  = 300;
cfg_npu.size.height = 300;
cfg_npu.pixelFormat = libcamera::formats::RGB888;

However, camera->configure() fails with:


ERROR DCMIPP dcmipp_path.cpp:448 Unable to configure capture in 300x300-RGB888 got instead: 304x300-BGR3
ERROR DCMIPP dcmipp.cpp:677 Failed to configure path
[04:14:22] ❌ CRITICAL: camera->configure failed with error code: -22

Changing the stream to 304×300 RGB888 allows the pipeline to start successfully.

Current workaround:

  • Capture at 304×300

  • Remove the extra 4 pixels & changing BGR3 to RGB888 in software

  • Feed a 300×300 tensor to the AI model

Question:

Is the 304-pixel width a mandatory DCMIPP alignment requirement, or is there an ISP/DCMIPP configuration that can output a true 300×300 RGB888 image without software cropping?

 

 

2. SSD MobileNet post-processing failure

Before implementing our application, we evaluated the STM32AI Model Zoo object detection models supported for STM32MP25.

Initially, we explored the available YOLO models (YOLOv2, YOLOv5, YOLOv8, etc.). However, since the current ST object detection reference application (stai_mpu_object_detection) and its associated post-processing implementation (ssd_mobilenet_pp.hpp) are designed specifically for SSD MobileNet, we decided to first integrate the officially supported SSD workflow before extending our application to other architectures.

From the Model Zoo, we therefore tested the official SSD models:

  • ssd_mobilenetv1_pt_coco_300_qdq_int8.onnx
  • ssd_mobilenetv2_pt_coco_300_qdq_int8.onnx

We also noticed that the current ssd_mobilenet_pp.hpp provides decoding support for SSD MobileNet V1 and SSD MobileNet V2 only. There is currently no equivalent post-processing implementation for SSD MobileNet V3 or other object detection architectures in the reference example.

Inference status

The inference pipeline itself executes successfully.

  • Camera capture works correctly.
  • Image preprocessing completes successfully.
  • stai_mpu_wrapper::RunInference() executes successfully.
  • ONNX Runtime loads the model correctly.
  • ONNX Runtime returns valid output tensors.

The failure occurs only during the official ST post-processing stage:

nn_postproc::nn_post_proc(...)

Runtime error:

[ORT] Failed: Index exceeding number of outputs.

Output inspection

To verify the model outputs, we inspected the ONNX model directly using ONNX Runtime:

sess.get_outputs()

Both official Model Zoo SSD models return exactly two outputs:

Output 0
Shape = [1,3000,81]

Output 1
Shape = [1,3000,4]

However, the official ssd_mobilenet_pp.hpp used in the ST object detection example expects three outputs:

get_output(0) -> class predictions
get_output(1) -> box encodings
get_output(2) -> anchors

Since the third output is not present in these official Model Zoo ONNX models, the following call fails:

nn_model->get_output(2);

resulting in:

[ORT] Failed: Index exceeding number of outputs.

 

Questions

 

  1. What is the standard library used to decode different types of YOLO output tensors in an embedded framework ?

  2. Are the current STM32AI Model Zoo SSD ONNX models intentionally exported with only two outputs?

  3. Is there an updated version of ssd_mobilenet_pp.hpp compatible with these SSD MobileNet ONNX models?

  4. Is there an official 256×256 SSD MobileNet model (or recommended anchor configuration) for STM32MP25?

  5. Is the 304×300 RGB888 DCMIPP configuration expected, or should a true 300×300 RGB888 stream be supported?

Our long-term objective is to build a generic object detection framework supporting SSD MobileNet, SSDLite, and YOLO models on STM32MP25 while remaining compatible with the X-LINUX-AI ecosystem.

Any guidance or updated reference implementation from the ST engineering team would be greatly appreciated.

Thank you.

1 reply

Erwan SZYMANSKI
ST Technical Moderator
July 17, 2026

Hello ​@Dhanakrishna_Chaitanya,
I forward you the answer provided by Embedded AI team member that took time to analyse your point.

--------------------------------

1. What is the standard library used to decode different types of YOLO output tensors in an embedded framework?

 

YOLO models come from Ultralytics. I’m not sure what you mean by “standard library,” but all the information related to YOLO models and post-processing, with examples, can be found on the Ultralytics website and GitHub:

 

https://docs.ultralytics.com/
GitHub - ultralytics/ultralytics: Ultralytics YOLO26, YOLO11, YOLOv8 — object detection, instance se…

 

In X-LINUX-AI, we do not provide any object detection example using a YOLO model. However, we do provide an example of pose estimation using YOLOv8. The model post-processing is included and can be easily adapted to an object detection use case.

 

2. Are the current STM32AI Model Zoo SSD ONNX models intentionally exported with only two outputs?

 

The object detection application in X-LINUX-AI was released several years ago. At that time, we were using SSD MobileNet V2 FPN Lite with a 256x256 resolution.
This model can be found in the recipes-samples/object-detection/models/ directory of X-LINUX-AI, or in previous versions of the STM32AI Model Zoo: https://github.com/STMicroelectronics/stm32ai-modelzoo/tree/v3.2.0/object_detection/ssd_mobilenet_v…

 

However, this model has been removed since version 4.0.0 of the Model Zoo.

 

This model was optimized for the STM32MP25 NPU and delivered as an NBG file in X-LINUX-AI. The input resolution is 256x256x3, and the model has 3 outputs. The post-processing provided in our application is only applicable to this model. If you want to use another model, it is necessary to adapt the post-processing accordingly.

 

As you mentioned, the post-processing file also supports SSD MobileNet V1 300x300, which is the model used for the MP1 series on CPU. This model is also provided directly in ONNX format in the recipes-samples/object-detection/models/ directory of X-LINUX-AI. The TFLite model is downloaded when generating the Debian package object-detect-models-ssd-mobilenet-v1-10-300.

 

This is why the models from the latest version of the Model Zoo are not directly usable in X-LINUX-AI applications. You therefore have two options:

 

- use the models provided directly in X-LINUX-AI;
- adapt the application post-processing to match the new model you are using.

 

3. Is there an updated version of ssd_mobilenet_pp.hpp compatible with these SSD MobileNet ONNX models?

 

No, there is no updated version of the post-processing for X-LINUX-AI applications.

 

X-LINUX-AI is a demonstrator designed to showcase what is possible on the STM32MPU series, and the applications and source code are delivered as examples.

 

4. Is there an official 256×256 SSD MobileNet model, or recommended anchor configuration, for STM32MP25?

 

As mentioned previously, SSD MobileNet V2 FPN Lite with 256x256 resolution is provided with the X-LINUX-AI package on target, and also in the X-LINUX-AI GitHub repository.

 

5. Is the 304×300 RGB888 DCMIPP configuration expected, or should a true 300×300 RGB888 stream be supported?

 

There are two aspects to consider here.

 

First, DCMIPP should be configurable to the nearest pixel, so in principle, trying to configure it through Libcamera with a resolution of 300x300 should not trigger any error.

 

Second, we are aware of a hardware limitation in the DCMIPP pixel packer: the output resolution must be aligned to 16 pixels. To work around this limitation and account for the DCMIPP behavior, our application uses the following function: gst_preprocess_buffer(GstMapInfo& info, int width, int height, int nnInputWidth)
This function helps us handle the actual buffer resolution and stride provided by GStreamer.

 

As mentioned in the function comments:

 

"DCMIPP pixelpacker has a constraint on the output resolution that should be a multiple of 16.
The allocated buffer may contain stride to handle the DCMIPP HW constraints.
The following code allows handling both cases by anticipating the size of the allocated buffer according to the NN resolution."

 

Since 300x300 is not a multiple of 16, DCMIPP automatically adjusts the buffer shape and fills it to match the expected resolution, which becomes 304x300.

 

The gst_preprocess_buffer function is called from new_sample to extract the input buffer information and handle the stride before running inference:

 

if (camera_src_str == "LIBCAMERA") {
    /* Preprocess the camera buffer */
    std::vector<uint8_t> nn_input_sample;
    nn_input_sample = gst_preprocess_buffer(info, width, height, data->nn_input_width);

 

    /* Execute the inference */
    nn_inference(nn_input_sample.data());
}

 

These helper functions are used throughout our example applications to handle this limitation automatically. That said, using the original SSD MobileNet V2 at 256x256 would avoid the issue entirely, since 256 is a multiple of 16.


Kind regards,
Erwan.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.