omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Recognize text from picture

    Pythonista
    12
    65
    25588
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • mikael
      mikael last edited by

      This script recognizes text from a camera or photo library picture. Sharing it since iOS 13 has made it this easy, and Apple Shortcuts do not have support for it (yet, I bet).

      Adjust languages on the first row.

      language_preference = ['fi','en','se']
      
      import photos, ui, dialogs
      import io
      from objc_util import *
      
      load_framework('Vision')
      VNRecognizeTextRequest = ObjCClass('VNRecognizeTextRequest')
      VNImageRequestHandler = ObjCClass('VNImageRequestHandler')
      
      def pil2ui(pil_image):
          buffer = io.BytesIO()
          pil_image.save(buffer, format='PNG')
          return ui.Image.from_data(buffer.getvalue())
      
      selection = dialogs.alert('Get pic', button1='Camera', button2='Photos')
      
      ui_image = None
      
      if selection == 1:
          pil_image = photos.capture_image()
          if pil_image is not None:
              ui_image = pil2ui(pil_image)
      elif selection == 2:
          ui_image = photos.pick_asset().get_ui_image()
      
      if ui_image is not None:
          print('Recognizing...\n')
      
          req = VNRecognizeTextRequest.alloc().init().autorelease()
          req.setRecognitionLanguages_(language_preference)
          handler = VNImageRequestHandler.alloc().initWithData_options_(ui_image.to_png(), None).autorelease()
      
          success = handler.performRequests_error_([req], None)
          if success:
              for result in req.results():
                  print(result.text())
          else:
              print('Problem recognizing anything') ```
      JonB 1 Reply Last reply Reply Quote 1
      • pavlinb
        pavlinb last edited by

        I think VNRecognizeText works only for English.

        mikael 2 Replies Last reply Reply Quote 0
        • cvp
          cvp last edited by

          It works perfectly in French, thanks to @mikael

          1 Reply Last reply Reply Quote 0
          • mikael
            mikael @pavlinb last edited by

            @pavlinb, works perfectly for Finnish, too.

            But the version above is slower than it needs to be, due to an unnecessary roundtrip to ui.Image. Here’s a faster version:

            language_preference = ['fi','en','se']
            
            import photos, ui, dialogs
            import io
            from objc_util import *
            
            load_framework('Vision')
            VNRecognizeTextRequest = ObjCClass('VNRecognizeTextRequest')
            VNImageRequestHandler = ObjCClass('VNImageRequestHandler')
            
            def pil2ui(pil_image):
                buffer = io.BytesIO()
                pil_image.save(buffer, format='PNG')
                return ui.Image.from_data(buffer.getvalue())
            
            selection = dialogs.alert('Get pic', button1='Camera', button2='Photos')
            
            pil_image = None
            
            if selection == 1:
                pil_image = photos.capture_image()
            elif selection == 2:
                pil_image = photos.pick_asset().get_image()
            
            if pil_image is not None:
                print('Recognizing...\n')
                
                buffer = io.BytesIO()
                pil_image.save(buffer, format='PNG')
                image_data = buffer.getvalue()
            
                req = VNRecognizeTextRequest.alloc().init().autorelease()
                req.setRecognitionLanguages_(language_preference)
                handler = VNImageRequestHandler.alloc().initWithData_options_(image_data, None).autorelease()
            
                success = handler.performRequests_error_([req], None)
                if success:
                    for result in req.results():
                        print(result.text())
                else:
                    print('Problem recognizing anything')
            
            1 Reply Last reply Reply Quote 0
            • mikael
              mikael @pavlinb last edited by

              @pavlinb, ah, but you were right. This does not recognize the scandinavian letters ä and ö, substituting them with a and o. @cvp, are you getting é, ô and all the others?

              cvp 1 Reply Last reply Reply Quote 0
              • cvp
                cvp @mikael last edited by

                @mikael
                é yes
                à no

                mikael 1 Reply Last reply Reply Quote 0
                • mikael
                  mikael @cvp last edited by

                  @cvp, checked, usesLanguageCorrection is true and recognitionLevel set to ”accurate” by default, so no help there.

                  1 Reply Last reply Reply Quote 0
                  • pavlinb
                    pavlinb last edited by

                    Doesn’t work for Cyrillic (Bulgarian).

                    1 Reply Last reply Reply Quote 0
                    • mikael
                      mikael last edited by

                      Eh.

                      revision = VNRecognizeTextRequest.currentRevision()
                      supported = VNRecognizeTextRequest.supportedRecognitionLanguagesForTextRecognitionLevel_revision_error_(0, revision, None)
                      

                      Returns ”en-US”.

                      cvp 1 Reply Last reply Reply Quote 0
                      • cvp
                        cvp @mikael last edited by

                        @mikael I had also seen that but it supports French, thus ...buggy?

                        1 Reply Last reply Reply Quote 0
                        • pavlinb
                          pavlinb last edited by

                          BTW, I'm impressed from accuracy ( for Latin based texts ).

                          1 Reply Last reply Reply Quote 0
                          • JonB
                            JonB @mikael last edited by JonB

                            @mikael @cvp have you tried setting customWords attrib of the request? Or, turn off usesLanguageCorrection? (Since the language is en-US you DON'T want language correction when trying to detect other languages!)

                            I gather they are looking for words you'd find in an English dictionary. So perhaps façade, or tête-à-tête might recognize, while other examples wouldn't?

                            cvp 2 Replies Last reply Reply Quote 0
                            • cvp
                              cvp @JonB last edited by

                              @JonB I didn't try but we are not alone with this problem, see here.

                              I've tried with unknown language codes like xx and yy in setRecognitionLanguages_ and the result is the same. It seems that characters are recognized in any languages.
                              My last test on a French text was entirely correct

                              Asie-Pacifique
                              La mission économique belge en Chine cible de
                              cyberattaques massives
                              
                              1 Reply Last reply Reply Quote 0
                              • cvp
                                cvp @JonB last edited by cvp

                                @JonB said:

                                usesLanguageCorrection

                                Tried with False: à still recognized as a

                                Edit : even with

                                    req.setCustomWords_(['à']) 
                                
                                1 Reply Last reply Reply Quote 0
                                • sodoku
                                  sodoku last edited by sodoku

                                  Is there any code examples of how to recognize text with ios 12.4.3 for the i pad mini 2 that would be cool to add it to my sodoku app game

                                  mikael 1 Reply Last reply Reply Quote 0
                                  • mikael
                                    mikael @sodoku last edited by

                                    @sodoku, yes, but it seems a bit more involved. Check this thread where @cvp does all kinds of magic.

                                    1 Reply Last reply Reply Quote 0
                                    • ccc
                                      ccc last edited by

                                      def pil2ui(pil_image):
                                          buffer = io.BytesIO()
                                          pil_image.save(buffer, format='PNG')
                                          return ui.Image.from_data(buffer.getvalue())
                                      

                                      is memory leaking buffer which has been proven to crash Pythonista when multiple images are processed. A better approach is to use a context manager to force the .close().

                                      def pil2ui(pil_image):
                                          with io.BytesIO() as buffer:
                                              pil_image.save(buffer, format='PNG')
                                              return ui.Image.from_data(buffer.getvalue())
                                      
                                      1 Reply Last reply Reply Quote 2
                                      • mikael
                                        mikael last edited by mikael

                                        Revisiting this.

                                        Regardless of language restrictions, I have found the simple and reliable ability to pick text from paper to be useful for me almost weekly - URLs, email addresses, reservation codes, laptop serial numbers, etc.

                                        With the use, I noted that the original script had some issues:

                                        1. Difficult to find and open when quickly needed.
                                        2. Slow to get from the picked photo to recognized text.
                                        3. Results are a pain to copy from the Console as it likes to jump around just as you’ve selected the text to copy.

                                        Point #1 was fixed with a simple Apple Shortcuts shortcut to make the script easy to run.

                                        Point #3 was resolved by presenting the recognized text in a TableView, with tap to copy.

                                        Point #2 took a bit more doing.

                                        Pythonista photos module wants to return PIL images, and that results in two very slow conversions - first the module converts the UIImage to PIL, and then I converted that back to a PNG image for recognition. I found some @cvp code in this thread and replaced photos module with objc_util pickers, which return PNG data almost directly.

                                        And hey presto! Not just faster recognition, but instantaneous - and with much better quality than with the only contender app I could find (Prizmo Go).

                                        Updated script here.

                                        cvp 1 Reply Last reply Reply Quote 0
                                        • cvp
                                          cvp @mikael last edited by

                                          @mikael Thanks for your great 🎁for New Year

                                          1 Reply Last reply Reply Quote 0
                                          • cvp
                                            cvp last edited by

                                            Question for a specialist of this forum.
                                            In the last post of @mikael , I see my user as @cvp but as a black text and not clickable blue, although I've received a notification "Mikael mentioned you...".
                                            How is that possible?

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post
                                            Powered by NodeBB Forums | Contributors