Implementation:Tencent Ncnn Mat From Pixels Resize
| Knowledge Sources | |
|---|---|
| Domains | Computer_Vision, Preprocessing |
| Last Updated | 2026-02-09 00:00 GMT |
Overview
Concrete tool for converting raw pixel buffers into resized, normalized floating-point tensors provided by the ncnn library.
Description
ncnn::Mat::from_pixels_resize is a static factory method that converts a raw unsigned char pixel buffer into an ncnn::Mat floating-point tensor, simultaneously performing pixel format conversion (e.g., BGR to RGB) and bilinear resize to target dimensions. The companion method substract_mean_normalize applies per-channel mean subtraction and normalization scaling in-place.
Together, these two methods form the standard ncnn image preprocessing pipeline. The pixel format conversion is specified via the PixelType enum, which supports RGB, BGR, GRAY, RGBA, BGRA and all cross-conversions. The implementation uses SIMD-accelerated paths (NEON, SSE) for high throughput on mobile and desktop platforms.
Note: the method name substract (not subtract) is the actual spelling in the ncnn API.
Usage
Use these methods to preprocess images before inference in any classification, detection, segmentation, or other vision pipeline. Pair with OpenCV's cv::imread (or ncnn's built-in simpleocv) to load the raw pixel data first.
Code Reference
Source Location
- Repository: ncnn
- File: src/mat.h (declaration), src/mat_pixel.cpp (from_pixels_resize impl), src/mat.cpp (substract_mean_normalize impl)
- Lines: mat.h:L261-263 (from_pixels_resize decl), mat_pixel.cpp:L2524-2578 (impl), mat.h:L299 (substract_mean_normalize decl), mat.cpp:L1121 (impl)
Signature
class Mat
{
public:
// Pixel format enum
enum PixelType
{
PIXEL_RGB = 1,
PIXEL_BGR = 2,
PIXEL_GRAY = 3,
PIXEL_RGBA = 4,
PIXEL_BGRA = 5,
PIXEL_RGB2BGR = PIXEL_RGB | (PIXEL_BGR << 16),
PIXEL_BGR2RGB = PIXEL_BGR | (PIXEL_RGB << 16),
// ... all cross-conversion combinations
};
// Convert pixel buffer to Mat with resize
static Mat from_pixels_resize(
const unsigned char* pixels, // raw pixel buffer
int type, // PixelType enum value
int w, // source width
int h, // source height
int target_width, // resize target width
int target_height, // resize target height
Allocator* allocator = 0 // optional memory allocator
);
// Overload with stride parameter
static Mat from_pixels_resize(
const unsigned char* pixels,
int type,
int w, int h,
int stride, // bytes per row in source
int target_width,
int target_height,
Allocator* allocator = 0
);
// In-place mean subtraction and normalization
// pass 0 (NULL) to skip mean or norm
void substract_mean_normalize(
const float* mean_vals, // per-channel mean [3] or NULL
const float* norm_vals // per-channel scale [3] or NULL
);
};
Import
#include "mat.h"
// ncnn::Mat is in the ncnn namespace
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| pixels | const unsigned char* | Yes | Raw pixel buffer (from cv::imread or similar) |
| type | int | Yes | Pixel format enum (e.g., PIXEL_BGR, PIXEL_BGR2RGB) |
| w, h | int | Yes | Source image width and height |
| target_width, target_height | int | Yes | Desired output dimensions |
| mean_vals | const float[3] | No | Per-channel mean values for subtraction (NULL to skip) |
| norm_vals | const float[3] | No | Per-channel normalization scales (NULL to skip) |
Outputs
| Name | Type | Description |
|---|---|---|
| return (from_pixels_resize) | ncnn::Mat | Float32 tensor with shape (target_w, target_h, channels) |
| in-place (substract_mean_normalize) | void | Modifies the Mat data in-place |
Usage Examples
Classification Preprocessing (SqueezeNet)
#include "mat.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
cv::Mat bgr = cv::imread("image.jpg", 1);
// Convert BGR pixels to ncnn::Mat, resize to 227x227
ncnn::Mat in = ncnn::Mat::from_pixels_resize(
bgr.data,
ncnn::Mat::PIXEL_BGR,
bgr.cols, bgr.rows,
227, 227
);
// SqueezeNet mean values (BGR order), no normalization
const float mean_vals[3] = {104.f, 117.f, 123.f};
in.substract_mean_normalize(mean_vals, 0);
Detection Preprocessing (YOLO, normalized to 0-1)
cv::Mat bgr = cv::imread("image.jpg", 1);
// Convert BGR to RGB and resize to 640x640
ncnn::Mat in = ncnn::Mat::from_pixels_resize(
bgr.data,
ncnn::Mat::PIXEL_BGR2RGB,
bgr.cols, bgr.rows,
640, 640
);
// Normalize to [0, 1] range
const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f};
in.substract_mean_normalize(0, norm_vals);