Google विज़न, पाठ पहचान में पहचान क्षेत्र को सीमित करना


11

मैं एक समाधान के लिए पूरे दिन खोज रहा हूं। मैंने अपनी समस्या के बारे में कई थ्रेड्स की जाँच की है।

लेकिन इससे मुझे बहुत मदद नहीं मिली। मूल रूप से मैं चाहता हूं कि कैमरा पूर्वावलोकन फुलस्क्रीन हो लेकिन पाठ केवल स्क्रीन के केंद्र में पहचाना जाता है, जहां एक आयत खींची जाती है।

मैं जिन तकनीकों का उपयोग कर रहा हूं:

  • ऑप्टिकल कैरेक्टर रिकग्निशन (OCR) के लिए Google मोबाइल विज़न एपीआई
  • निर्भरता: 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);
    }
}

और इस वर्ग के एक उदाहरण को यहां लागू किया है:

   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();

निष्पादन पर इस अपवाद को फेंक दिया जाता है:

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)

अगर किसी के पास कोई सुराग है, तो मेरी क्या गलती है या कोई विकल्प है जिसकी मैं वास्तव में सराहना करूंगा। धन्यवाद!

यह वही है जिसे मैं प्राप्त करना चाहता हूं, एक रेक्ट। पाठ क्षेत्र स्कैनर:

मैं क्या हासिल करना चाहता हूं

जवाबों:


0

Google विज़न डिटेक्शन में इनपुट एक फ्रेम है। एक फ्रेम एक छवि डेटा है और इसमें संबंधित डेटा के रूप में एक चौड़ाई और ऊंचाई होती है। यू इस फ्रेम को प्रोसेस कर सकते हैं (इसे छोटे केंद्रित फ्रेम में काटें) इसे डिटेक्टर को पास करने से पहले। यह प्रक्रिया तेज़ होनी चाहिए और कैमरा प्रसंस्करण छवि के साथ करना चाहिए। नीचे मेरे Github की जाँच करें, फ्रेमप्रोसेसर के लिए खोजें। U वहां फ्रेम इनपुट देख सकता है। आप खुद वहां प्रक्रिया कर सकते हैं।

CameraSource


नमस्कार, सबसे पहले उत्तर देने के लिए धन्यवाद! मैंने आपका कोड देखा और सोचा, मुझे अपने कोड में क्या बदलना है? केवल एक चीज जो मुझे जोड़ना है वह है फ्रेम प्रोसेसिंग पार्ट? (2 निजी कक्षाएं)?
एलन

हां, आपको अपने फ्रेम को संशोधित करना होगा, इससे पहले कि आप इसे डिटेक्टर के अंतिम ऑपरेशन में पास कर दें: mDetector.receiveFrame(outputFrame);
Thành Hà Văn

क्या आप अपना उत्तर उस कोड के साथ संपादित कर सकते हैं, जिसे मुझे जोड़ने की आवश्यकता है, ताकि मैं इसे कोड कर सकूं और आपको इनाम दे सकूं?
एलन

0

Google-विज़न में आप एक पता किए गए पाठ के निर्देशांक प्राप्त कर सकते हैं जैसे कि मोबाइल विज़न एपीआई का उपयोग करके छवि में पाठ की स्थिति कैसे प्राप्त करें?

आप से प्राप्त करते TextBlocksहैं TextRecognizer, तो आप TextBlockउनके निर्देशांक द्वारा फ़िल्टर करते हैं , जिसे कक्षा की विधि getBoundingBox()या getCornerPoints()विधि द्वारा निर्धारित किया जा सकता है TextBlocks:

TextRecognizer

पहचान परिणाम फ़्रेम (फ़्रेम) द्वारा लौटाए जाते हैं। OCR एल्गोरिथ्म पाठ लेआउट को हटाने की कोशिश करता है और प्रत्येक पैराग्राफ को TextBlock उदाहरणों में व्यवस्थित करता है। यदि किसी पाठ का पता लगाया जाता है, तो कम से कम एक TextBlock उदाहरण वापस आ जाएगा।

[..]

सार्वजनिक तरीके

public SparseArray<TextBlock> detect (Frame frame)एक छवि में पाठ का पता लगाता है और पहचानता है। अभी के लिए केवल बिटमैप और NV21 का समर्थन करता है। टेक्स्टब्लॉक के लिए इंट की मैपिंग लौटाता है, जहां टेक्स्ट डोमेन के लिए इंट डोमेन एक अपारदर्शी आईडी का प्रतिनिधित्व करता है।

स्रोत: https://developers.google.com/android/reference/com/google/android/gms/vision/text/TextRecognizer

TextBlock

public class TextBlock extends Object implements Text

OCR इंजन द्वारा समझे गए पाठ का एक खंड (इसे अनुच्छेद के रूप में सोचें)।

लोक विधि सारांश

Rect getBoundingBox() TextBlock का अक्ष-संरेखित बाउंडिंग बॉक्स लौटाता है।

List<? extends Text> getComponents() छोटे घटक जो इस इकाई को शामिल करते हैं, यदि कोई हो।

Point[] getCornerPoints() शीर्ष-बाएं से शुरू होकर दक्षिणावर्त दिशा में 4 कोने बिंदु।

String getLanguage() टेक्स्टब्लॉक में प्रचलित भाषा।

String getValue() एक स्ट्रिंग के रूप में मान्यता प्राप्त पाठ को पुनः प्राप्त करें।

स्रोत: https://developers.google.com/android/reference/com/google/android/gms/vision/text/extBlock

तो आप मूल रूप से इस तरह से आगे बढ़ें कि मोबाइल विज़न एपीआई का उपयोग करके छवि में पाठ की स्थिति कैसे प्राप्त करें? हालाँकि आप किसी भी ब्लॉक को लाइनों में विभाजित नहीं करते हैं और फिर शब्दों में किसी भी लाइन को विभाजित करते हैं

//Loop through each `Block`
            foreach (TextBlock textBlock in blocks)
            {
                IList<IText> textLines = textBlock.Components; 

                //loop Through each `Line`
                foreach (IText currentLine in textLines)
                {
                    IList<IText>  words = currentLine.Components;

                    //Loop through each `Word`
                    foreach (IText currentword in words)
                    {
                        //Get the Rectangle/boundingBox of the word
                        RectF rect = new RectF(currentword.BoundingBox);
                        rectPaint.Color = Color.Black;

                        //Finally Draw Rectangle/boundingBox around word
                        canvas.DrawRect(rect, rectPaint);

                        //Set image to the `View`
                        imgView.SetImageDrawable(new BitmapDrawable(Resources, tempBitmap));


                    }

                }
            }

इसके बजाय आपको सभी टेक्स्ट ब्लॉक की सीमा बॉक्स मिलती है और फिर स्क्रीन / फ्रेम के केंद्र या आपके द्वारा निर्दिष्ट आयत के समन्वय के साथ सीमा बॉक्स का चयन करें (यानी मैं एंड्रॉइड में मेरे विचार का केंद्र x, y कैसे प्राप्त कर सकता हूं? ) का है। इसके लिए आप getBoundingBox()या की getCornerPoints()विधि का उपयोग करें TextBlocks...


मैं कल इसका परीक्षण करूँगा
एलन

मैंने इसे आजमाया लेकिन मुझे नहीं पता था कि इसे सही तरीके से कैसे लागू किया जाए
एलन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.