乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      基于Paddle的截圖&OCR文字識別的實現(xiàn)

       hncdman 2022-05-25 發(fā)布于湖南

      一款截圖識別文字的OCR工具主要涉及2個環(huán)境:

      • 截圖

      • OCR識別

      前要

      OCR的應(yīng)用場景

      根據(jù)OCR的應(yīng)用場景而言,我們可以大致分成識別特定場景下的專用OCR以及識別多種場景下的通用OCR。就前者而言,證件識別以及車牌識別就是專用OCR的典型案例。針對特定場景進行設(shè)計、優(yōu)化以達(dá)到最好的特定場景下的效果展示。那通用的OCR就是使用在更多、更復(fù)雜的場景下,擁有比較好的泛性。在這個過程中由于場景的不確定性,比如:圖片背景極其豐富、亮度不均衡、光照不均衡、殘缺遮擋、文字扭曲、字體多樣等等問題,會帶來極大的挑戰(zhàn)。

      OCR的技術(shù)路線

      典型的OCR技術(shù)路線如下圖所示:

      其中OCR識別的關(guān)鍵路徑在于文字檢測和文本識別部分,這也是深度學(xué)習(xí)技術(shù)可以充分發(fā)揮功效的地方。PaddleHub為大家開源的預(yù)訓(xùn)練模型的網(wǎng)絡(luò)結(jié)構(gòu)是Differentiable Binarization+ CRNN,基于icdar2015數(shù)據(jù)集下進行的訓(xùn)練。

      首先,DB是一種基于分割的文本檢測算法。在各種文本檢測算法中,基于分割的檢測算法可以更好地處理彎曲等不規(guī)則形狀文本,因此往往能取得更好的檢測效果。但分割法后處理步驟中將分割結(jié)果轉(zhuǎn)化為檢測框的流程復(fù)雜,耗時嚴(yán)重。因此作者提出一個可微的二值化模塊(Differentiable Binarization,簡稱DB),將二值化閾值加入訓(xùn)練中學(xué)習(xí),可以獲得更準(zhǔn)確的檢測邊界,從而簡化后處理流程。DB算法最終在5個數(shù)據(jù)集上達(dá)到了state-of-art的效果和性能。參考論文:Real-time Scene Text Detection with Differentiable Binarization

      下圖是DB算法的結(jié)構(gòu)圖:
      基于Paddle的截圖&OCR文字識別的實現(xiàn)_第1張圖片

      接著,我們使用 CRNN(Convolutional Recurrent Neural Network)即卷積遞歸神經(jīng)網(wǎng)絡(luò),是DCNN和RNN的組合,專門用于識別圖像中的序列式對象。與CTC loss配合使用,進行文字識別,可以直接從文本詞級或行級的標(biāo)注中學(xué)習(xí),不需要詳細(xì)的字符級的標(biāo)注。參考論文:An end-to-end trainable neural network for image-based sequence recognition and its application to scene text recognition

      下圖是CRNN的網(wǎng)絡(luò)結(jié)構(gòu)圖:

      基于Paddle的截圖&OCR文字識別的實現(xiàn)_第2張圖片

      截圖工具

      很多人會把它想的非常復(fù)雜,其實,Python中有很多可以實現(xiàn)截圖的庫或者函數(shù),最常見的有三種方法。

      一、Python調(diào)用windows API實現(xiàn)屏幕截圖

      二、使用PIL的ImageGrab模塊

      三、使用Selenium截圖

      而我們需要做到的事鼠標(biāo)框選范圍截圖,因此我們采用PyQt5和PIL實現(xiàn)截圖功能。

      我們只需要把鼠標(biāo)框選起點終點坐標(biāo)傳給grab方法就可以實現(xiàn)截圖功能。

      那么,現(xiàn)在問題就轉(zhuǎn)化為如何獲取鼠標(biāo)框選的起點和終點?

      Textshot通過調(diào)用PyQt5并繼承QWidget來實現(xiàn)鼠標(biāo)框選過程中的一些方法來獲取框選的起點和終點。

      Textshot繼承和重寫QWidget方法主要包括如下幾個,

      • keyPressEvent(self, event):鍵盤響應(yīng)函數(shù)

      • paintEvent(self, event):UI繪制函數(shù)

      • mousePressEvent(self, event):鼠標(biāo)點擊事件

      • mouseMoveEvent(self, event):鼠標(biāo)移動事件

      • mouseReleaseEvent(self, event):鼠標(biāo)釋放事件

      可以看出,上面重寫的方法以及囊括了截圖過程中涉及的各個動作,

      • 點擊鼠標(biāo)

      • 拖動、繪制截圖框

      • 釋放鼠標(biāo)

      當(dāng)然了,這一部分有現(xiàn)成的

      可以直接使用:

      class Snipper(QtWidgets.QWidget):
          def __init__(self, parent=None, flags=Qt.WindowFlags()):
              super().__init__(parent=parent, flags=flags)
      
              self.setWindowTitle("TextShot")
              self.setWindowFlags(
                  Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Dialog        )
      
              self.setWindowState(self.windowState() | Qt.WindowFullScreen)
              self.screen = QtGui.QScreen.grabWindow(
                  QtWidgets.QApplication.primaryScreen(),
                  QtWidgets.QApplication.desktop().winId(),
              )
              palette = QtGui.QPalette()
              palette.setBrush(self.backgroundRole(), QtGui.QBrush(self.screen))
              self.setPalette(palette)
      
              QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
      
              self.start, self.end = QtCore.QPoint(), QtCore.QPoint()
      
          def keyPressEvent(self, event):
              if event.key() == Qt.Key_Escape:
                  QtWidgets.QApplication.quit()
      
              return super().keyPressEvent(event)
      
          def paintEvent(self, event):
              painter = QtGui.QPainter(self)
              painter.setPen(Qt.NoPen)
              painter.setBrush(QtGui.QColor(0, 0, 0, 100))
              painter.drawRect(0, 0, self.width(), self.height())
      
              if self.start == self.end:
                  return super().paintEvent(event)
      
              painter.setPen(QtGui.QPen(QtGui.QColor(255, 255, 255), 3))
              painter.setBrush(painter.background())
              painter.drawRect(QtCore.QRect(self.start, self.end))
              return super().paintEvent(event)
      
          def mousePressEvent(self, event):
              self.start = self.end = QtGui.QCursor.pos()
              self.update()
              return super().mousePressEvent(event)
      
          def mouseMoveEvent(self, event):
              self.end = QtGui.QCursor.pos()
              self.update()
              return super().mousePressEvent(event)
      
          def mouseReleaseEvent(self, event):
              if self.start == self.end:
                  return super().mouseReleaseEvent(event)
      
              self.hide()
              QtWidgets.QApplication.processEvents()
              shot = self.screen.copy(QtCore.QRect(self.start, self.end))
              processImage(shot)
              QtWidgets.QApplication.quit()def processImage(img):
      
          buffer = QtCore.QBuffer()
          buffer.open(QtCore.QBuffer.ReadWrite)
          img.save(buffer, "PNG")
          pil_img = Image.open(io.BytesIO(buffer.data()))
          buffer.close()if __name__ == '__main__':
      
          QtCore.QCoreApplication.setAttribute(Qt.AA_DisableHighDpiScaling)
          app = QtWidgets.QApplication(sys.argv)
          window = QtWidgets.QMainWindow()
          snipper = Snipper(window)
          snipper.show()
          sys.exit(app.exec_())

      OCR文字識別

      那么我們的文字識別模型選擇了Paddle最新推出的OCR識別模型。改模型同時支持中英文識別;支持傾斜、豎排等多種方向文字識別。

      識別文字算法采用CRNN (Convolutional Recurrent Neural Network)即卷積遞歸神經(jīng)網(wǎng)絡(luò)。其是DCNN和RNN的組合,專門用于識別圖像中的序列式對象。與CTC loss配合使用,進行文字識別,可以直接從文本詞級或行級的標(biāo)注中學(xué)習(xí),不需要詳細(xì)的字符級的標(biāo)注。該Module是一個通用的OCR模型,支持直接預(yù)測。

      這一步我們就要做的是將截取的圖片傳入文字識別模型即可。

      import os
      os.environ['HUB_HOME'] = "./modules"from PyQt5 import QtCore, QtGui, QtWidgetsfrom PyQt5.QtCore import Qtfrom PIL import Imageimport ioimport sysimport numpy as npimport paddlehub as hubclass Snipper(QtWidgets.QWidget):
          def __init__(self, parent=None, flags=Qt.WindowFlags()):
              super().__init__(parent=parent, flags=flags)
      
              self.setWindowTitle("TextShot")
              self.setWindowFlags(
                  Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Dialog        )
      
              self.setWindowState(self.windowState() | Qt.WindowFullScreen)
              self.screen = QtGui.QScreen.grabWindow(
                  QtWidgets.QApplication.primaryScreen(),
                  QtWidgets.QApplication.desktop().winId(),
              )
              palette = QtGui.QPalette()
              palette.setBrush(self.backgroundRole(), QtGui.QBrush(self.screen))
              self.setPalette(palette)
      
              QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
      
              self.start, self.end = QtCore.QPoint(), QtCore.QPoint()
      
          def keyPressEvent(self, event):
              if event.key() == Qt.Key_Escape:
                  QtWidgets.QApplication.quit()
      
              return super().keyPressEvent(event)
      
          def paintEvent(self, event):
              painter = QtGui.QPainter(self)
              painter.setPen(Qt.NoPen)
              painter.setBrush(QtGui.QColor(0, 0, 0, 100))
              painter.drawRect(0, 0, self.width(), self.height())
      
              if self.start == self.end:
                  return super().paintEvent(event)
      
              painter.setPen(QtGui.QPen(QtGui.QColor(255, 255, 255), 3))
              painter.setBrush(painter.background())
              painter.drawRect(QtCore.QRect(self.start, self.end))
              return super().paintEvent(event)
      
          def mousePressEvent(self, event):
              self.start = self.end = QtGui.QCursor.pos()
              self.update()
              return super().mousePressEvent(event)
      
          def mouseMoveEvent(self, event):
              self.end = QtGui.QCursor.pos()
              self.update()
              return super().mousePressEvent(event)
      
          def mouseReleaseEvent(self, event):
              if self.start == self.end:
                  return super().mouseReleaseEvent(event)
      
              self.hide()
              QtWidgets.QApplication.processEvents()
              shot = self.screen.copy(QtCore.QRect(self.start, self.end))
              processImage(shot)
              QtWidgets.QApplication.quit()def processImage(img):
      
          buffer = QtCore.QBuffer()
          buffer.open(QtCore.QBuffer.ReadWrite)
          img.save(buffer, "PNG")
          pil_img = Image.open(io.BytesIO(buffer.data()))
          buffer.close()
      
          np_images = [np.array(pil_img)]
      
          results = ocr.recognize_text(
              images=np_images,  # 圖片數(shù)據(jù),ndarray.shape 為 [H, W, C],BGR格式;
              use_gpu=False,  # 是否使用 GPU;若使用GPU,請先設(shè)置CUDA_VISIBLE_DEVICES環(huán)境變量
              output_dir='ocr_result',  # 圖片的保存路徑,默認(rèn)設(shè)為 ocr_result;
              visualization=True,  # 是否將識別結(jié)果保存為圖片文件;
              box_thresh=0.5,  # 檢測文本框置信度的閾值;
              text_thresh=0.5)  # 識別中文文本置信度的閾值;
      
          text = []
      
          for result in results:
              data = result['data']
              save_path = result['save_path']
              for infomation in data:
                  print('text: ', infomation['text'], '\nconfidence: ', infomation['confidence'], '\ntext_box_position: ',
                        infomation['text_box_position'])
                  text.append(str(infomation['text']) + '\n')
      
          print(text)
      
          with open('data.txt', 'w') as f:
              for i in text:
                  f.write(str(i))
      
          os.system(r'data.txt')if __name__ == '__main__':
          # 加載移動端預(yù)訓(xùn)練模型
          # ocr = hub.Module(name="chinese_ocr_db_crnn_mobile")
          # 服務(wù)端可以加載大模型,效果更好
          ocr = hub.Module(name="chinese_ocr_db_crnn_server")
      
          QtCore.QCoreApplication.setAttribute(Qt.AA_DisableHighDpiScaling)
          app = QtWidgets.QApplication(sys.argv)
          window = QtWidgets.QMainWindow()
          snipper = Snipper(window)
          snipper.show()
          sys.exit(app.exec_())

      那么我們可以測試一下它的效果:
      基于Paddle的截圖&OCR文字識別的實現(xiàn)_第3張圖片
      基于Paddle的截圖&OCR文字識別的實現(xiàn)_第4張圖片

      那么再看一些模型的其他應(yīng)用吧:

      基于Paddle的截圖&OCR文字識別的實現(xiàn)_第5張圖片

      基于Paddle的截圖&OCR文字識別的實現(xiàn)_第6張圖片

      AISTUDIO地址:https://aistudio.baidu.com/aistudio/projectdetail/532299?shared=1

      Github地址:https://github.com/chenqianhe/screenshot_and_ocr

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多