一、环境准备
1.yolactdbolya/yolactgithub.com
1、git clone 改模型。
2、下载预编译的模型
2.ncnnReleases · Tencent/ncnngithub.com
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
下载好的模型放到weight目录下。跑如下命令
python eval.py --trained_model=weight/yolact_resnet50_54_800000.pth --score_threshold=0.15 --top_k=15 --image=test.jpg
但是还要修改
修改1:eval.py中,添加导出函数
def evalimage(net:Yolact, path:str, save_path:str=None):
frame = torch.from_numpy(cv2.imread(path)).cuda().float()
batch = FastBaseTransform()(frame.unsqueeze(0))
preds = net(batch)
torch.onnx._export(net, batch, "yolact.onnx", export_params=True, keep_initializers_as_inputs=True, opset_version=11)
修改2:yolact.py,class Yolact 的 forward 方法直接返回模型的 pred_outs 输出
# return self.detect(pred_outs, self)return pred_outs;
在跑下导出onnx
python eval.py --trained_model=weight/yolact_resnet50_54_800000.pth --score_threshold=0.15 --top_k=15 --image=test.jpg
修改3:简化onnx
python -m onnxsim yolact.onnx yolact-sim.onnx
2.转换成ncnn模型
./onnx2ncnn yolact-sim.onnx yolact.param yolact.bin
./ncnnoptimize yolact.param yolact.bin yolact-opt.param yolact-opt.bin 0
但是,还是会有问题的。
修改:yolact-opt.param文件(用文件编辑器打开)
Concat 10465 5 1 10283 10322 10361 10400 10439 10465 0=0
Concat 10466 5 1 10295 10334 10373 10412 10451 10466 0=0
Concat 10467 5 1 10308 10347 10386 10425 10464 10467 0=0
三.apk制作
0、将上面编译好的转换好的模型放到assert中
可以直接clone我的apk。然后放入你的模型。这里有几点要注意的。
1、修改好的节点要和你自己的节点对应。完整代码如下。
YolactNet->load_param(mgr, "yolact-opt.param");
YolactNet->load_model(mgr, "yolact-opt.bin");
ncnn::Extractor ex = YolactNet->create_extractor();
ncnn::Mat in(550, 550, 3);
ex.input("input.1", in);
ncnn::Mat maskmaps;
ncnn::Mat location;
ncnn::Mat mask;
ncnn::Mat confidence;
//ex.extract("620", b620);// 32 x 138x138//ex.extract("816", b816);// 4 x 19248//ex.extract("818", b818);// 32 x 19248//ex.extract("820", confidence);// 81 x 19248ex.extract("600", maskmaps);// 32 x 138x138ex.extract("797", location);// 4 x 19248ex.extract("799", mask);// 32 x 19248ex.extract("801", confidence);// 81 x 19248LOGI("nativeInit %f ", 0.1);
int num_class = confidence.w;
int num_priors = confidence.h;
for (int i = 0; i < num_priors; i++) {
const float *conf = confidence.row(i);
int label = 0;
float score = 0.f;
for (int j = 1; j < num_class; j++) {
float class_score = conf[j];
if (class_score > score) {
label = j;
score = class_score;
}
}
}
中间的四个节点,需要你对应修改。
2、下载好的ncnn库放入到cpp目录编译,在cmake中指定导出相关头文件。
add_library( ncnn STATIC IMPORTED )
set_target_properties( # Specifies the target library.
ncnn
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
${CMAKE_SOURCE_DIR}/ncnn/${ANDROID_ABI}/libncnn.a )
3、opencv的库要放到lib中
四、展示
setContentView(R.layout.activity_main);
Native.init(getAssets());
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.hekaiming);
Matrix matrix1 = new Matrix();
float scaleWidth = ((float) 550) / bitmap.getWidth();
float scaleHeight = ((float) 550) / bitmap.getHeight();
matrix1.postScale(scaleWidth, scaleHeight);
Bitmap bitmap2 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix1, false);
YolactMask [] yolactMasks = Native.detect(bitmap2);
Bitmap mutableBitmap = drawYolactMask(bitmap2, yolactMasks);
ImageView view = (ImageView)findViewById(R.id.im);
view.setImageBitmap(bitmap);
ImageView viewout = (ImageView)findViewById(R.id.imout);
viewout.setImageBitmap(mutableBitmap);
apk代码就很简单了。图片展示,借用下何凯明大神的照片。
git 代码。djh123/yolactAndroidgithub.com
简易apk
当然还有很多需要优化的地方,知识先弄个demo。