限制谷歌视觉中的检测区域,文本识别

Ala*_*lan 15 java android android-camera google-vision

我一整天都在寻找解决方案。我已经检查了几个关于我的问题的线程。

但这对我没有多大帮助。基本上我希望相机预览是全屏的,但文本只能在屏幕中央被识别,在那里绘制了一个矩形。

我正在使用的技术:

  • 用于光学字符识别 (OCR) 的 Google Mobile Vision API
  • 依赖: play-services-vision

我目前的状态: 我创建了一个 BoxDetector 类:

public class BoxDetector extends Detector {
    private Detector mDelegate;
    private int mBoxWidth, mBoxHeight;

    public BoxDetector(Detector delegate, int boxWidth, int boxHeight) {
        mDelegate = delegate;
        mBoxWidth = boxWidth;
        mBoxHeight = boxHeight;
    }

    public SparseArray detect(Frame frame) {
        int width = frame.getMetadata().getWidth();
        int height = frame.getMetadata().getHeight();
        int right = (width / 2) + (mBoxHeight / 2);
        int left = (width / 2) - (mBoxHeight / 2);
        int bottom = (height / 2) + (mBoxWidth / 2);
        int top = (height / 2) - (mBoxWidth / 2);

        YuvImage yuvImage = new YuvImage(frame.getGrayscaleImageData().array(), ImageFormat.NV21, width, height, null);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        yuvImage.compressToJpeg(new Rect(left, top, right, bottom), 100, byteArrayOutputStream);
        byte[] jpegArray = byteArrayOutputStream.toByteArray();
        Bitmap bitmap = BitmapFactory.decodeByteArray(jpegArray, 0, jpegArray.length);

        Frame croppedFrame =
                new Frame.Builder()
                        .setBitmap(bitmap)
                        .setRotation(frame.getMetadata().getRotation())
                        .build();

        return mDelegate.detect(croppedFrame);
    }

    public boolean isOperational() {
        return mDelegate.isOperational();
    }

    public boolean setFocus(int id) {
        return mDelegate.setFocus(id);
    }

    @Override
    public void receiveFrame(Frame frame) {
        mDelegate.receiveFrame(frame);
    }
}
Run Code Online (Sandbox Code Playgroud)

并在这里实现了这个类的一个实例:

final TextRecognizer textRecognizer = new TextRecognizer.Builder(App.getContext()).build();

// Instantiate the created box detector in order to limit the Text Detector scan area
BoxDetector boxDetector = new BoxDetector(textRecognizer, width, height);

//Set the TextRecognizer's Processor but using the box collider

boxDetector.setProcessor(new Detector.Processor<TextBlock>() {
    @Override
    public void release() {
    }

    /*
        Detect all the text from camera using TextBlock
        and the values into a stringBuilder which will then be set to the textView.
    */
    @Override
    public void receiveDetections(Detector.Detections<TextBlock> detections) {
        final SparseArray<TextBlock> items = detections.getDetectedItems();
        if (items.size() != 0) {

            mTextView.post(new Runnable() {
                @Override
                public void run() {
                    StringBuilder stringBuilder = new StringBuilder();
                    for (int i = 0; i < items.size(); i++) {
                        TextBlock item = items.valueAt(i);
                        stringBuilder.append(item.getValue());
                        stringBuilder.append("\n");
                    }
                    mTextView.setText(stringBuilder.toString());
                }
            });
        }
    }
});


    mCameraSource = new CameraSource.Builder(App.getContext(), boxDetector)
            .setFacing(CameraSource.CAMERA_FACING_BACK)
            .setRequestedPreviewSize(height, width)
            .setAutoFocusEnabled(true)
            .setRequestedFps(15.0f)
            .build();
Run Code Online (Sandbox Code Playgroud)

执行时抛出此异常:

Exception thrown from receiver.
java.lang.IllegalStateException: Detector processor must first be set with setProcessor in order to receive detection results.
    at com.google.android.gms.vision.Detector.receiveFrame(com.google.android.gms:play-services-vision-common@@19.0.0:17)
    at com.spectures.shopendings.Helpers.BoxDetector.receiveFrame(BoxDetector.java:62)
    at com.google.android.gms.vision.CameraSource$zzb.run(com.google.android.gms:play-services-vision-common@@19.0.0:47)
    at java.lang.Thread.run(Thread.java:919)
Run Code Online (Sandbox Code Playgroud)

如果有人有线索,我的错是什么或有任何替代方案,我将不胜感激。谢谢!

这就是我想要实现的,一个 Rect。文本区域扫描仪:

我想要达到的目标

小智 0

谷歌视觉检测的输入是一个框架。帧是图像数据并且包含宽度和高度作为关联数据。在将其传递给检测器之前,您可以处理该帧(将其剪切为较小的中心帧)。这个过程必须快速并且沿着相机处理图像进行。查看下面我的 Github,搜索 FrameProcessingRunnable。你可以在那里看到帧输入。你可以在那里自己做这个过程。

相机源