目錄
- 前期準(zhǔn)備
- 界面編寫
- 截圖功能實(shí)現(xiàn)
- OCR實(shí)現(xiàn)
- 內(nèi)容顯示
- 總結(jié)
前期準(zhǔn)備
在這個(gè)階段主要準(zhǔn)備整個(gè)小程序的結(jié)構(gòu),既然要實(shí)現(xiàn)ocr,那么輸入就是一張圖片,而圖片這里采用屏幕截圖的方式獲得,輸出是文字,這里采用搜狗的ocr接口,我們把截好的圖片傳到搜狗ocr接口中,然后把返回的文字作為輸出即可。
由于想做一個(gè)小程序,所以要為程序做GUI,這里采用tkinter編制GUI界面。
界面編寫
界面主要就準(zhǔn)備一個(gè)窗體,里面有菜單,給出OCR功能。
之后我們點(diǎn)擊菜單,則啟動(dòng)一個(gè)截圖功能,在截圖完成后,我們就把截得的圖片傳入ocr接口并返回文字到主窗體中。
主面板的編寫則直接使用tkinter建立菜單等
root = Tk()
root.title("小新的OCR")
# 創(chuàng)建一個(gè)頂級(jí)菜單
menubar = Menu(root)
# 創(chuàng)建一個(gè)下拉菜單“文件”,然后將它添加到頂級(jí)菜單中
filemenu = Menu(menubar, tearoff=False)
filemenu.add_command(label="OCR", command=buttonCaptureClick, accelerator='Ctrl+N')
filemenu.add_command(label="幫助",command=helpClick)
filemenu.add_command(label="退出", command=root.quit)
menubar.add_cascade(label="操作", menu=filemenu)
# 顯示菜單
root.config(menu=menubar)
root.bind_all("Control-d>", lambda event: buttonCaptureClick())
#啟動(dòng)消息主循環(huán)
root.mainloop()
這樣變回產(chǎn)生一個(gè)窗體,用戶可以和這個(gè)窗體進(jìn)行交互,你可以點(diǎn)擊菜單,然后找到其子菜單中的OCR一項(xiàng),點(diǎn)擊它便會(huì)調(diào)用一個(gè)buttonCaptureClick的函數(shù),這個(gè)函數(shù)就來(lái)產(chǎn)生截圖,并且保存截圖。
截圖功能實(shí)現(xiàn)
截圖功能我也是參考網(wǎng)上的內(nèi)容,原理就是先把整個(gè)屏幕給捕捉到,然后監(jiān)聽(tīng)鼠標(biāo)事件,當(dāng)鼠標(biāo)左邊按下則作為截圖的左頂點(diǎn),鼠標(biāo)左鍵松下則最為截圖的右底點(diǎn),這樣我們截圖區(qū)域就出來(lái)了,然后進(jìn)行保存即可。
#用來(lái)顯示全屏幕截圖并響應(yīng)二次截圖的窗口類
class MyCapture:
def __init__(self, png):
#變量X和Y用來(lái)記錄鼠標(biāo)左鍵按下的位置
self.X = tkinter.IntVar(value=0)
self.Y = tkinter.IntVar(value=0)
#屏幕尺寸
screenWidth = root.winfo_screenwidth()
screenHeight = root.winfo_screenheight()
#創(chuàng)建頂級(jí)組件容器
self.top = tkinter.Toplevel(root, width=screenWidth, height=screenHeight)
#不顯示最大化、最小化按鈕
self.top.overrideredirect(True)
self.canvas = tkinter.Canvas(self.top,bg='white', width=screenWidth, height=screenHeight)
#顯示全屏截圖,在全屏截圖上進(jìn)行區(qū)域截圖
self.image = tkinter.PhotoImage(file=png)
self.text =""
self.canvas.create_image(screenWidth//2, screenHeight//2, image=self.image)
#鼠標(biāo)左鍵按下的位置
def onLeftButtonDown(event):
self.X.set(event.x)
self.Y.set(event.y)
#開(kāi)始截圖
self.sel = True
self.canvas.bind('Button-1>', onLeftButtonDown)
#鼠標(biāo)左鍵移動(dòng),顯示選取的區(qū)域
def onLeftButtonMove(event):
if not self.sel:
return
global lastDraw
try:
#刪除剛畫完的圖形,要不然鼠標(biāo)移動(dòng)的時(shí)候是黑乎乎的一片矩形
self.canvas.delete(lastDraw)
except Exception as e:
pass
lastDraw = self.canvas.create_rectangle(self.X.get(), self.Y.get(), event.x, event.y, outline='black')
self.canvas.bind('B1-Motion>', onLeftButtonMove)
#獲取鼠標(biāo)左鍵抬起的位置,保存區(qū)域截圖
def onLeftButtonUp(event):
self.sel = False
try:
self.canvas.delete(lastDraw)
except Exception as e:
pass
sleep(0.1)
#考慮鼠標(biāo)左鍵從右下方按下而從左上方抬起的截圖
left, right = sorted([self.X.get(), event.x])
top, bottom = sorted([self.Y.get(), event.y])
pic = ImageGrab.grab((left+1, top+1, right, bottom))
fileName ="temp.jpg"
pic.save(fileName)
self.text = get_text(fileName)
#關(guān)閉當(dāng)前窗口
self.top.destroy()
self.canvas.bind('ButtonRelease-1>', onLeftButtonUp)
#讓canvas充滿窗口,并隨窗口自動(dòng)適應(yīng)大小
self.canvas.pack(fill=tkinter.BOTH, expand=tkinter.YES)
#開(kāi)始截圖
def buttonCaptureClick():
#最小化主窗口
# root.state('icon')
root.withdraw()
sleep(0.4)
filename = 'temp.png'
#grab()方法默認(rèn)對(duì)全屏幕進(jìn)行截圖
im = ImageGrab.grab()
im.save(filename)
im.close()
#顯示全屏幕截圖
w = MyCapture(filename)
root.wait_window(w.top)
#截圖結(jié)束,恢復(fù)主窗口,并刪除臨時(shí)的全屏幕截圖文件
root.update()
root.deiconify()
text1.config(state = NORMAL)
text1.delete(0.0,END)
text1.insert('insert',w.text)
text1.config(state = DISABLED)
text1.pack()
os.remove(filename)
OCR實(shí)現(xiàn)
因?yàn)镺CR其實(shí)是采用了搜狗的接口,所以需要做的工作也不是很多,只需要把我們的圖片傳入即可。
def get_text(img_path):
print("")
img = img_path # 圖片路徑
files = {"pic_path": open(img, "rb")} # files # 類似data數(shù)據(jù)
url = "http://pic.sogou.com/pic/upload_pic.jsp" # post的url
keywords = requests.post(url, files=files).text # requests 提交圖片
url = "http://pic.sogou.com/pic/ocr/ocrOnline.jsp?query=" + keywords # keywords就是圖片url此方式為get請(qǐng)求
ocrResult = requests.get(url).json() # 直接轉(zhuǎn)換為json格式
contents = ocrResult['result'] # 類似字典 把result的value值取出來(lái) 是一個(gè)list然后里面很多json就是識(shí)別的文字
text = ""
for content in contents: # 遍歷所有結(jié)果
text+=(content['content'].strip()+'\n') # strip去除空格 他返回的結(jié)果自帶一個(gè)換行
return text
內(nèi)容顯示
內(nèi)容顯示是在截圖結(jié)束后我們把ocr識(shí)別的內(nèi)容存儲(chǔ)起來(lái)
self.text = get_text(fileName)
然后再顯示到主窗體上
text1.config(state = NORMAL)
text1.delete(0.0,END)
text1.insert('insert',w.text)
text1.config(state = DISABLED)
text1.pack()
總結(jié)
雖然是一個(gè)完整的項(xiàng)目,但是其中的很多模塊其實(shí)都是借用其他人的模塊,而我做的只是把他們結(jié)合起來(lái)做成一個(gè)小項(xiàng)目,所以是站在巨人的肩膀上開(kāi)發(fā)。
到此這篇關(guān)于Python實(shí)現(xiàn)OCR識(shí)別的文章就介紹到這了,更多相關(guān)Python實(shí)現(xiàn)OCR識(shí)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
參考:
- https://cloud.tencent.com/developer/article/1097904
- https://morvanzhou.github.io/tutorials/python-basic/tkinter/
- https://www.52pojie.cn/thread-708177-1-1.html
您可能感興趣的文章:- 基于Python實(shí)現(xiàn)對(duì)PDF文件的OCR識(shí)別
- 初探利用Python進(jìn)行圖文識(shí)別(OCR)
- 如何使用Python進(jìn)行OCR識(shí)別圖片中的文字
- python3安裝OCR識(shí)別庫(kù)tesserocr過(guò)程圖解
- Python文字截圖識(shí)別OCR工具實(shí)例解析
- Python圖像處理之圖片文字識(shí)別功能(OCR)
- python實(shí)現(xiàn)百度OCR圖片識(shí)別過(guò)程解析
- Python基于百度AI實(shí)現(xiàn)OCR文字識(shí)別
- Python3實(shí)現(xiàn)騰訊云OCR識(shí)別
- Python 實(shí)現(xiàn)任意區(qū)域文字識(shí)別(OCR)操作