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 SCRFD Example

From Leeroopedia


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

Overview

Concrete tool for face detection inference using SCRFD (Sample and Computation Redistribution for Face Detection) with ncnn.

Description

This example implements the SCRFD face detector, an efficient anchor-based face detection architecture from InsightFace. It loads the scrfd_500m-opt2 model (a lightweight 500K-parameter variant). The input image is resized so the longer side fits within 640 pixels while preserving aspect ratio, converted from BGR to RGB, and padded to a multiple of 32 pixels with zero-padding. Normalization uses mean=127.5 and scale=1/128 per channel.

The model produces predictions at three feature pyramid strides (8, 16, 32). For each stride, anchors are generated with a single ratio (1.0) and two scales (1.0, 2.0), with base sizes of 16, 64, and 256 respectively. Unlike RetinaFace which uses exponential delta decoding, SCRFD uses a distance-to-bbox approach: raw outputs are multiplied by the feat_stride to get pixel distances, then converted to absolute coordinates via distance2bbox() (cx-dx, cy-dy, cx+dw, cy+dh). Proposals from all three strides are merged, sorted by confidence using quicksort with OMP parallel sections, and filtered via NMS with a threshold of 0.45. The probability threshold is 0.3. Detection coordinates are adjusted for letterbox padding and rescaled to the original image dimensions. Results are drawn as green bounding boxes with confidence percentages.

Usage

Use this example for efficient face detection. SCRFD provides a good balance between speed and accuracy, particularly suitable for mobile and edge deployment.

Code Reference

Source Location

Signature

static ncnn::Mat generate_anchors(int base_size, const ncnn::Mat& ratios, const ncnn::Mat& scales);
static void generate_proposals(const ncnn::Mat& anchors, int feat_stride, const ncnn::Mat& score_blob, const ncnn::Mat& bbox_blob, float prob_threshold, std::vector<FaceObject>& faceobjects);
static int detect_scrfd(const cv::Mat& bgr, std::vector<FaceObject>& faceobjects);
static void draw_faceobjects(const cv::Mat& bgr, const std::vector<FaceObject>& faceobjects);
int main(int argc, char** argv);

Import

#include "net.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

I/O Contract

Inputs

Name Type Required Description
imagepath const char* (argv[1]) Yes Path to input image

Outputs

Name Type Description
faceobjects std::vector<FaceObject> Detected faces with bounding box (Rect_<float>) and confidence (float)
visualization cv::Mat Image with green bounding boxes and confidence labels displayed via cv::imshow

Usage Examples

Running the Example

./scrfd image.jpg

Key Code Pattern

ncnn::Net scrfd;
scrfd.opt.use_vulkan_compute = true;
scrfd.load_param("scrfd_500m-opt2.param");
scrfd.load_model("scrfd_500m-opt2.bin");

ncnn::Mat in = ncnn::Mat::from_pixels_resize(bgr.data, ncnn::Mat::PIXEL_BGR2RGB, width, height, w, h);

// Pad to multiple of 32
int wpad = (w + 31) / 32 * 32 - w;
int hpad = (h + 31) / 32 * 32 - h;
ncnn::Mat in_pad;
ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, ncnn::BORDER_CONSTANT, 0.f);

const float mean_vals[3] = {127.5f, 127.5f, 127.5f};
const float norm_vals[3] = {1 / 128.f, 1 / 128.f, 1 / 128.f};
in_pad.substract_mean_normalize(mean_vals, norm_vals);

ncnn::Extractor ex = scrfd.create_extractor();
ex.input("input.1", in_pad);

// Decode from 3 stride levels
std::vector<FaceObject> faceproposals;
// stride 8:  extract("412", score), extract("415", bbox)
// stride 16: extract("474", score), extract("477", bbox)
// stride 32: extract("536", score), extract("539", bbox)

qsort_descent_inplace(faceproposals);
nms_sorted_bboxes(faceproposals, picked, 0.45f);
// Adjust for padding offset and scale

Related Pages

Page Connections

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