摘要:在上一篇博客圖像處理之圖片文字識(shí)別中我們介紹了在中如何利用軟件來(lái)識(shí)別圖片中的英文與中文,本文將具體介紹如何在中利用軟件來(lái)識(shí)別驗(yàn)證碼數(shù)字加字母。
??在上一篇博客Python圖像處理之圖片文字識(shí)別(OCR)中我們介紹了在Python中如何利用Tesseract軟件來(lái)識(shí)別圖片中的英文與中文,本文將具體介紹如何在Python中利用Tesseract軟件來(lái)識(shí)別驗(yàn)證碼(數(shù)字加字母)。
??我們?cè)诰W(wǎng)上瀏覽網(wǎng)頁(yè)或注冊(cè)賬號(hào)時(shí),會(huì)經(jīng)常遇到驗(yàn)證碼(CAPTCHA),如下圖:
本文將具體介紹如何利用Python的圖像處理模塊pillow和OCR模塊pytesseract來(lái)識(shí)別上述驗(yàn)證碼(數(shù)字加字母)。
??我們識(shí)別上述驗(yàn)證碼的算法過(guò)程如下:
將原圖像進(jìn)行灰度處理,轉(zhuǎn)化為灰度圖像;
獲取圖片中像素點(diǎn)數(shù)量最多的像素(此為圖片背景),將該像素作為閾值進(jìn)行二值化處理,將灰度圖像轉(zhuǎn)化為黑白圖像(用來(lái)提高識(shí)別的準(zhǔn)確率);
去掉黑白圖像中的噪聲,噪聲定義為:以該點(diǎn)為中心的九宮格的黑點(diǎn)的數(shù)量小于等于4;
利用pytesseract模塊識(shí)別,去掉識(shí)別結(jié)果中的特殊字符,獲得識(shí)別結(jié)果。
??我們的圖片如下(共66張圖片):
??完整的Python代碼如下:
import os import pytesseract from PIL import Image from collections import defaultdict # tesseract.exe所在的文件路徑 pytesseract.pytesseract.tesseract_cmd = "C://Program Files (x86)/Tesseract-OCR/tesseract.exe" # 獲取圖片中像素點(diǎn)數(shù)量最多的像素 def get_threshold(image): pixel_dict = defaultdict(int) # 像素及該像素出現(xiàn)次數(shù)的字典 rows, cols = image.size for i in range(rows): for j in range(cols): pixel = image.getpixel((i, j)) pixel_dict[pixel] += 1 count_max = max(pixel_dict.values()) # 獲取像素出現(xiàn)出多的次數(shù) pixel_dict_reverse = {v:k for k,v in pixel_dict.items()} threshold = pixel_dict_reverse[count_max] # 獲取出現(xiàn)次數(shù)最多的像素點(diǎn) return threshold # 按照閾值進(jìn)行二值化處理 # threshold: 像素閾值 def get_bin_table(threshold): # 獲取灰度轉(zhuǎn)二值的映射table table = [] for i in range(256): rate = 0.1 # 在threshold的適當(dāng)范圍內(nèi)進(jìn)行處理 if threshold*(1-rate)<= i <= threshold*(1+rate): table.append(1) else: table.append(0) return table # 去掉二值化處理后的圖片中的噪聲點(diǎn) def cut_noise(image): rows, cols = image.size # 圖片的寬度和高度 change_pos = [] # 記錄噪聲點(diǎn)位置 # 遍歷圖片中的每個(gè)點(diǎn),除掉邊緣 for i in range(1, rows-1): for j in range(1, cols-1): # pixel_set用來(lái)記錄該店附近的黑色像素的數(shù)量 pixel_set = [] # 取該點(diǎn)的鄰域?yàn)橐栽擖c(diǎn)為中心的九宮格 for m in range(i-1, i+2): for n in range(j-1, j+2): if image.getpixel((m, n)) != 1: # 1為白色,0位黑色 pixel_set.append(image.getpixel((m, n))) # 如果該位置的九宮內(nèi)的黑色數(shù)量小于等于4,則判斷為噪聲 if len(pixel_set) <= 4: change_pos.append((i,j)) # 對(duì)相應(yīng)位置進(jìn)行像素修改,將噪聲處的像素置為1(白色) for pos in change_pos: image.putpixel(pos, 1) return image # 返回修改后的圖片 # 識(shí)別圖片中的數(shù)字加字母 # 傳入?yún)?shù)為圖片路徑,返回結(jié)果為:識(shí)別結(jié)果 def OCR_lmj(img_path): image = Image.open(img_path) # 打開(kāi)圖片文件 imgry = image.convert("L") # 轉(zhuǎn)化為灰度圖 # 獲取圖片中的出現(xiàn)次數(shù)最多的像素,即為該圖片的背景 max_pixel = get_threshold(imgry) # 將圖片進(jìn)行二值化處理 table = get_bin_table(threshold=max_pixel) out = imgry.point(table, "1") # 去掉圖片中的噪聲(孤立點(diǎn)) out = cut_noise(out) #保存圖片 # out.save("E://figures/img_gray.jpg") # 僅識(shí)別圖片中的數(shù)字 #text = pytesseract.image_to_string(out, config="digits") # 識(shí)別圖片中的數(shù)字和字母 text = pytesseract.image_to_string(out) # 去掉識(shí)別結(jié)果中的特殊字符 exclude_char_list = " .:|""?![],()~@#$%^&*_+-={};<>/¥" text = "".join([x for x in text if x not in exclude_char_list]) #print(text) return text def main(): # 識(shí)別指定文件目錄下的圖片 # 圖片存放目錄figures dir = "E://figures" correct_count = 0 # 圖片總數(shù) total_count = 0 # 識(shí)別正確的圖片數(shù)量 # 遍歷figures下的png,jpg文件 for file in os.listdir(dir): if file.endswith(".png") or file.endswith(".jpg"): # print(file) image_path = "%s/%s"%(dir,file) # 圖片路徑 answer = file.split(".")[0] # 圖片名稱(chēng),即圖片中的正確文字 recognizition = OCR_lmj(image_path) # 圖片識(shí)別的文字結(jié)果 print((answer, recognizition)) if recognizition == answer: # 如果識(shí)別結(jié)果正確,則total_count加1 correct_count += 1 total_count += 1 print("Total count: %d, correct: %d."%(total_count, correct_count)) """ # 單張圖片識(shí)別 image_path = "E://figures/code (1).jpg" OCR_lmj(image_path) """ main()
運(yùn)行結(jié)果如下:
("101659", "101659") ("111073", "111073") ("114510", "114510") ("118235", "118235") ("124677", "124677") ("147291", "147291") ("169147", "169147") ("185302", "185302") ("23YB", "23YB") ("262051", "262051") ("2HED", "2MED") ("315386", "315386") ("3D7K", "3D7K") ("3DYH", "3DYH") ("3QG8", "30G8") ("3XNR", "EXNR") ("44G5", "44G5") ("470259", "470259") ("515413", "515413") ("522351", "522351") ("539824", "539824") ("5CVL", "SCVL") ("642689", "642689") ("671991", "671991") ("672838", "672838") ("6F5Y", "6F5Y") ("6USB", "GUSB") ("703167", "703167") ("765120", "765120") ("779931", "779931") ("8UEF", "8SUEF") ("905857", "905857") ("9H4H", "9H4H") ("9SK1", "OSK1") ("BDP4", "BDP4") ("DXV3", "DXV3") ("E78Y", "E78Y") ("EAHR", "EAHR") ("F585", "Fss§") ("FBV8", "FBV8") ("FJKK", "FJKK") ("GXKQ", "GXKQ") ("H7Y9", "H7Y9") ("J4LJ", "J4LJ") ("J8YH", "J8YH") ("JCDL", "JCDL") ("JTX2", "JTX2") ("JYLH", "JYLH") ("KFYA", "KFYA") ("L3VZ", "L3VZ") ("LCGV", "LCGV") ("LKEK", "LKEK") ("N3FJ", "N3FJ") ("PJZN", "PJZN") ("PNDQ", "PNDQ") ("Q7HP", "Q7HP") ("QSHU", "QSHU") ("R1RN", "RLRN") ("RPNX", "RPNX") ("TUKG", "TUKG") ("U9G3", "U9G3") ("UZAH", "UZAH") ("V6P9", "very") ("Y18D", "18D") ("Y237", "Y237") ("ZZT5", "2215") Total count: 66, correct: 54.
我們可以看到圖片識(shí)別的正確率為80%以上,其中數(shù)字類(lèi)圖片的識(shí)別正確率為100%.
??我們可以在圖片識(shí)別方面的算法再加改進(jìn),以提高圖片識(shí)別的正確率。當(dāng)然,以上算法并不是對(duì)所有驗(yàn)證碼都適用,不同的驗(yàn)證碼需要用不同的圖片處理算法。
注意:本人現(xiàn)已開(kāi)通兩個(gè)微信公眾號(hào): 因?yàn)镻ython(微信號(hào)為:python_math)以及輕松學(xué)會(huì)Python爬蟲(chóng)(微信號(hào)為:easy_web_scrape), 歡迎大家關(guān)注哦~~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/41835.html
摘要:時(shí)間永遠(yuǎn)都過(guò)得那么快,一晃從年注冊(cè),到現(xiàn)在已經(jīng)過(guò)去了年那些被我藏在收藏夾吃灰的文章,已經(jīng)太多了,是時(shí)候把他們整理一下了。那是因?yàn)槭詹貖A太亂,橡皮擦給設(shè)置私密了,不收拾不好看呀。 ...
摘要:學(xué)習(xí)網(wǎng)絡(luò)爬蟲(chóng)主要分個(gè)大的版塊抓取,分析,存儲(chǔ)另外,比較常用的爬蟲(chóng)框架,這里最后也詳細(xì)介紹一下。網(wǎng)絡(luò)爬蟲(chóng)要做的,簡(jiǎn)單來(lái)說(shuō),就是實(shí)現(xiàn)瀏覽器的功能。 Python學(xué)習(xí)網(wǎng)絡(luò)爬蟲(chóng)主要分3個(gè)大的版塊:抓取,分析,存儲(chǔ) 另外,比較常用的爬蟲(chóng)框架Scrapy,這里最后也詳細(xì)介紹一下。 首先列舉一下本人總結(jié)的相關(guān)文章,這些覆蓋了入門(mén)網(wǎng)絡(luò)爬蟲(chóng)需要的基本概念和技巧:寧哥的小站-網(wǎng)絡(luò)爬蟲(chóng),當(dāng)我們?cè)跒g覽器中輸入...
python作為一門(mén)比較常見(jiàn)的編程語(yǔ)言,在工作當(dāng)中的應(yīng)用還是比較的廣泛的,比如可以對(duì)此進(jìn)行相關(guān)的自動(dòng)化測(cè)試,比如自動(dòng)化測(cè)試相關(guān)的代碼,另外還有破解滑動(dòng)驗(yàn)證碼。那么,具體的操作手法是怎樣的呢?下面就給大家詳細(xì)解答下。 在Web自動(dòng)化測(cè)試的過(guò)程中,經(jīng)常會(huì)被登錄的驗(yàn)證碼給卡住,不知道如何去通過(guò)驗(yàn)證碼的驗(yàn)證。 一般的情況下遇到驗(yàn)證碼我們可以都可以找開(kāi)發(fā)去幫忙解決,關(guān)閉驗(yàn)證碼,或者給一個(gè)萬(wàn)能的驗(yàn)證碼...
小編寫(xiě)這篇文章的主要目的,主要是用來(lái)給大家介紹關(guān)于python自動(dòng)化測(cè)試的一些事情,涉及到的內(nèi)容主要有包括破解圖文驗(yàn)證碼等相關(guān)的一些事宜,具體怎么才能夠破解圖文驗(yàn)證碼呢?下面就給大家詳細(xì)解答下。 對(duì)于web應(yīng)用程序來(lái)講,處于安全性考慮,在登錄的時(shí)候,都會(huì)設(shè)置驗(yàn)證碼, 驗(yàn)證碼的類(lèi)型種類(lèi)繁多,有圖片中辨別數(shù)字字母的,有點(diǎn)擊圖片中指定的文字的,也有算術(shù)計(jì)算結(jié)果的,再?gòu)?fù)雜一點(diǎn)就是滑動(dòng)驗(yàn)證的?! ≈T...
閱讀 2649·2023-04-26 02:17
閱讀 1623·2021-11-24 09:39
閱讀 1083·2021-11-18 13:13
閱讀 2660·2021-09-02 15:11
閱讀 2784·2019-08-30 15:48
閱讀 3415·2019-08-30 14:00
閱讀 2446·2019-08-29 13:43
閱讀 666·2019-08-29 13:07