android系统部署Yolov5和Yolo11不同版本模型
·
yolov5和yolo11训练生成的检测模型均可通过ncnn转换为在android端运行的文件,查看大小,yolov5s和yolo11n的bin文件大小分别是28M和5M,感觉对yolo11精度有点不太自信了。同时部署两个版本的模型以防万一。
yolov5版本的cpp文件为yolov5_ncnn_jni.cpp,yolo11则有多个文件,初准备两版本模型用不同的cmake编译,但仅后一个能正确编译生成相应的so文件。
/*cmake {
version "3.22.1"
path file('libs/CMakeLists.txt')
}*/
cmake {
version '3.22.1'
path file('libs/y11/CMakeLists.txt')
}
比较其模型载入和检测,其主要区别在于yolov5的stride8,16,32是三个不同的值,而yolo11为一个值
ex.input("images", in_pad);
std::vector<DetectRes> proposals;
// anchor setting from yolov5/models/yolov5s.yaml
{// stride 8
ncnn::Mat out;
ex.extract("output", out);//output397
ncnn::Mat anchors(6);
anchors[0] = 10.f;
anchors[1] = 13.f;
anchors[2] = 16.f;
anchors[3] = 30.f;
anchors[4] = 33.f;
anchors[5] = 23.f;
std::vector<DetectRes> objects8;
generateProposals(anchors, 8, in_pad, out, prob_threshold, objects8);
proposals.insert(proposals.end(), objects8.begin(), objects8.end());
}
{// stride 16
ncnn::Mat out;
ex.extract("417", out);//781,458
ncnn::Mat anchors(6);
anchors[0] = 30.f;
anchors[1] = 61.f;
anchors[2] = 62.f;
anchors[3] = 45.f;
anchors[4] = 59.f;
anchors[5] = 119.f;
std::vector<DetectRes> objects16;
generateProposals(anchors, 16, in_pad, out, prob_threshold, objects16);
proposals.insert(proposals.end(), objects16.begin(), objects16.end());
}
{// stride 32
ncnn::Mat out;
ex.extract("437", out);//801,519
ncnn::Mat anchors(6);
anchors[0] = 116.f;
anchors[1] = 90.f;
anchors[2] = 156.f;
anchors[3] = 198.f;
anchors[4] = 373.f;
anchors[5] = 326.f;
std::vector<DetectRes> objects32;
generateProposals(anchors, 32, in_pad, out, prob_threshold, objects32);
proposals.insert(proposals.end(), objects32.begin(), objects32.end());
}
而yolo11则为
ex.input("in0", in_pad);
ncnn::Mat out;
ex.extract("out0", out);
std::vector<DetectRes> proposals;
generate_proposals(out, strides, in_pad, prob_threshold, proposals);
编译后运行,提示 layer 层not exist or register。
查看yolov5 param文件,新增了一层YoloV5 focus
Input images 0 1 images
YoloV5 focus 1 1 images 167
重定义初始化
class YoloV5 : public ncnn::Layer {
public:
YoloV5() {
one_blob_only = true;
}
virtual int
forward(const ncnn::Mat &bottom_blob, ncnn::Mat &top_blob, const ncnn::Option &opt) const {
int w = bottom_blob.w;
int h = bottom_blob.h;
int channels = bottom_blob.c;
int outw = w / 2;
int outh = h / 2;
int outc = channels * 4;
top_blob.create(outw, outh, outc, 4u, 1, opt.blob_allocator);//.workspace_allocator);//)
if (top_blob.empty())
return -100;
#pragma omp parallel for num_threads(opt.num_threads)
for (int p = 0; p < outc; p++) {
const float *ptr = bottom_blob.channel(p % channels).row((p / channels) % 2) +
((p / channels) / 2);
float *outptr = top_blob.channel(p);
for (int i = 0; i < outh; i++) {
for (int j = 0; j < outw; j++) {
*outptr = *ptr;
outptr += 1;
ptr += 2;
}
ptr += w;
}
}
return 0;
}
};
DEFINE_LAYER_CREATOR(YoloV5)
并在代码中注册该层
if (yModVal == 5) {//yolo5 模型自定义层
yolo.register_custom_layer("YoloV5", YoloV5_layer_creator);
}
成功!
更多推荐



所有评论(0)