需求描述

深度学习模型在Android移动端部署的时候,对于采集到的的摄像头画面需要保持宽高比的将Bitmap缩放到模型输入的大小,缩放后较目标尺寸像素缺失的部分采用灰度填充方式, 以防止目标发生明显形变影响识别效果。在本例中,深度模型是以MobileNetV2为Backbone网络的YOLOv3,并基于MNN移动端推理框架部署。其中模型输入图像的尺寸大小为(320,320)。

实现

public static Bitmap scaleImage(Bitmap bm, int newWidth, int newHeight)
{
    if (bm == null) {
        return null;
    }
    int width = bm.getWidth();
    int height = bm.getHeight();
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;
    
    // 保持宽高比缩放,以长边为主
    float scaleRatio = Math.min(scaleHeight, scaleWidth);
    Matrix matrix = new Matrix();
    matrix.postScale(scaleRatio, scaleRatio);
    Bitmap newBm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
    
    // 创建目标大小Bitmap
    Bitmap scaledImage = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(scaledImage);
    
    // 绘制背景颜色
    Paint paint = new Paint();
    paint.setColor(Color.GRAY);
    paint.setStyle(Paint.Style.FILL);
    canvas.drawRect(0, 0, canvas.getWidth(),    canvas.getHeight(), paint);
    
    // 确定画面位置
    float left = 0;
    float top = 0;
    if (width > height){
        top = (float)((newBm.getWidth() - newBm.getHeight()) / 2.0);
    }
    else{
        left = (float)((newBm.getHeight() - newBm.getWidth()) / 2.0);
    }
    canvas.drawBitmap( newBm, left , top, null );
    if (!bm.isRecycled()){
            bm.recycle();
    }
    return scaledImage;
}

效果

摄像头捕捉到的原始画面Bitmap:

屏幕快照 2020-10-21 下午2.34.48.png

保持宽高比缩放后的画面Bitmap:

屏幕快照 2020-10-21 下午2.35.27.png


CRANOLA
1 声望1 粉丝