update ncnn example

This commit is contained in:
jinyanhua 2022-07-08 17:09:01 +08:00
parent 6d08de2a42
commit b1d7230a61
7 changed files with 361 additions and 0 deletions

View File

@ -186,6 +186,13 @@ TRAIN:
```
python3 test.py --yaml configs/coco.yaml --weight weights/coco_ap05_0.250_280epoch.pth --img data/3.jpg --torchscript
```
## NCNN
* Need to compile ncnn and opencv in advance and modify the path in build.sh
```
cd example/ncnn/
sh build.sh
./FastestDet
```
## onnx-runtime
* You can learn about the pre and post-processing methods of FastestDet in this Sample
```

BIN
example/ncnn/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

BIN
example/ncnn/FastestDet.bin Normal file

Binary file not shown.

224
example/ncnn/FastestDet.cpp Normal file
View File

@ -0,0 +1,224 @@
#include <math.h>
#include <algorithm>
#include "net.h"
#include "benchmark.h"
#include <opencv2/opencv.hpp>
float Sigmoid(float x)
{
return 1.0f / (1.0f + exp(-x));
}
float Tanh(float x)
{
return 2.0f / (1.0f + exp(-2 * x)) - 1;
}
class TargetBox
{
private:
float GetWidth() { return (x2 - x1); };
float GetHeight() { return (y2 - y1); };
public:
int x1;
int y1;
int x2;
int y2;
int category;
float score;
float area() { return GetWidth() * GetHeight(); };
};
float IntersectionArea(const TargetBox &a, const TargetBox &b)
{
if (a.x1 > b.x2 || a.x2 < b.x1 || a.y1 > b.y2 || a.y2 < b.y1)
{
// no intersection
return 0.f;
}
float inter_width = std::min(a.x2, b.x2) - std::max(a.x1, b.x1);
float inter_height = std::min(a.y2, b.y2) - std::max(a.y1, b.y1);
return inter_width * inter_height;
}
bool scoreSort(TargetBox a, TargetBox b)
{
return (a.score > b.score);
}
//NMS处理
int nmsHandle(std::vector<TargetBox> &src_boxes, std::vector<TargetBox> &dst_boxes)
{
std::vector<int> picked;
sort(src_boxes.begin(), src_boxes.end(), scoreSort);
for (int i = 0; i < src_boxes.size(); i++)
{
int keep = 1;
for (int j = 0; j < picked.size(); j++)
{
//交集
float inter_area = IntersectionArea(src_boxes[i], src_boxes[picked[j]]);
//并集
float union_area = src_boxes[i].area() + src_boxes[picked[j]].area() - inter_area;
float IoU = inter_area / union_area;
if(IoU > 0.45 && src_boxes[i].category == src_boxes[picked[j]].category)
{
keep = 0;
break;
}
}
if (keep) {
picked.push_back(i);
}
}
for (int i = 0; i < picked.size(); i++)
{
dst_boxes.push_back(src_boxes[picked[i]]);
}
return 0;
}
int main()
{
// 类别标签
static const char* class_names[] = {
"person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light",
"fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow",
"elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee",
"skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
"tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
"sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
"potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone",
"microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear",
"hair drier", "toothbrush"
};
// 类别数量
int class_num = sizeof(class_names) / sizeof(class_names[0]);
// 阈值
float thresh = 0.65;
// 模型输入宽高
int input_width = 352;
int input_height = 352;
// 加载模型
ncnn::Net net;
net.load_param("FastestDet.param");
net.load_model("FastestDet.bin");
printf("ncnn model load sucess...\n");
// 加载图片
cv::Mat img = cv::imread("1.jpg");
int img_width = img.cols;
int img_height = img.rows;
// resize of input image data
ncnn::Mat input = ncnn::Mat::from_pixels_resize(img.data, ncnn::Mat::PIXEL_BGR,\
img.cols, img.rows, input_width, input_height);
// Normalization of input image data
const float mean_vals[3] = {0.f, 0.f, 0.f};
const float norm_vals[3] = {1/255.f, 1/255.f, 1/255.f};
input.substract_mean_normalize(mean_vals, norm_vals);
// creat extractor
ncnn::Extractor ex = net.create_extractor();
ex.set_num_threads(1);
double start = ncnn::get_current_time();
//set input tensor
ex.input("in0", input);
// get output tensor
ncnn::Mat output;
ex.extract("out0", output);
printf("output: %d, %d, %d\n", output.c, output.h, output.w);
// handle output tensor
std::vector<TargetBox> target_boxes;
for (int h = 0; h < output.h; h++)
{
for (int w = 0; w < output.h; w++)
{
// 前景概率
int obj_score_index = (0 * output.h * output.w) + (h * output.w) + w;
float obj_score = output[obj_score_index];
// 解析类别
int category;
float max_score = 0.0f;
for (size_t i = 0; i < class_num; i++)
{
int obj_score_index = ((5 + i) * output.h * output.w) + (h * output.w) + w;
float cls_score = output[obj_score_index];
if (cls_score > max_score)
{
max_score = cls_score;
category = i;
}
}
float score = max_score * obj_score;
// 阈值筛选
if(score > thresh)
{
// 解析坐标
int x_offset_index = (1 * output.h * output.w) + (h * output.w) + w;
int y_offset_index = (2 * output.h * output.w) + (h * output.w) + w;
int box_width_index = (3 * output.h * output.w) + (h * output.w) + w;
int box_height_index = (4 * output.h * output.w) + (h * output.w) + w;
float x_offset = Tanh(output[x_offset_index]);
float y_offset = Tanh(output[y_offset_index]);
float box_width = Sigmoid(output[box_width_index]);
float box_height = Sigmoid(output[box_height_index]);
float cx = (w + x_offset) / output.w;
float cy = (h + y_offset) / output.h;
int x1 = (int)((cx - box_width * 0.5) * img_width);
int y1 = (int)((cy - box_height * 0.5) * img_height);
int x2 = (int)((cx + box_width * 0.5) * img_width);
int y2 = (int)((cy + box_height * 0.5) * img_height);
target_boxes.push_back(TargetBox{x1, y1, x2, y2, category, score});
}
}
}
// NMS处理
std::vector<TargetBox> nms_boxes;
nmsHandle(target_boxes, nms_boxes);
// 打印耗时
double end = ncnn::get_current_time();
double time = end - start;
printf("Time:%7.2f ms\n",time);
// draw result
for (size_t i = 0; i < nms_boxes.size(); i++)
{
TargetBox box = nms_boxes[i];
printf("x1:%d y1:%d x2:%d y2:%d %s:%.2f%%\n", box.x1, box.y1, box.x2, box.y2, class_names[box.category], box.score * 100);
cv::rectangle(img, cv::Point(box.x1, box.y1), cv::Point(box.x2, box.y2), cv::Scalar(0, 0, 255), 2);
cv::putText(img, class_names[box.category], cv::Point(box.x1, box.y1), cv::FONT_HERSHEY_SIMPLEX, 0.75, cv::Scalar(0, 255, 0), 2);
}
cv::imwrite("result.jpg", img);
return 0;
}

View File

@ -0,0 +1,129 @@
7767517
127 150
Input in0 0 1 in0
Convolution convrelu_0 1 1 in0 1 0=24 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=648 9=1
Pooling maxpool2d_43 1 1 1 2 0=0 1=3 11=3 12=2 13=1 2=2 3=1 5=1
Split splitncnn_0 1 2 2 3 4
ConvolutionDepthWise convdw_95 1 1 4 5 0=24 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=216 7=24
Convolution convrelu_1 1 1 3 6 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=576 9=1
ConvolutionDepthWise convdw_96 1 1 6 7 0=24 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=216 7=24
Convolution convrelu_3 1 1 5 8 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=576 9=1
Convolution convrelu_2 1 1 7 9 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=576 9=1
Concat cat_0 2 1 8 9 10 0=0
ShuffleChannel shufflechannel_0 1 1 10 11 0=2 1=1
Slice shufflechannel_0_slice 1 2 11 12 13 -23300=2,-233,-233 1=0
Convolution convrelu_4 1 1 13 14 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=576 9=1
ConvolutionDepthWise convdw_97 1 1 14 15 0=24 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=216 7=24
Convolution convrelu_5 1 1 15 16 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=576 9=1
Concat cat_1 2 1 12 16 17 0=0
ShuffleChannel shufflechannel_1 1 1 17 18 0=2 1=1
Slice shufflechannel_1_slice 1 2 18 19 20 -23300=2,-233,-233 1=0
Convolution convrelu_6 1 1 20 21 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=576 9=1
ConvolutionDepthWise convdw_98 1 1 21 22 0=24 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=216 7=24
Convolution convrelu_7 1 1 22 23 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=576 9=1
Concat cat_2 2 1 19 23 24 0=0
ShuffleChannel shufflechannel_2 1 1 24 25 0=2 1=1
Slice shufflechannel_2_slice 1 2 25 26 27 -23300=2,-233,-233 1=0
Convolution convrelu_8 1 1 27 28 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=576 9=1
ConvolutionDepthWise convdw_99 1 1 28 29 0=24 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=216 7=24
Convolution convrelu_9 1 1 29 30 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=576 9=1
Concat cat_3 2 1 26 30 31 0=0
Split splitncnn_1 1 3 31 32 33 34
ConvolutionDepthWise convdw_100 1 1 34 35 0=48 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=432 7=48
Convolution convrelu_10 1 1 33 36 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
ConvolutionDepthWise convdw_101 1 1 36 37 0=48 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=432 7=48
Convolution convrelu_12 1 1 35 38 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
Convolution convrelu_11 1 1 37 39 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
Concat cat_4 2 1 38 39 40 0=0
ShuffleChannel shufflechannel_3 1 1 40 41 0=2 1=1
Slice shufflechannel_3_slice 1 2 41 42 43 -23300=2,-233,-233 1=0
Convolution convrelu_13 1 1 43 44 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
ConvolutionDepthWise convdw_102 1 1 44 45 0=48 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=432 7=48
Convolution convrelu_14 1 1 45 46 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
Concat cat_5 2 1 42 46 47 0=0
ShuffleChannel shufflechannel_4 1 1 47 48 0=2 1=1
Slice shufflechannel_4_slice 1 2 48 49 50 -23300=2,-233,-233 1=0
Convolution convrelu_15 1 1 50 51 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
ConvolutionDepthWise convdw_103 1 1 51 52 0=48 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=432 7=48
Convolution convrelu_16 1 1 52 53 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
Concat cat_6 2 1 49 53 54 0=0
ShuffleChannel shufflechannel_5 1 1 54 55 0=2 1=1
Slice shufflechannel_5_slice 1 2 55 56 57 -23300=2,-233,-233 1=0
Convolution convrelu_17 1 1 57 58 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
ConvolutionDepthWise convdw_104 1 1 58 59 0=48 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=432 7=48
Convolution convrelu_18 1 1 59 60 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
Concat cat_7 2 1 56 60 61 0=0
ShuffleChannel shufflechannel_6 1 1 61 62 0=2 1=1
Slice shufflechannel_6_slice 1 2 62 63 64 -23300=2,-233,-233 1=0
Convolution convrelu_19 1 1 64 65 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
ConvolutionDepthWise convdw_105 1 1 65 66 0=48 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=432 7=48
Convolution convrelu_20 1 1 66 67 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
Concat cat_8 2 1 63 67 68 0=0
ShuffleChannel shufflechannel_7 1 1 68 69 0=2 1=1
Slice shufflechannel_7_slice 1 2 69 70 71 -23300=2,-233,-233 1=0
Convolution convrelu_21 1 1 71 72 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
ConvolutionDepthWise convdw_106 1 1 72 73 0=48 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=432 7=48
Convolution convrelu_22 1 1 73 74 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
Concat cat_9 2 1 70 74 75 0=0
ShuffleChannel shufflechannel_8 1 1 75 76 0=2 1=1
Slice shufflechannel_8_slice 1 2 76 77 78 -23300=2,-233,-233 1=0
Convolution convrelu_23 1 1 78 79 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
ConvolutionDepthWise convdw_107 1 1 79 80 0=48 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=432 7=48
Convolution convrelu_24 1 1 80 81 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
Concat cat_10 2 1 77 81 82 0=0
ShuffleChannel shufflechannel_9 1 1 82 83 0=2 1=1
Slice shufflechannel_9_slice 1 2 83 84 85 -23300=2,-233,-233 1=0
Convolution convrelu_25 1 1 85 86 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
ConvolutionDepthWise convdw_108 1 1 86 87 0=48 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=432 7=48
Convolution convrelu_26 1 1 87 88 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1
Concat cat_11 2 1 84 88 89 0=0
Split splitncnn_2 1 3 89 90 91 92
ConvolutionDepthWise convdw_109 1 1 92 93 0=96 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 7=96
Convolution convrelu_27 1 1 91 94 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=9216 9=1
ConvolutionDepthWise convdw_110 1 1 94 95 0=96 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 7=96
Convolution convrelu_29 1 1 93 96 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=9216 9=1
Convolution convrelu_28 1 1 95 97 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=9216 9=1
Concat cat_12 2 1 96 97 98 0=0
ShuffleChannel shufflechannel_10 1 1 98 99 0=2 1=1
Slice shufflechannel_10_slice 1 2 99 100 101 -23300=2,-233,-233 1=0
Convolution convrelu_30 1 1 101 102 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=9216 9=1
ConvolutionDepthWise convdw_111 1 1 102 103 0=96 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=864 7=96
Convolution convrelu_31 1 1 103 104 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=9216 9=1
Concat cat_13 2 1 100 104 105 0=0
ShuffleChannel shufflechannel_11 1 1 105 106 0=2 1=1
Slice shufflechannel_11_slice 1 2 106 107 108 -23300=2,-233,-233 1=0
Convolution convrelu_32 1 1 108 109 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=9216 9=1
ConvolutionDepthWise convdw_112 1 1 109 110 0=96 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=864 7=96
Convolution convrelu_33 1 1 110 111 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=9216 9=1
Concat cat_14 2 1 107 111 112 0=0
ShuffleChannel shufflechannel_12 1 1 112 113 0=2 1=1
Slice shufflechannel_12_slice 1 2 113 114 115 -23300=2,-233,-233 1=0
Convolution convrelu_34 1 1 115 116 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=9216 9=1
ConvolutionDepthWise convdw_113 1 1 116 117 0=96 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=864 7=96
Convolution convrelu_35 1 1 117 118 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=9216 9=1
Concat cat_15 2 1 114 118 119 0=0
Pooling avgpool2d_0 1 1 32 120 0=1 1=3 11=3 12=2 13=1 2=2 3=1 5=1 6=1
Interp upsample_94 1 1 119 121 0=1 1=2.000000e+00 2=2.000000e+00 6=0
Concat cat_16 3 1 120 90 121 122 0=0
Convolution convrelu_36 1 1 122 123 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32256 9=1
Split splitncnn_3 1 4 123 124 125 126 127
ConvolutionDepthWise convdwrelu_5 1 1 127 128 0=96 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=2400 7=96 9=1
ConvolutionDepthWise convdwrelu_0 1 1 126 129 0=96 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=2400 7=96 9=1
ConvolutionDepthWise convdwrelu_4 1 1 129 130 0=96 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=2400 7=96 9=1
ConvolutionDepthWise convdwrelu_1 1 1 125 131 0=96 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=2400 7=96 9=1
ConvolutionDepthWise convdwrelu_2 1 1 131 132 0=96 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=2400 7=96 9=1
ConvolutionDepthWise convdwrelu_3 1 1 132 133 0=96 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=2400 7=96 9=1
Concat cat_17 3 1 128 130 133 134 0=0
Convolution conv_38 1 1 134 135 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=27648
BinaryOp add_0 2 1 124 135 136 0=0
ReLU relu_87 1 1 136 137
Convolution convrelu_37 1 1 137 138 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=9216 9=1
Split splitncnn_4 1 3 138 139 140 141
ConvolutionDepthWise convdwrelu_7 1 1 139 142 0=96 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=2400 7=96 9=1
Convolution conv_41 1 1 142 143 0=80 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=7680
ConvolutionDepthWise convdwrelu_8 1 1 140 144 0=96 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=2400 7=96 9=1
Convolution conv_42 1 1 144 145 0=4 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=384
Softmax softmax_93 1 1 143 146 0=0 1=1
ConvolutionDepthWise convdwrelu_6 1 1 141 147 0=96 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=2400 7=96 9=1
Convolution convsigmoid_38 1 1 147 148 0=1 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=96 9=4
Concat cat_18 3 1 148 145 146 out0 0=0

1
example/ncnn/build.sh Normal file
View File

@ -0,0 +1 @@
g++ -o FastestDet FastestDet.cpp -I include/ncnn lib/libncnn.a `pkg-config --libs --cflags opencv` -fopenmp

BIN
example/ncnn/result.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB