Implementation:Tencent Ncnn Mat Pixel Affine
| Knowledge Sources | |
|---|---|
| Domains | Computer Vision, Image Processing |
| Last Updated | 2026-02-09 19:00 GMT |
Overview
Implements affine transformation operations on pixel images, including rotation matrix computation, affine transform estimation from point correspondences, affine transform inversion, and bilinear-interpolated warp affine for 1-4 channel images and YUV420SP.
Description
This file provides several core functions for affine image transformations within the ncnn framework. get_rotation_matrix() computes a 2x3 affine matrix from an angle (in degrees), a scale factor, and a center point. get_affine_transform() estimates an affine transform from corresponding source and destination point pairs by solving a 4x4 linear system using explicit matrix inversion via the cofactor method. invert_affine_transform() computes the inverse of a 2x3 affine matrix.
The core functions are warpaffine_bilinear_c1/c2/c3/c4 which apply an affine transformation with bilinear interpolation. They use fixed-point arithmetic with 10-bit fractional precision for coordinate mapping to avoid floating-point operations in the inner loop. The implementation uses boundary-aware fast paths: it checks whether a block of 8 output pixels all map within the source image bounds to use a branchless inner loop, or falls back to per-pixel boundary checking when near edges. Border handling supports constant fill, replicate, and transparent modes.
Overloaded versions accept either implicit or explicit stride parameters. A warpaffine_bilinear_yuv420sp variant handles YUV420SP (NV12/NV21) formatted data by processing the Y plane and UV plane separately. The entire file is guarded by the NCNN_PIXEL_AFFINE compile-time flag.
Usage
Use these functions for face alignment (mapping detected face landmarks to a canonical pose), data augmentation, perspective correction, and any other image preprocessing that requires affine warping before neural network inference. These functions operate directly on raw pixel buffers without requiring OpenCV.
Code Reference
Source Location
- Repository: Tencent_Ncnn
- File: src/mat_pixel_affine.cpp
Signature
// Compute a 2x3 rotation matrix from angle, scale, and center
void get_rotation_matrix(float angle, float scale, float dx, float dy, float* tm);
// Estimate an affine transform from point correspondences
void get_affine_transform(const float* points_from, const float* points_to, int num_point, float* tm);
// Invert a 2x3 affine transform matrix
void invert_affine_transform(const float* tm, float* tm_inv);
// Warp affine with bilinear interpolation (implicit stride)
void warpaffine_bilinear_c1(const unsigned char* src, int srcw, int srch,
unsigned char* dst, int w, int h, const float* tm, int type, unsigned int v);
void warpaffine_bilinear_c2(const unsigned char* src, int srcw, int srch,
unsigned char* dst, int w, int h, const float* tm, int type, unsigned int v);
void warpaffine_bilinear_c3(const unsigned char* src, int srcw, int srch,
unsigned char* dst, int w, int h, const float* tm, int type, unsigned int v);
void warpaffine_bilinear_c4(const unsigned char* src, int srcw, int srch,
unsigned char* dst, int w, int h, const float* tm, int type, unsigned int v);
// Warp affine with bilinear interpolation (explicit stride)
void warpaffine_bilinear_c1(const unsigned char* src, int srcw, int srch, int srcstride,
unsigned char* dst, int w, int h, int stride, const float* tm, int type, unsigned int v);
void warpaffine_bilinear_c2(const unsigned char* src, int srcw, int srch, int srcstride,
unsigned char* dst, int w, int h, int stride, const float* tm, int type, unsigned int v);
void warpaffine_bilinear_c3(const unsigned char* src, int srcw, int srch, int srcstride,
unsigned char* dst, int w, int h, int stride, const float* tm, int type, unsigned int v);
void warpaffine_bilinear_c4(const unsigned char* src, int srcw, int srch, int srcstride,
unsigned char* dst, int w, int h, int stride, const float* tm, int type, unsigned int v);
// YUV420SP variant
void warpaffine_bilinear_yuv420sp(const unsigned char* src, int srcw, int srch,
unsigned char* dst, int w, int h, const float* tm, int type, unsigned int v);
Import
#include "mat.h"
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| src | const unsigned char* | Yes | Source image pixel buffer |
| srcw | int | Yes | Source image width in pixels |
| srch | int | Yes | Source image height in pixels |
| srcstride | int | No | Source row stride in bytes (defaults to srcw * channels) |
| dst | unsigned char* | Yes | Destination image pixel buffer (pre-allocated) |
| w | int | Yes | Destination image width in pixels |
| h | int | Yes | Destination image height in pixels |
| stride | int | No | Destination row stride in bytes (defaults to w * channels) |
| tm | const float* | Yes | 2x3 affine transformation matrix (6 floats) |
| type | int | Yes | Border handling mode (constant, replicate, or transparent) |
| v | unsigned int | Yes | Fill value for constant border mode |
Outputs
| Name | Type | Description |
|---|---|---|
| dst | unsigned char* | Destination buffer filled with the affine-warped image |
| tm (get_rotation_matrix) | float* | Computed 2x3 rotation matrix |
| tm (get_affine_transform) | float* | Estimated 2x3 affine transform matrix |
| tm_inv (invert_affine_transform) | float* | Inverted 2x3 affine transform matrix |
Usage Examples
Face Alignment with Rotation Matrix
#include "mat.h"
// Compute rotation matrix centered at (112, 112) with 30-degree rotation
float tm[6];
ncnn::get_rotation_matrix(30.0f, 1.0f, 112.0f, 112.0f, tm);
// Apply affine warp to a 3-channel RGB image
unsigned char dst[224 * 224 * 3];
ncnn::warpaffine_bilinear_c3(src_pixels, src_w, src_h,
dst, 224, 224, tm, 0, 0);
Affine Transform from Landmark Points
#include "mat.h"
// 5 source landmark points and 5 target landmark points
float src_points[10] = { /* x0,y0, x1,y1, ... */ };
float dst_points[10] = { /* x0,y0, x1,y1, ... */ };
float tm[6];
ncnn::get_affine_transform(src_points, dst_points, 5, tm);
// Warp the face region to canonical alignment
unsigned char aligned[112 * 112 * 3];
ncnn::warpaffine_bilinear_c3(src_pixels, src_w, src_h,
aligned, 112, 112, tm, 0, 0);