转换模型

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);