在 Windows 上实现“实时屏幕捕获”文本检测/提取

问题描述 投票:0回答:1

嗨,实现从电脑屏幕本身(可能是屏幕的一部分)的“实时馈送或捕获”检测文本的最佳方法是什么,以便程序可以根据在屏幕本身上找到的内容执行,程序实时运行时的文本。使用 opencv 或 pyterrseract 等常见库的简单直接的方法是什么?寻找基本示例。谢谢。

导入pytesseract 导入CV2 导入numpy

##这里有一些代码

python-3.x opencv ocr python-tesseract image-recognition
1个回答
0
投票

检测文本的最佳方法可以使用下面的代码,它的作用是,实时读取屏幕或截取屏幕截图(临时屏幕截图以节省内存),然后使用 pytesseract 对其进行处理以获取文本,稍后程序行为将取决于您根据我们从光学字符识别中获得的内容定义的其他常量函数,这是一个离线示例,并使用上面的库或 PIL,将此功能与在使用时与用户交互的 GUI 结合起来:

下例的关键是:

Clock.schedule_interval
from pytesseract import image_to_string #keep constantly obtaining the text from live screen

这是大多数 SDK 或 GUI 设计器中确实存在的功能,它在给定时间(以秒或毫秒为单位)的情况下重复某些功能,完整代码为:

结果:在此处输入图像描述

完整代码:

try:
    from PIL import ImageGrab #ImageGrab is macOS and Windows only
except:
    pass
from PIL import Image
from PIL import ImageChops

try:
    from pytesseract import image_to_string
    import pytesseract
    pytesseract.pytesseract.tesseract_cmd = r"C:\\Program Files\\Tesseract-OCR\\tesseract.exe"
except:
    pass

from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.clock import Clock


from kivymd.uix.behaviors import (
    RectangularElevationBehavior,
    BackgroundColorBehavior,
    RectangularRippleBehavior
)
from kivymd.uix.behaviors import (
    SpecificBackgroundColorBehavior,
    RectangularElevationBehavior,
    CircularElevationBehavior
)
from kivymd.theming import ThemableBehavior
from kivy.uix.behaviors import ButtonBehavior

