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

如何限制Google Vision API仅在相机预览指定区域检测文本

嘿,这个需求我帮很多开发者处理过,给你分享两种实用的实现思路,看哪种更适合你的场景:

方法一:本地裁剪预览帧后再调用Vision API

这种方式适合需要先对指定区域做预处理(比如放大、调整对比度),或者不想纠结API参数的情况,步骤很清晰:

  • 先获取相机预览的每一帧(不管你用CameraX、Camera2还是其他相机框架,先拿到原始的图像帧)
  • 关键:坐标转换:把屏幕上用户框选的矩形,转换成预览图像上的真实坐标——这里要注意相机传感器的方向和屏幕显示方向可能不一致(比如手机竖屏时,相机传感器可能是横屏的),得先做旋转/缩放映射,不然裁剪的区域会跑偏
  • 裁剪图像:用对应平台的图像工具截出指定区域(比如Android用Bitmap.createBitmap(),Python用PIL的crop())
  • 把裁剪后的小图像传给Vision API做文本检测,返回的结果自然就只有目标区域的文本了

举个Android平台的代码片段参考:

// 假设screenRect是用户在屏幕上框选的矩形,previewBitmap是相机预览的原始Bitmap
// 先处理图像旋转(根据你的相机实际旋转角度调整,这里以90度为例)
val matrix = Matrix().apply { postRotate(90f) }
val rotatedPreview = Bitmap.createBitmap(
    previewBitmap, 0, 0, previewBitmap.width, previewBitmap.height, matrix, true
)

// 计算裁剪区域在旋转后图像上的坐标(归一化转实际像素)
val screenWidth = resources.displayMetrics.widthPixels
val screenHeight = resources.displayMetrics.heightPixels
val cropRect = Rect(
    (screenRect.left * rotatedPreview.width / screenWidth).toInt(),
    (screenRect.top * rotatedPreview.height / screenHeight).toInt(),
    (screenRect.right * rotatedPreview.width / screenWidth).toInt(),
    (screenRect.bottom * rotatedPreview.height / screenHeight).toInt()
)

// 裁剪出目标区域
val croppedBitmap = Bitmap.createBitmap(
    rotatedPreview, cropRect.left, cropRect.top, cropRect.width(), cropRect.height()
)

// 后续把croppedBitmap传给Vision API做文本检测即可
方法二:直接在Vision API请求中指定检测区域

如果你不想在本地处理图像裁剪,可以直接让Vision API只关注指定区域,这样节省本地计算资源,步骤如下:

  • 获取相机预览的完整图像帧(不用裁剪)
  • 把屏幕上的框选矩形转换成归一化坐标(也就是相对于图像宽高的比例,范围0-1,比如左上角是(0,0),右下角是(1,1))
  • 在构建Vision API的AnnotateImageRequest时,添加imageContext参数,其中textDetectionParams里的boundingPoly设置为目标区域的矩形顶点

举个Java平台的请求构建示例:

// 先把预览图像转成ByteString(Vision API要求的格式)
ByteString imageBytes = ByteString.copyFrom(previewImageByteArray);
Image image = Image.newBuilder().setContent(imageBytes).build();

// 定义目标区域的归一化顶点(比如图像的20%-80%宽,30%-70%高)
BoundingPoly targetRegion = BoundingPoly.newBuilder()
    .addVertices(Vertex.newBuilder().setX(0.2f).setY(0.3f)) // 左上角
    .addVertices(Vertex.newBuilder().setX(0.8f).setY(0.3f)) // 右上角
    .addVertices(Vertex.newBuilder().setX(0.8f).setY(0.7f)) // 右下角
    .addVertices(Vertex.newBuilder().setX(0.2f).setY(0.7f)) // 左下角
    .build();

// 配置文本检测参数,指定只检测目标区域
TextDetectionParams textParams = TextDetectionParams.newBuilder()
    .addBoundingPoly(targetRegion)
    .build();

ImageContext imageContext = ImageContext.newBuilder()
    .setTextDetectionParams(textParams)
    .build();

// 构建完整的检测请求
AnnotateImageRequest request = AnnotateImageRequest.newBuilder()
    .setImage(image)
    .addFeatures(Feature.newBuilder().setType(Feature.Type.TEXT_DETECTION))
    .setImageContext(imageContext)
    .build();

// 发送请求到Vision API,获取结果即可
几个重要的注意点
  • 坐标转换一定要准确:这是最容易踩坑的地方,务必测试不同屏幕方向、不同设备下的坐标映射,确保目标区域正确
  • 性能优化:实时预览场景下,本地裁剪后再传API会减少上传的数据量,提升响应速度;而用API自带的裁剪参数则节省本地CPU资源,根据你的设备性能选择
  • 基础配置别忘:确保已经在Google Cloud控制台启用Vision API,配置好API密钥,并且相机权限已经申请到位

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:36:07