python驗(yàn)證碼識別教程之利用投影法、連通域法分割圖片
前言
今天這篇文章主要記錄一下如何切分驗(yàn)證碼,用到的主要庫就是Pillow和Linux下的圖像處理工具GIMP。首先假設(shè)一個固定位置和寬度、無粘連、無干擾的例子學(xué)習(xí)一下如何使用Pillow來切割圖片。
使用GIMP打開圖片后,按 加號 放大圖片,然后點(diǎn)擊View->Show Grid來顯示網(wǎng)格線:
其中,每個正方形邊長為10像素,所以數(shù)字1切割坐標(biāo)為左20、上20、右40、下70。以此類推可以知道剩下3個數(shù)字的切割位置。
代碼如下:
from PIL import Image p = Image.open("1.png") # 注意位置順序?yàn)樽蟆⑸?、右、? cuts = [(20,20,40,70),(60,20,90,70),(100,10,130,60),(140,20,170,50)] for i,n in enumerate(cuts,1): temp = p.crop(n) # 調(diào)用crop函數(shù)進(jìn)行切割 temp.save("cut%s.png" % i)
切割后得到4張圖片:
那么,如果字符位置不固定怎么辦呢?現(xiàn)在假設(shè)一種隨機(jī)位置寬度、無粘連、無干擾線的情況。
第一種方法,也是最簡單的方法叫做”投影法”。原理就是將二值化后的圖片在豎直方向進(jìn)行投影,根據(jù)投影后的極值來判斷分割邊界。這里我依然使用上面的驗(yàn)證碼圖片來進(jìn)行演示:
def vertical(img): """傳入二值化后的圖片進(jìn)行垂直投影""" pixdata = img.load() w,h = img.size ver_list = [] # 開始投影 for x in range(w): black = 0 for y in range(h): if pixdata[x,y] == 0: black += 1 ver_list.append(black) # 判斷邊界 l,r = 0,0 flag = False cuts = [] for i,count in enumerate(ver_list): # 閾值這里為0 if flag is False and count > 0: l = i flag = True if flag and count == 0: r = i-1 flag = False cuts.append((l,r)) return cuts p = Image.open('1.png') b_img = binarizing(p,200) v = vertical(b_img)
通過vertical函數(shù)我們就得到了一個包含所有黑色像素在X軸上投影后左右邊界的位置。由于驗(yàn)證碼沒有任何干擾,所以我的閾值設(shè)定為0。 關(guān)于binarizing函數(shù)可以參考上一篇文章
輸出如下:
[(21, 37), (62, 89), (100, 122), (146, 164)]
可以看到,投影法給出左右邊界和我們手工查看得到很接近。對于上下邊界,偷懶的可以直接使用0和圖片的高度,也可以在水平方向進(jìn)行投影,這里有興趣的小伙伴可以自己嘗試。
但是,對于字符間有粘連的情況,投影法就會出現(xiàn)拆分錯誤,比如上篇文章中的:
修改閾值為5后,投影法給出的左右邊界是:
[(5, 27), (33, 53), (59, 108)]
明顯最后的6和9數(shù)字沒有切割。
修改閾值為7,結(jié)果則是:
[(5, 27), (33, 53), (60, 79), (83, 108)]
所以對于簡單粘連的情況,調(diào)整閾值也是可以解決的。
第二種方法,叫做CFS連通域分割法。原理就是假定每個字符都由一個單獨(dú)的連通域組成,換言之就是無粘連,找到一個黑色像素并開始判斷,直到所有相連的黑色像素都被遍歷標(biāo)記過后即可判斷出這個字符的分割位置。算法如下:
- 將二值化后的圖片進(jìn)行從左到右、從上到下的遍歷,如果遇到黑色像素并且這個像素沒有沒訪問過,就將這個像素入棧并標(biāo)記為已經(jīng)訪問。
- 如果棧不為空,則繼續(xù)探測周圍8個像素,并執(zhí)行第2步;如果棧空,則代表探測完了一個字符塊。
- 探測結(jié)束,這樣就確定了若干字符。
代碼如下:
import queue def cfs(img): """傳入二值化后的圖片進(jìn)行連通域分割""" pixdata = img.load() w,h = img.size visited = set() q = queue.Queue() offset = [(-1,-1),(0,-1),(1,-1),(-1,0),(1,0),(-1,1),(0,1),(1,1)] cuts = [] for x in range(w): for y in range(h): x_axis = [] #y_axis = [] if pixdata[x,y] == 0 and (x,y) not in visited: q.put((x,y)) visited.add((x,y)) while not q.empty(): x_p,y_p = q.get() for x_offset,y_offset in offset: x_c,y_c = x_p+x_offset,y_p+y_offset if (x_c,y_c) in visited: continue visited.add((x_c,y_c)) try: if pixdata[x_c,y_c] == 0: q.put((x_c,y_c)) x_axis.append(x_c) #y_axis.append(y_c) except: pass if x_axis: min_x,max_x = min(x_axis),max(x_axis) if max_x - min_x > 3: # 寬度小于3的認(rèn)為是噪點(diǎn),根據(jù)需要修改 cuts.append((min_x,max_x)) return cuts
調(diào)用后輸出結(jié)果和使用投影法是一樣的。另外我看網(wǎng)上還有一種叫做“泛洪填充(Flood Fill)”的方法,似乎和連通域是一樣的。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
- python驗(yàn)證碼識別教程之利用滴水算法分割圖片
- python3 實(shí)現(xiàn)對圖片進(jìn)行局部切割的方法
- python opencv實(shí)現(xiàn)圖片旋轉(zhuǎn)矩形分割
- python opencv將表格圖片按照表格框線分割和識別
- python實(shí)現(xiàn)將文件夾內(nèi)的每張圖片批量分割成多張
- python實(shí)現(xiàn)對任意大小圖片均勻切割的示例
- python實(shí)現(xiàn)圖片中文字分割效果
- Python+opencv 實(shí)現(xiàn)圖片文字的分割的方法示例
- python3 實(shí)現(xiàn)驗(yàn)證碼圖片切割的方法
- Python?Opencv實(shí)現(xiàn)圖片切割處理
相關(guān)文章
Python?Pandas讀取csv/tsv文件(read_csv,read_table)的區(qū)別
這篇文章主要給大家介紹了關(guān)于Python?Pandas讀取csv/tsv文件(read_csv,read_table)區(qū)別的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Pandas具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2022-01-01帶你學(xué)習(xí)Python如何實(shí)現(xiàn)回歸樹模型
這篇文章主要介紹了Python如何實(shí)現(xiàn)回歸樹模型,文中講解非常細(xì)致,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07Python如何獲取免費(fèi)高匿代理IP及驗(yàn)證
這篇文章主要介紹了Python如何獲取免費(fèi)高匿代理IP及驗(yàn)證問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06Python threading.local代碼實(shí)例及原理解析
這篇文章主要介紹了Python threading.local代碼實(shí)例及原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03win8下python3.4安裝和環(huán)境配置圖文教程
這篇文章主要為大家詳細(xì)介紹了win8下python3.4安裝和環(huán)境配置圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07python利用opencv調(diào)用攝像頭實(shí)現(xiàn)目標(biāo)檢測
這篇文章主要為大家介紹了python利用opencv調(diào)用攝像頭實(shí)現(xiàn)目標(biāo)檢測的示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05python常用數(shù)據(jù)結(jié)構(gòu)字典梳理
這篇文章主要介紹了python常用數(shù)據(jù)結(jié)構(gòu)字典梳理,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-08-08