from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty, ColorProperty, StringProperty
KV = '''

#pro.py
#pro.py

Screen:
    ScreenManager:
        Screen:
            FloatLayout:
                id: changer_jbsidis
                BoxLayout:
                    padding: dp(5),dp(1)
                    spacing: dp(10)
                    MDFillRoundFlatIconButton:
                        icon: "home"
                        text: "Tab 1"
                        width: dp(250)
                        on_release:
                            app.screen=1
                            app.globaltext=""
                            app.root.ids.ritems2.data=[]
                            app.root.ids.ritems2.data=[{"viewclass": "MDTextButton","font_style": "H3","text":"*"},{"viewclass": "Bane"},{"viewclass": "Bane2"},{"viewclass": "B_"}]
                            
                    MDFillRoundFlatIconButton:
                        icon: "pencil"
                        text: "Tab 2"
                        width: dp(250)
                        on_release:
                            app.screen=2
                            app.globaltext=""
                            app.root.ids.ritems2.data=[]
                            app.root.ids.ritems2.data=[{"viewclass": "MDTextButton","font_style": "H3","text":"*"},{"viewclass": "Bane3"},{"viewclass": "Bane4"},{"viewclass": "B_"}]
                            
                BoxLayout:
                    id: m5
                    pos_hint: {"center_x": .5, "center_y": .59}
                    orientation: "horizontal"
                    padding: dp(1),dp(1)
                    
                    BoxLayout:
                        padding: dp(1),dp(1)
                        pos_hint: {"center_x": .6, "center_y": .5}
                        #size_hint_x: .34
                                     
                        RecycleView: 
                            id: ritems2
                            pos_hint: {'x': 0, 'y': 0}
                            #effect_cls: app.SF()
                            key_viewclass: "viewclass"
                            bar_color: [.92,.05,.5,.6]
                            bar_inactive_color: [1,1,1,0]
                            bar_width: 5
                            #data: [{"viewclass": "MDTextButton","font_style": "H3","text":"Einstenio"},{"viewclass": "Bane"},{"viewclass": "Bane2"},{"viewclass": "B_"}]
                            #
                            data: [{"viewclass": "MDTextButton","font_style": "H3","text":"*"},{"viewclass": "Bane3"},{"viewclass": "Bane4"},{"viewclass": "B_"}]
                            #scroll_wheel_distance: sp(80)

                            RecycleGridLayout:
                                id: cat2
                                cols: 1
                                padding: dp(5),dp(75)
                                spacing: dp(10),dp(30)
                                default_size: None, dp(265)
                                default_size_hint: 1,None
                                size_hint_y: None
                                height: self.minimum_height

<B_@BoxLayout>:
    orientation: "vertical"
    canvas.after:
        Color:
            rgba: [0,0,0,0]
        Line:
            width: dp(1.2)
            rounded_rectangle:
                (self.x, self.y, self.width, self.height+dp(50),\
                dp(9),dp(9),dp(9),dp(9),\
                dp(50))
        
<Bane>:
    BoxLayout:
        canvas:
            Color:
                rgba: [1,1,1,1]
            RoundedRectangle:
                pos: self.pos[0],self.pos[1]
                size: self.width, dp(270)
                radius: [dp(14),dp(14),dp(14),dp(14)]
        id: gg
        elevation: 1
        orientation: "vertical"
        padding: dp(5),dp(1)
        BoxLayout:
            padding: dp(5)
            canvas:
                Color:
                    rgba: [1,1,1,1]
                RoundedRectangle:
                    pos: self.width/2.3,self.pos[1]-dp(10)
                    size: dp(70), dp(70)
                    radius: [dp(14),dp(14),dp(14),dp(14)]
                    source: app.resource_path("logo.ico") if not root.pic else app.resource_path("logo.ico")
            canvas.after:
                Color:
                    rgba: [.7,0,1,.5]
                Line:
                    width: dp(1)
                    rounded_rectangle:
                        (self.x+dp(196), self.y-dp(10), dp(70),dp(70),\
                        dp(14),dp(14),dp(14),dp(14),\
                        dp(50))
                
        MDLabel:
            markup: True
            text: "[b] Pregunta:\\n[/b]"
        TextInput:
            id: thetext5
            height: dp(40)
            pos_hint: {"center_x": .5, "top": .975}
            font_size: "14sp"
            hint_text_color: [0,0,0, .7]
            foreground_color: [0,.1,1,1]
            background_color: [1,1,1,0]
            multiline: True
            canvas.after:
                Color:
                    rgba: [.1,.05,1,.6]
                Line:
                    width: dp(2)
                    rounded_rectangle:
                        (self.x, self.y, self.width+dp(1), dp(115),\
                        dp(8),dp(8),dp(8),dp(8),\
                        dp(50))
            size_hint: 1,3
            text: root.question
            
        BoxLayout:
            id: co
            padding: dp(10),dp(-5)
            pos_hint: {"center_x": .5, "center_y": -.6}
        FloatLayout:
            MDFillRoundFlatIconButton: #MDIconButton:
                #size: (dp(30), dp(30))
                user_font_size: "17sp"
                text: "Obtener respuesta"
                pos_hint: {"center_x": .22, "center_y": 1.4}
                theme_text_color: "Custom"
                text_color: [1,1,1,1]
                md_bg_color: [1,.1,.1,.5]
                icon: "send"
                on_release: app.obtener_respuesta(root.ids.thetext5.text)

        
<Bane2>:
    BoxLayout:
        canvas:
            Color:
                rgba: [1,1,0,1]
            RoundedRectangle:
                pos: self.pos[0],self.pos[1]
                size: self.width, dp(270)
                radius: [dp(14),dp(14),dp(14),dp(14)]
        id: gg
        elevation: 1
        orientation: "vertical"
        padding: dp(5),dp(1)
        BoxLayout:
            padding: dp(5)
            canvas:
                Color:
                    rgba: [1,1,1,1]
                RoundedRectangle:
                    pos: self.width/2.3,self.pos[1]-dp(10)
                    size: dp(70), dp(70)
                    radius: [dp(14),dp(14),dp(14),dp(14)]
                    source: app.resource_path("logo.ico")
            canvas.after:
                Color:
                    rgba: [.7,0,1,.5]
                Line:
                    width: dp(1)
                    rounded_rectangle:
                        (self.x+dp(196), self.y-dp(10), dp(70),dp(70),\
                        dp(14),dp(14),dp(14),dp(14),\
                        dp(50))
        MDLabel:
            markup: True
            font_style: "H5"
            text: "[b] Respuesta:\\n[/b]"
        TextInput:
            height: dp(40)
            pos_hint: {"center_x": .5, "top": .975}
            font_size: "14sp"
            hint_text_color: [0,0,0, .7]
            foreground_color: [0,.1,1,1]
            background_color: [1,1,1,0]
            multiline: True
            canvas.after:
                Color:
                    rgba: [.42,.05,.6,.6]
                Line:
                    width: dp(2)
                    rounded_rectangle:
                        (self.x, self.y, self.width+dp(1), dp(115),\
                        dp(8),dp(8),dp(8),dp(8),\
                        dp(50))
            size_hint: 1,3
            text: root.answer
            
        BoxLayout:
            id: co
            padding: dp(10),dp(-5)
            pos_hint: {"center_x": .5, "center_y": -.6}
        FloatLayout:

<Bane3>:
    BoxLayout:
        canvas:
            Color:
                rgba: [1,1,1,1]
            RoundedRectangle:
                pos: self.pos[0],self.pos[1]
                size: self.width, dp(270)
                radius: [dp(14),dp(14),dp(14),dp(14)]
        id: gg
        elevation: 1
        orientation: "vertical"
        padding: dp(5),dp(1)
        BoxLayout:
            padding: dp(5)
            canvas:
                Color:
                    rgba: [1,1,1,1]
                RoundedRectangle:
                    pos: self.width/2.3,self.pos[1]-dp(10)
                    size: dp(70), dp(70)
                    radius: [dp(14),dp(14),dp(14),dp(14)]
                    source: app.resource_path("logo.ico")
            canvas.after:
                Color:
                    rgba: [.7,0,1,.5]
                Line:
                    width: dp(1)
                    rounded_rectangle:
                        (self.x+dp(196), self.y-dp(10), dp(70),dp(70),\
                        dp(14),dp(14),dp(14),dp(14),\
                        dp(50))
        MDLabel:
            markup: True
            text: "[b] Agregando texto de cada Snipping capture:\\n[/b]"
        TextInput:
            id: box5
            height: dp(40)
            pos_hint: {"center_x": .5, "top": .975}
            font_size: "14sp"
            hint_text_color: [0,0,0, .7]
            foreground_color: [0,.1,1,1]
            background_color: [1,1,1,0]
            multiline: True
            canvas.after:
                Color:
                    rgba: [.42,.05,.6,.6]
                Line:
                    width: dp(2)
                    rounded_rectangle:
                        (self.x, self.y, self.width+dp(1), dp(115),\
                        dp(8),dp(8),dp(8),dp(8),\
                        dp(50))
            size_hint: 1,3
            text: root.question
            
        BoxLayout:
            id: co
            padding: dp(10),dp(-5)
            pos_hint: {"center_x": .5, "center_y": -.6}
        FloatLayout:
            MDIconButton:
                #size: (dp(20), dp(20))
                user_font_size: "17sp"
                pos_hint: {"center_x": .59, "center_y": 6.4}
                theme_text_color: "Custom"
                text_color: [1,1,1,1]
                md_bg_color: [0,.9,.1,1]
                icon: "camera"
                #on_release: 
            MDFillRoundFlatIconButton: #MDIconButton:
                #size: (dp(30), dp(30))
                user_font_size: "17sp"
                text: "Obtener respuesta"
                pos_hint: {"center_x": .22, "center_y": 1.4}
                theme_text_color: "Custom"
                text_color: [1,1,1,1]
                md_bg_color: [.1,.5,.1,1]
                icon: "send"
                on_release: app.obtener_respuesta(root.ids.box5.text)
            MDFillRoundFlatIconButton: #MDIconButton:
                #size: (dp(30), dp(30))
                user_font_size: "17sp"
                text: "Borrar "+str(len(root.ids.box5.text))+" letras"
                pos_hint: {"center_x": .75, "center_y": 1.4}
                theme_text_color: "Custom"
                text_color: [1,1,1,1]
                md_bg_color: [.1,.1,1,.9]
                icon: "delete"
                on_release:
                    app.globaltext=""
                    root.ids.box5.text=""



<Bane4>:
    BoxLayout:
        canvas:
            Color:
                rgba: [1,1,1,1]
            RoundedRectangle:
                pos: self.pos[0],self.pos[1]
                size: self.width, dp(270)
                radius: [dp(14),dp(14),dp(14),dp(14)]
        id: gg
        elevation: 1
        orientation: "vertical"
        padding: dp(5),dp(1)
        BoxLayout:
            padding: dp(5)
            canvas:
                Color:
                    rgba: [1,1,1,1]
                RoundedRectangle:
                    pos: self.width/2.3,self.pos[1]-dp(10)
                    size: dp(70), dp(70)
                    radius: [dp(14),dp(14),dp(14),dp(14)]
                    source: app.resource_path("logo.ico")
            canvas.after:
                Color:
                    rgba: [.7,0,1,.5]
                Line:
                    width: dp(1)
                    rounded_rectangle:
                        (self.x+dp(196), self.y-dp(10), dp(70),dp(70),\
                        dp(14),dp(14),dp(14),dp(14),\
                        dp(50))
        MDLabel:
            markup: True
            text: "[b] Respuesta obtenida:\\n[/b]"
        TextInput:
            height: dp(40)
            pos_hint: {"center_x": .5, "top": .975}
            font_size: "14sp"
            hint_text_color: [0,0,0, .7]
            foreground_color: [0,.1,1,1]
            background_color: [1,1,1,0]
            multiline: True
            canvas.after:
                Color:
                    rgba: [.42,.05,.6,.6]
                Line:
                    width: dp(2)
                    rounded_rectangle:
                        (self.x, self.y, self.width+dp(1), dp(115),\
                        dp(8),dp(8),dp(8),dp(8),\
                        dp(50))
            size_hint: 1,3
            text: root.answer
            
        BoxLayout:
            id: co
            padding: dp(10),dp(-5)
            pos_hint: {"center_x": .5, "center_y": -.6}
        FloatLayout:
            MDIconButton:
                #size: (dp(20), dp(20))
                user_font_size: "17sp"
                pos_hint: {"center_x": .59, "center_y": 6.4}
                theme_text_color: "Custom"
                text_color: [1,1,1,1]
                md_bg_color: [1,0,0,1]
                icon: "bell"
                #on_release: 

'''

