You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过TFLite模型完成目标检测后,如何裁剪检测到的矩形区域?

问题根因

你裁剪失败的核心原因是坐标体系不匹配:

  • 你调用cropToFrameTransform.mapRect(location)之后,location的坐标已经从TFLite输入图(cropCopyBitmap,尺寸为模型输入尺寸,比如300x300/640x640)的相对坐标,转换为了原始预览帧(rgbFrameBitmap,尺寸为previewWidth x previewHeight)的绝对坐标
  • 但你裁剪用的源图是cropCopyBitmap,两者的尺寸完全不一致,要么裁剪坐标超出cropCopyBitmap的宽高范围,要么裁剪到空白区域,自然会出问题。
可行解决方案

你可以任选以下两种方案之一实现裁剪:

方案1:用未映射的检测坐标裁剪模型输入图

如果你的裁剪需求是从TFLite的输入图里抠出检测区域,直接在调用cropToFrameTransform.mapRect(location)之前做裁剪即可,首先编写通用裁剪方法:

private Bitmap cropBitmapFromRect(Bitmap source, RectF rect) {
    // 转换坐标为int值同时做边界校验,防止越界
    int left = Math.max(0, (int) rect.left);
    int top = Math.max(0, (int) rect.top);
    int width = Math.min(source.getWidth() - left, (int) rect.width());
    int height = Math.min(source.getHeight() - top, (int) rect.height());
    // 宽高合法性校验,避免出现0值导致崩溃
    if (width <= 0 || height <= 0) {
        return null;
    }
    return Bitmap.createBitmap(source, left, top, width, height);
}

再修改你循环内的代码顺序:

for (final Detector.Recognition result : results) {
    RectF location = result.getLocation();
    if (location != null && result.getConfidence() >= minimumConfidence) { 
        canvas.drawRect(location, paint);
        // 先裁剪,再做坐标映射
        Bitmap cropImage = cropBitmapFromRect(cropCopyBitmap, location);
        // 坐标映射用于后续追踪逻辑
        cropToFrameTransform.mapRect(location);
        result.setLocation(location);
        mappedRecognitions.add(result);
        // 后续赋值逻辑
        try {
            crop_result_list = new Detector.Recognition("0", "BusinessCard", result.getConfidence(), location);
            if (cropImage != null) {
                crop_result_list.setCrop(cropImage);
            }
        } catch (Exception err) {
            err.printStackTrace();
        }
    }
}

方案2:用映射后的坐标裁剪原始预览帧

如果你需要的是从原始高清预览帧里抠出检测区域,直接用映射后的location坐标裁剪rgbFrameBitmap即可,裁剪方法还是上述的cropBitmapFromRect,调用时替换源图参数即可:

cropToFrameTransform.mapRect(location);
result.setLocation(location);
mappedRecognitions.add(result);
// 用原始预览帧作为裁剪源
Bitmap cropImage = cropBitmapFromRect(rgbFrameBitmap, location);
注意事项
  • 不要直接用RectF的float值作为createBitmap的入参,必须转int后做边界校验,否则很容易出现坐标越界、宽高为0的异常
  • 如果你的预览帧有旋转角度,裁剪后需要根据sensorOrientation对裁剪出来的Bitmap做旋转处理,保证方向正确

内容的提问来源于stack exchange,提问作者AlisonJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 11:45:04