一、环境准备
1.yolov5
https://github.com/ultralytics/yolov5github.com
1、git clone 改模型。
2、下载预编译的模型,这里使用yolov5s
2.ncnn
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/yolov5Androidgithub.com
其他
关注我不迷路,目前只是一些入门级的小文章,后面会有AI系列文章推送。
https://github.com/yazone/ai_learning_path
更多嵌入式AI技术相关内容请关注嵌入式AI专栏。