爱笑的小姐姐 · 2021年06月22日

NCNN Yolov5 Android apk开发记录

本文转自:知乎
作者:djh

一、环境准备

1.yolov5

https://github.com/ultralytics/yolov5​github.com

1、git clone 改模型。

2、下载预编译的模型,这里使用yolov5s

2.ncnn

Releases · Tencent/ncnn​github.com!(https://pic2.zhimg.com/v2-f7e555885da850c975679ac2dcf22089_ipico.jpg)

1、git clone。然后根据文档编译出tool工具,方便等下转换

2、下载Android的预编译模型库,方便等下开发apk。

3.其他

python 安装好:

pytorch的环境。
pip install -U onnx --user
pip install -U onnxruntime --user
pip install -U onnx-simplifier --user

安装好AndroidStudio的环境

二、转换模型

1.转换成onnx

将模型放到目录下直接转换成onnx

python models/export.py --weights yolov5s.pt

但是这里会出现算子转换不过去的问题

Unsupported slice step !
Unsupported slice step !

所以有几个修改的地方

修改1:640修改成320,速度的考虑

    parser.add_argument('--img-size', nargs='+', type=int, default=[320, 320], help='image size')  # height, width

修改2:export 设置为True,后面的计算层不要了

    model.model[-1].export = True # set Detect() layer export=True

修改3:common.py下的Focus 去除slice数组操作,这样精度有损失

class Focus(nn.Module):
 # Focus wh information into c-space
 def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groups
     super(Focus, self).__init__()
     self.conv = Conv(c1 * 4, c2, k, s, p, g, act)

 def forward(self, x):  # x(b,c,w,h) -> y(b,4c,w/2,h/2)
    return self.conv(torch.cat([x,x,x,x],1))
    # return self.conv(torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1))

修改4:导出版本号修改成11,去除class分类,用output

torch.onnx.export(model, img, f, verbose=False, opset_version=11, input_names=['images'],
 output_names=['output'])

再跑下导出onnx

python models/export.py --weights yolov5s.pt

简化onnx

python -m onnxsim yolov5s.onnx yolov5ssim.onnx

2.转换成ncnn模型

./onnx2ncnn yolov5ssim.onnx yolov5ssim.param yolov5ssim.bin

导出后。这里我们后面制作apk的使用使用了三个输出节点,但是每个人的是不一样的,建议打开param文件(文件编辑器),和netron图形化工具,一一对比,找出你的模型的节点。

//std::vector<YoloLayerData> layers{
//            {"394",    32, {{116, 90}, {156, 198}, {373, 326}}},
//            {"375",    16, {{30,  61}, {62,  45},  {59,  119}}},
//            {"output", 8,  {{10,  13}, {16,  30},  {33,  23}}},
//    };
//    std::vector<YoloLayerData> layers{
//            {"output",    32, {{116, 90}, {156, 198}, {373, 326}}},
//            {"741",    16, {{30,  61}, {62,  45},  {59,  119}}},
//            {"761", 8,  {{10,  13}, {16,  30},  {33,  23}}},
//    };

    std::vector<YoloLayerData> layers{
            {"761",    32, {{116, 90}, {156, 198}, {373, 326}}},
            {"741",    16, {{30,  61}, {62,  45},  {59,  119}}},
            {"output", 8,  {{10,  13}, {16,  30},  {33,  23}}},
    };

三.apk制作

1、将上面编译好的转换好的模型放到assert中

可以直接clone我的apk。然后放入你的模型。这里有几点要注意的。

1、修改好的节点要和你自己的节点对应。

2、下载好的ncnn库放入到cpp目录编译,在cmake中指定导出相关头文件。

3、opencv的库要放到lib中

四、展示

主要java代码

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Native.init(getAssets());
////
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.hekaiming);
//
        Matrix matrix1 = new Matrix();

        float scaleWidth = ((float) 640) / bitmap.getWidth();
        float scaleHeight = ((float) 640) / bitmap.getHeight();
        // 取得想要缩放的matrix参数
        matrix1.postScale(scaleWidth, scaleHeight);

        Bitmap bitmap2 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix1, false);


//
        Box[] result = Native.detect(bitmap2,0.3,0.7);
//
        Bitmap mutableBitmap = drawBoxRects(bitmap2, result);//

        ImageView view = (ImageView)findViewById(R.id.im);
        view.setImageBitmap(bitmap);

        ImageView viewout = (ImageView)findViewById(R.id.imout);
        viewout.setImageBitmap(mutableBitmap);

显示

git代码

https://github.com/djh123/yolov5Android​github.com

其他

关注我不迷路,目前只是一些入门级的小文章,后面会有AI系列文章推送。

https://github.com/yazone/ai_learning_path
更多嵌入式AI技术相关内容请关注嵌入式AI专栏。
推荐阅读
关注数
16510
内容数
1230
嵌入式端AI,包括AI算法在推理框架Tengine,MNN,NCNN,PaddlePaddle及相关芯片上的实现。欢迎加入微信交流群,微信号:aijishu20(备注:嵌入式)
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息