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

标签 java android android-camera google-vision

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

  • Custom detector object
  • Reduce bar code tracking window
  • 还有更多...

  • 但这对我没有多大帮助。基本上我希望相机预览是全屏的,但文本只能在屏幕中心被识别,在那里绘制一个矩形。
    我正在使用的技术:
  • 用于光学字符识别 (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);
        }
    }
    
    并在这里实现了这个类的一个实例:
    最终 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();
    
    执行时抛出此异常:
    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)
    

    If anyone has a clue, what my fault is or has any alternatives I would really appreciate it. Thank you!


    这就是我想要实现的,一个 Rect.文本区域扫描仪:
    What I want to achieve

    最佳答案

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

    CameraSource

    关于java - 限制谷歌视觉中的检测区域,文本识别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60578754/

    相关文章:

    java - 如何从 Java 获取 Acoustid (Chromaprint) 来识别 mp3/m4a/etc

    java - 使用 --severity 参数运行 gae appcfg.sh 时出错

    java - TrueZip 无法从存档中提取文件

    android - 正则表达式如何从json中提取数据

    android - 贝塞尔曲线自定义 View 的阴影效果

    java - 用户关键字替换密码在两个不同大小的数组上循环

    java - 检查我的应用程序的通知是否正在运行

    android - 带有OpenCV3.0.0 Android的Camera Flash无法正常工作

    android - 从安卓相机中提取 EXIF 数据

    Android 2.3.4 在 Camera.setParameters 上崩溃