1. 模型介绍
Github:https://github.com/Linzaer/Ultra-Light-Fast-Generic-Face-Detector-1MB
一个轻量级人脸检测模型,提供了Slim-320(速度更快)和RFB-320(精度更高)两个版本,并提供Caffe推理脚本。在产品上部署Slim-320做人脸检测,腾讯TNN提供的人脸检测Demo同样使用的该模型。
运行效果:
2. 生成预选框
模型采用4个分支做预测,每个分支的基础anchor分别为3,2,2,3个:
min_boxes = [[10, 16, 24], [32, 48], [64, 96], [128, 192, 256]]
输入图片的size为240x320,通过设置步长[ 8.0, 16.0, 32.0, 64.0]
产生四种尺寸的特征图:40 x 30, 20 x 15, 10 x 8, 5 x 4
通过步长和基础anchor,产生了30x40x3 + 20x15x2 + 10x8x2 + 5x4x3 = 4420
组预选框,产生的方式为:
void CreateAnchors(int image_w, int image_h)
{
auto w_h_list = {image_w, image_h};
for (auto size : w_h_list)
{
std::vector<float> item;
for (auto stride : strides)
{
item.push_back(ceil(size / stride));
}
featuremap_size.push_back(item);
}
for (auto size : w_h_list)
{
shrinkage_size.push_back(strides);
}
for(int index = 0; index < FeatureMap; index++)
{
float scale_w = image_w / featuremap_size[0][index];
float scale_h = image_h / featuremap_size[1][index];
for(int i = 0; i < featuremap_size[1][index]; ++i)
{
for (int j = 0; j < featuremap_size[0][index]; ++j)
{
float x_center = (i + 0.5) / scale_w;
float y_center = (j + 0.5) / scale_h;
for (float k : min_boxes[index])
{
float w = k / image_w;
float h = k / image_h;
priors.push_back({clip(x_center, 1), clip(y_center, 1), clip(w, 1), clip(h, 1)});
}
}
}
}
}
3. 推理结果
模型推理完成后,shape为(4420, 4)的Boxes输出包含所有预选框的坐标,shape为(4420, 2)的Scores输出包含每个预选框的置信度。通过NMS筛选后,得到正确结果。