yolov5-face只检测一个种类,nc=1,yolov5-face的三个输出分别是
1x3x80x80x16
1x3x40x40x16
1x3x20x20x16
这里的3是指RGB三个通道,每个通道都会产生一个结果,这里的16是指x y w h boxScore x1 y1 x2 y2 x3 y3 x4 y4 x5 y5 idScore。
2.代码这里以瑞芯微的代码为例,只不过在前面和后面加上了有关padding resize的处理,瑞芯微的具体代码见rknpu/rknn/rknn_api/examples/rknn_yolov5_demo at master · rockchip-linux/rknpu · GitHub
2.1 padding resize代码瑞芯微的官方demo里面是用opencl读取图片,这里我改成了用opencv读取图片,关于opencv的交叉编译见:ubuntu交叉编译RV1126的opencv库/ubuntu交叉编译opencv
void padding_resize(cv::InputArray src, cv::OutputArray dst, cv::Size size) {
float padd_w = 0;
float padd_h = 0;
float r = std::min(float(size.width) / src.cols(), float(size.height) / src.rows());
int inside_w = round(src.cols() * r);
int inside_h = round(src.rows() * r);
padd_w = size.width - inside_w;
padd_h = size.height - inside_h;
cv::resize(src, dst, cv::Size(inside_w, inside_h));
padd_w = padd_w / 2;
padd_h = padd_h / 2;
//外层边框填充灰色
printf("gain:%f, padd_w:%f,padd_h:%f. in padding_resize============n", r, padd_w,padd_h);
int top = int(round(padd_h - 0.1));
int bottom = int(round(padd_h + 0.1));
int left = int(round(padd_w - 0.1));
int right = int(round(padd_w + 0.1));
cv::copyMakeBorder(dst, dst, top, bottom, left, right, cv::BORDER_CONSTANT, cv::Scalar(114, 114, 114));
}
cv::Mat read_image(const char *image_path, int w, int h, int & img_width, int & img_height, cv::Mat & img)
{
img = cv::imread(image_path);
img_width = img.cols;
img_height = img.rows;
cv::Mat sample_resize, sample;
padding_resize(img, sample_resize, cv::Size(w, h));
//cv::resize(img, sample_resize, cv::Size(w, h));
cv::cvtColor(sample_resize, sample, cv::COLOR_BGR2RGB);
return sample;
}
2.2 yolov5-face后处理(在瑞芯微yolov5后处理代码基础上修改)
这是瑞芯微的yolov5 demo里的代码,这里面我把坐标框后处理时影射回原图的四行代码注释掉了。然后其他代码也针对yolov5-face进行了修改。
参考文献:
yolov5输出后处理_C++实现
ubuntu交叉编译RV1126的opencv库/ubuntu交叉编译opencv
opencv实现padding resize
瑞芯微RV1126的YOLOv5官方推理demo



