代碼格式問題見諒,csdn寫好粘過來的,想看起來直觀的請(qǐng)移步我的csdn,個(gè)人簡(jiǎn)介有~
昨天我姐問我有沒有軟件可以批量識(shí)別圖片上的文字,她在幫客戶做資料整理,但是用的方法只能一張一張上傳識(shí)別,不僅效率低還浪費(fèi)時(shí)間。
?我就找了找批量識(shí)別的軟件,下載下來覺得:嗯?不錯(cuò),界面也挺好,小東西做的還挺別致。但是,識(shí)別三張就停止了,提示非最新版本要聯(lián)系客服升級(jí)之類的,妥妥的套路,果斷刪除。又找了一個(gè),嗯?界面更加好看一點(diǎn)兒,人家就很直接,三張之后提示購(gòu)買會(huì)員,還顯示了幾種VIP的費(fèi)用,很“人性”嘛。
?但是,在這個(gè)萬物開源的互聯(lián)網(wǎng)時(shí)代,讓程序員掏腰包買軟件是不可能滴,反正我是不會(huì),啊哈哈。我首想到了反編譯,把三張的限制取消,之前看過一些ios逆向工程的東西,這些應(yīng)該都是通的。搜索了一番之后,有這么個(gè)方法,下載一個(gè)軟件,把exe拖進(jìn)去,就能顯示源碼了。又讓我下東西,我就覺得很煩了,畢竟還是占空間的嘛。
?so,我寫寫就好了嘛,畢竟也是一名程序員,怎么能忘了呢。16年公司項(xiàng)目中身份證識(shí)別用到了OCR做身份證掃描,當(dāng)時(shí)還在做iOS開發(fā),好像用的一個(gè)第三方,細(xì)節(jié)嘛忘得差不多了(而且做app的話,我姐又不是iOS系統(tǒng))。這次就用python的GUI然后打包成exe吧,翻翻我的筆記,對(duì)的19年12月份學(xué)習(xí)到的python打包那些剛好用上。要考慮到客戶需求以及易用性,哈哈,然后就開始了。
批量、圖片文字識(shí)別、導(dǎo)出文本、操作便捷、圖形化界面
1、百度AI開放平臺(tái)的通用文字識(shí)別SDK(沒有廣告成分,搜到什么用什么,免費(fèi)調(diào)用量足夠了),我的代碼中用的是“網(wǎng)絡(luò)圖片文字識(shí)別”,可根據(jù)需求,自行調(diào)整;
2、python的tklinker模塊、打包工具pyinstaller;
3、也可以直接寫入txt;
前一天的代碼,第二天優(yōu)化改改改之后,再用新圖片來識(shí)別發(fā)現(xiàn)不行了,一度以為是哪里寫錯(cuò)了,各種找原因,以為是獲取文件夾路徑方式不對(duì),就自己復(fù)制了路徑進(jìn)來,發(fā)現(xiàn)報(bào)錯(cuò)了。
坑1:圖片路徑——轉(zhuǎn)義
運(yùn)行報(bào)錯(cuò):SyntaxError: (unicode error) ‘unicodeescape’ codec can’t decode bytes in position 2-3: tr
我文件夾中復(fù)制來的路徑:C:\Users\78755\Desktop\test\1.pngfilePath='C:\Users\78755\Desktop\test\1.png'報(bào)錯(cuò)原因:在windows系統(tǒng)當(dāng)中讀取文件路徑可以使用\,但是在python字符串中\(zhòng)有轉(zhuǎn)義的含義,如\t可代表TAB,\n代表換行,所以我們需要采取一些方式使得\不被解讀為轉(zhuǎn)義字符。解決方案:1、在路徑前面加r,保持字符原始值的意思。filePath=r'C:\Users\78755\Desktop\test\1.png’2、替換為雙反斜杠filePath='C:\\Users\\78755\\Desktop\\test\\1.png’3、替換為正斜杠filePath=‘C:/Users/78755/Desktop/test/1.png’
坑2:后綴——python批量修改指定文件夾下圖片后綴
import os# 此處我是將test文件夾下全部.jpg后綴修改了成了.png并給圖片重新命名os.chdir(r'C:\Users\78755\Desktop\test');# 指定文件夾路徑count=1;# 初始序號(hào)# os.listdir(path) 方法用于返回指定的文件夾(path)包含的文件或文件夾的名字的列表,如果path=None,則使用path="."foritem in[xforx in os.listdir(".")]:# os.path.isfile( )判斷某一對(duì)象(需提供絕對(duì)路徑)是否為文件# 并且后綴以.jpg結(jié)尾ifos.path.isfile(item)and os.path.splitext(item)[1]=='.jpg':os.rename(item,'%s.png'%(count));count+=1;print(item);
1、安裝OCR Python SDK
OCR Python SDK目錄結(jié)構(gòu)├── README.md├── aip//SDK目錄│? ├── __init__.py//導(dǎo)出類│? ├── base.py//aip基類│? ├── http.py//http請(qǐng)求│? └── ocr.py//OCR└── setup.py//setuptools安裝
支持Python版本:2.7.+ ,3.+
安裝使用Python SDK有如下方式:
如果已安裝pip,執(zhí)行pip install baidu-aip即可。
如果已安裝setuptools,執(zhí)行python setup.py install即可。
2、新建AipOcr
AipOcr是OCR的Python SDK客戶端,為使用OCR的開發(fā)人員提供了一系列的交互方法。
參考如下代碼新建一個(gè)AipOcr:
from aip import AipOcr""" 你的 APPID AK SK """APP_ID='你的 App ID'API_KEY='你的 Api Key'SECRET_KEY='你的 Secret Key'client=AipOcr(APP_ID,API_KEY,SECRET_KEY)
在上面代碼中,常量APP_ID在百度智能云控制臺(tái)中創(chuàng)建,常量API_KEY與SECRET_KEY是在創(chuàng)建完畢應(yīng)用后,系統(tǒng)分配給用戶的,均為字符串,用于標(biāo)識(shí)用戶,為訪問做簽名驗(yàn)證,可在AI服務(wù)控制臺(tái)中的應(yīng)用列表中查看。
3、單張識(shí)別:
# 單張圖片識(shí)別i=open(r'C:\Users\78755\Desktop\test\1.png','rb')image=i.read()result=client.basicGeneral(image)#將所有的文字都合并到一起foritem in result['words_result']:print(item['words'])
4、批量識(shí)別:
# 圖片批量識(shí)別filePath=r'C:\Users\78755\Desktop\test'defget_file_content(filePath):withopen(filePath,'rb')as fp:returnfp.read()forroot,dirs,files in os.walk(".",topdown=False):forname in files:if'png'in name:filePath=os.path.join(root,name)[2:]options={'detect_direction':'true','language_type':'CHN_ENG',}result=aipOcr.webImage(get_file_content(filePath),options)print(result)fori in result['words_result']:print(i['words'])
5、寫入txt文件:
# 寫入txt? ? f=open("文件名.txt","a")#a 打開一個(gè)文件用于追加。如果該文件已存在,文件指針將會(huì)放在文件的結(jié)尾。也就是說,新的內(nèi)容將會(huì)被寫入到已有內(nèi)容之后。如果該文件不存在,創(chuàng)建新文件進(jìn)行寫入。? ? f.write('要寫入的內(nèi)容')f.close()
6、Python GUI之tkinter窗口視窗的創(chuàng)建,并實(shí)現(xiàn)選擇文件夾路徑并展示路徑的功能:
import tkinter as tk? # 使用Tkinter前需要先導(dǎo)入from tkinter import*from tkinter.filedialog import askdirectory# GUI# 第1步,實(shí)例化object,建立窗口windowwindow=tk.Tk()# 第2步,給窗口的可視化起名字window.title('批量識(shí)別圖片文字')# 第3步,設(shè)定窗口的大小(長(zhǎng)*寬)window.geometry('1000x700')# 這里的乘是小x# 選擇文件夾路徑方法defselectPath():path_=askdirectory()path.set(path_)path=StringVar()# 第4步,在窗口界面設(shè)置放置Button按鍵selectedButton=tk.Button(window,text='選擇文件夾',font=('Arial',12),width=10,height=1,command=selectPath).place(x=50,y=20)# 第5步,在圖形界面上設(shè)定標(biāo)簽展示選擇好的文件夾路徑var=tk.StringVar()# 將label標(biāo)簽的內(nèi)容設(shè)置為字符類型,用var來接收hit_me函數(shù)的傳出內(nèi)容用以顯示在標(biāo)簽上pathLabel=tk.Label(window,textvariable=path,bg='gray',fg='white',font=('Arial',12),width=30,height=2).place(x=180,y=20)# 說明: bg為背景,fg為字體顏色,font為字體,width為長(zhǎng),height為高,這里的長(zhǎng)和高是字符的長(zhǎng)和高,比如height=2,就是標(biāo)簽有2個(gè)字符這么高# 第6步,主窗口循環(huán)顯示window.mainloop()
7、完整代碼:
(1)、融合圖片識(shí)別和圖形化界面,可自定通過窗口進(jìn)行選擇圖片文件夾進(jìn)行識(shí)別(將要識(shí)別的圖片放到同一文件夾下即可,此處以.png后綴為例);
(2)、識(shí)別結(jié)果的展示用到了tklinker的scrolledtext;
(3)、窗口大小及各控件樣式可調(diào)整;
# encoding:utf-8# author:笑胖仔from aip import AipOcrimport osimport tkinter as tk? # 使用Tkinter前需要先導(dǎo)入from tkinter import*from tkinter.filedialog import askdirectoryfrom tkinter import scrolledtext""" 你的 APPID AK SK """APP_ID='你的 App ID'API_KEY='你的 Api Key'SECRET_KEY='你的 Secret Key'client=AipOcr(APP_ID,API_KEY,SECRET_KEY)# GUI# 第1步,實(shí)例化object,建立窗口windowwindow=tk.Tk()# 第2步,給窗口的可視化起名字window.title('批量識(shí)別圖片文字')# 第3步,設(shè)定窗口的大小(長(zhǎng)*寬)window.geometry('1000x700')# 這里的乘是小x# 選擇文件夾路徑方法defselectPath():path_=askdirectory()path.set(path_)path=StringVar()# 第4步,在窗口界面設(shè)置放置Button按鍵selectedButton=tk.Button(window,text='選擇文件夾',font=('Arial',12),width=10,height=1,command=selectPath).place(x=50,y=20)# selectedButton.pack()# 第5步,在圖形界面上設(shè)定標(biāo)簽var=tk.StringVar()# 將label標(biāo)簽的內(nèi)容設(shè)置為字符類型,用var來接收hit_me函數(shù)的傳出內(nèi)容用以顯示在標(biāo)簽上pathLabel=tk.Label(window,textvariable=path,bg='gray',fg='white',font=('Arial',12),width=30,height=2).place(x=180,y=20)# 說明: bg為背景,fg為字體顏色,font為字體,width為長(zhǎng),height為高,這里的長(zhǎng)和高是字符的長(zhǎng)和高,比如height=2,就是標(biāo)簽有2個(gè)字符這么高# pathLabel.pack()# 第6步,展示識(shí)別結(jié)果resourceScrolledtext=scrolledtext.ScrolledText(window,width=80,height=23,font=("隸書",18))#滾動(dòng)文本框(寬,高(這里的高應(yīng)該是以行數(shù)為單位),字體樣式)resourceScrolledtext.place(x=20,y=100)#滾動(dòng)文本框在頁面的位置# 識(shí)別文字方法defscanPics():filePath=path.get()# 讀取圖片? ? defget_file_content(filePath):withopen(filePath,'rb')as fp:returnfp.read()forroot,dirs,files in os.walk(".",topdown=False):forname in files:if'png'in name:filePath=os.path.join(root,name)[2:]options={'detect_direction':'true','language_type':'CHN_ENG',}result=client.webImage(get_file_content(filePath),options)print(result)resourceScrolledtext.insert("insert",'\n\n')# 在scrolledtext插入間隔,使每張圖片識(shí)別內(nèi)容中間有間隔fori in result['words_result']:print(i['words'])# # 如果需要寫入txt,將此段解注釋即可# f = open("文件名.txt", "a") #a 打開一個(gè)文件用于追加。如果該文件已存在,文件指針將會(huì)放在文件的結(jié)尾。也就是說,新的內(nèi)容將會(huì)被寫入到已有內(nèi)容之后。如果該文件不存在,創(chuàng)建新文件進(jìn)行寫入。# f.write(i['words'] + '\n')# f.close()# 將識(shí)別結(jié)果插入scrolledtext,在窗口試圖中顯示? ? ? ? ? ? ? ? ? ? resourceScrolledtext.insert("insert",i['words']+'\n')# 第7步,識(shí)別文字按鈕scanButton=tk.Button(window,text='開始識(shí)別',font=('Arial',12),command=scanPics).place(x=800,y=20)# scanButton.pack()# 第8步,主窗口循環(huán)顯示window.mainloop()
8、將python打包成.exe文件:
(1)、安裝pyinstaller:pip install pyinstaller
(2)、打包:cd 到文件目錄下,如test.py文件,pyinstaller -F test.py
(3)、執(zhí)行完之后,會(huì)多出一個(gè).spec文件以及build、dist兩個(gè)目錄,dist中的.exe文件直接運(yùn)行即可;
9、測(cè)試:
10、后續(xù)測(cè)試:
按之前步驟進(jìn)行打包成exe后,反復(fù)測(cè)試都識(shí)別不成功,且命令行沒有返回任何結(jié)果,而程序內(nèi)運(yùn)行正常。開始尋找可能的原因,并進(jìn)行測(cè)試。
預(yù)測(cè)原因:“打包后exe程序不能發(fā)送網(wǎng)絡(luò)請(qǐng)求”
測(cè)試1(無果):
以為是打包后的exe程序沒有進(jìn)行網(wǎng)絡(luò)請(qǐng)求,網(wǎng)上有說是使用了第三方庫的話,用pyinstaller打包前,需要把\Lib\site-packages下相應(yīng)的包復(fù)制到同要打包的.py文件同一目錄,經(jīng)反復(fù)測(cè)試無用。
測(cè)試2(成功):
新建一文件requestTest.py,用request做單張圖片識(shí)別請(qǐng)求并打印結(jié)果,測(cè)試打包成exe之后能否成功調(diào)用接口。運(yùn)行打包后的exe,報(bào)錯(cuò):FileNotFoundError:
[Errno 2] No such file or directory: ‘呢呢呢.png’
嘗試將資源圖片復(fù)制到打包好的exe程序同目錄下,即為dist目錄下。此時(shí)再打開exe程序,點(diǎn)擊識(shí)別,成功打印出結(jié)果(但是,此時(shí)已不關(guān)乎GUI中選擇路徑的功能,直接點(diǎn)擊識(shí)別即可識(shí)別,不知其中緣由,但是解除了我“打包后exe程序不能發(fā)送網(wǎng)絡(luò)請(qǐng)求”的猜測(cè))。
測(cè)試3(成功):
仍然換回ocr.py進(jìn)行打包,打包成功后,選擇文件夾,開始識(shí)別,果然還是無打印結(jié)果。把要識(shí)別的文件夾放入dist文件夾下,再打開exe,直接點(diǎn)擊開始識(shí)別,識(shí)別成功。
11、補(bǔ)充:
pyinstaller打包,一些可選參數(shù):
使用順序:pyinstall -i 圖標(biāo)名稱.ico -n 打包后程序名稱 -w -F 要打包的文件名.py
先圖標(biāo)路徑,再程序路徑
(1)、打包單文件模式:-F
(2)、打包成文件夾:-D
(3)、修改icon(圖標(biāo)后綴.ico,不可自行修改,網(wǎng)上有轉(zhuǎn).ico格式的方法):-i xxx.ico
(4)、修改打包后的程序名稱:-n
(5)、不彈出命令行行:-w
如我的程序:pyinstaller -i 笑胖仔.ico -n 批量識(shí)別圖片中文字 -w -F ocr.py