成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Python圖像處理之圖片驗(yàn)證碼識(shí)別

kk_miles / 1187人閱讀

摘要:在上一篇博客圖像處理之圖片文字識(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

相關(guān)文章

  • 首次公開(kāi),整理12年積累的博客收藏夾,零距離展示《收藏夾吃灰》系列博客

    摘要:時(shí)間永遠(yuǎn)都過(guò)得那么快,一晃從年注冊(cè),到現(xiàn)在已經(jīng)過(guò)去了年那些被我藏在收藏夾吃灰的文章,已經(jīng)太多了,是時(shí)候把他們整理一下了。那是因?yàn)槭詹貖A太亂,橡皮擦給設(shè)置私密了,不收拾不好看呀。 ...

    Harriet666 評(píng)論0 收藏0
  • Python入門(mén)網(wǎng)絡(luò)爬蟲(chóng)精華版

    摘要:學(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覽器中輸入...

    Bmob 評(píng)論0 收藏0
  • python自動(dòng)化測(cè)試破解滑動(dòng)驗(yàn)證

      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)證碼...

    89542767 評(píng)論0 收藏0
  • python自動(dòng)化測(cè)試破解圖文驗(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...

    89542767 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<