class Bane(
    ThemableBehavior,
    RectangularElevationBehavior,
    SpecificBackgroundColorBehavior,
    BoxLayout):
    question=StringProperty()
    pic=StringProperty()
    answer=StringProperty()
    pass
    
class Bane2(
    ThemableBehavior,
    RectangularElevationBehavior,
    SpecificBackgroundColorBehavior,
    BoxLayout):
    question=StringProperty()
    pic=StringProperty()
    answer=StringProperty()
    pass
class Bane3(
    ThemableBehavior,
    RectangularElevationBehavior,
    SpecificBackgroundColorBehavior,
    BoxLayout):
    question=StringProperty()
    pic=StringProperty()
    answer=StringProperty()
    pass
class Bane4(
    ThemableBehavior,
    RectangularElevationBehavior,
    SpecificBackgroundColorBehavior,
    BoxLayout):
    question=StringProperty()
    pic=StringProperty()
    answer=StringProperty()
    pass
    
import sys,os

class Einsteniojbsidis(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.title="Einstenio V0.1 "

    def build(self):
        Clock.schedule_interval(lambda x:self.check_if_images_are_the_same2(self.resource_path('temp.png'),self.resource_path('n.png')),4)
        
        global app
        app=MDApp.get_running_app()
        return Builder.load_string(KV)
    def resource_path(self,relative_path):
        """ Get absolute path to resource, works for dev and for PyInstaller """
        base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
        return os.path.join(base_path, relative_path)
    def multiple_images(self):
        app.root.ids.ritems2.data=[]
        app.root.ids.ritems2.data=[
            {"viewclass": "MDTextButton","font_style": "H3","text":"*"},
            {"viewclass": "Bane3"},
            {"viewclass": "Bane4"},
            {"viewclass": "B_"}
            ]
    def check_if_images_are_the_same(self,new,last):
        print(new,last)
        pass
##        im = ImageGrab.grabclipboard()
##        print(im)
##        if im is not None:
##            im.save(self.resource_path('temp.png'),'PNG')
####        if im == None:
####            return 0
##        try:
##            i1 = Image.open(new)
##            i2 = Image.open(last)
##
##            
##            diff = ImageChops.difference(i1, i2)
##            channels = diff.split()
##            for channel in channels:
##                if channel.getbbox() is not None:
##                    self.listen_new_image()
##                    return False
##            print("images are the same")
##            return True
##        except Exception as e:
##            print(str(e))
    def check_if_images_are_the_same2(self,new,last):
        print(new,last)
        pass
Einsteniojbsidis().run()
© www.soinside.com 2019 - 2024. All rights reserved.