opencv實踐——驗證碼識別


完成了opencv基礎知識學習,現在進行實踐操作

1、生成隨機四位數字驗證碼

import os
import random
# captcha是用於生成驗證碼圖片的庫,可以 pip install captcha 來安裝它
from captcha.image import ImageCaptcha


def random_captcha_text(num):
    # 驗證碼列表
    captcha_text = []
    for i in range(10):  # 0-9數字
        captcha_text.append(str(i))
    # for i in range(65, 91):  # 對應從“A”到“Z”的ASCII碼
    #     captcha_text.append(chr(i))
    # for i in range(97, 123):  # 對應從“a”到“z”的ASCII碼
    #     captcha_text.append(chr(i))

    # 從list中隨機獲取6個元素,作為一個片斷返回
    example = random.sample(captcha_text, num)

    # 將列表里的片段變為字符串並返回
    verification_code = ''.join(example)
    return verification_code


# 生成字符對應的驗證碼
def generate_captcha_image():
    image = ImageCaptcha()
    # 獲得隨機生成的驗證碼
    captcha_text = random_captcha_text(4)
    # 把驗證碼列表轉為字符串
    captcha_text = ''.join(captcha_text)
    # 生成驗證碼

    path = 'D:/驗證碼識別/test/'
    if not os.path.exists(path):
        print("目錄不存在!,已自動創建")
        os.makedirs(path)
    print("生成的驗證碼的圖片為:", captcha_text)
    image.write(captcha_text, path + captcha_text + '.png')


if __name__ == '__main__':
    number = 100
    for i in range(number):
        generate_captcha_image()

2、安裝pytesseract包,中間出現很多問題,最終查閱資料得以解決

3、對驗證碼圖片進行預處理

圖像預處理主要包括對圖像的灰度化、二值化、去噪聲,以及圖像傾斜的矯正和增強等。

(1)灰度化:
對圖像進行灰度處理,是為了減少識別樣本的計算量,將圖像樣本統一,簡化訓練和識別難度。

Gray=0-299R+0.587G+0.114B(1)

(2)二值化:
二值化指將圖像上的像素點轉化為黑白兩種顏色的點,即將灰度值設置為0(黑)或255(白)。其目的是區分圖像的前后景,使圖像呈現明顯的視覺效果,同時為后續的識別和處理做准備。我試了幾種二值化的方法最后選擇了OTSU,可以明顯發現圖像中有一些橫線和小點點的干擾

 

 

# 二值圖像就是將灰度圖轉化成黑白圖,沒有灰,在一個值之前為黑,之后為白
# 有全局和局部兩種
# 在使用全局閾值時,我們就是隨便給了一個數來做閾值,那我們怎么知道我們選取的這個數的好壞呢?答案就是不停的嘗試。
# 如果是一副雙峰圖像(簡 單來說雙峰圖像是指圖像直方圖中存在兩個峰)呢?
# 我們豈不是應該在兩個峰之間的峰谷選一個值作為閾值?這就是 Otsu 二值化要做的。
# 簡單來說就是對 一副雙峰圖像自動根據其直方圖計算出一個閾值。
# (對於非雙峰圖像,這種方法 得到的結果可能會不理想)。

(3)去噪聲:
圖像中往往含有噪聲,要對圖形進行噪聲處理,減少噪聲影響,將噪聲干擾降到最低,我采用開運算,因為開運算的特性,正好可以降低干擾。

 

然后再試着改變kernel算子的值,我先設置的是(2,2)效果如上圖,后來找到最合適的是(3,3)

基本沒有小白點了

 

 

 


開運算:先進性腐蝕再進行膨脹就叫做開運算,它被用來去除噪聲。
閉運算:先膨脹再腐蝕。它經常被用來填充前景物體中的小洞,或者前景物體上的小黑點。
這里我們用到的函數是 cv2.morphologyEx()。
開閉操作作用:
1. 去除小的干擾塊-開操作
2. 填充閉合區間-閉操作
3. 水平或垂直線提取,調整kernel的row,col值差異。
比如:采用開操作,kernel為(1, 15),提取垂直線,kernel為(15, 1),提取水平線,
"""

def recongize_text(image):
    gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
    cv.imshow("gray1",gray)
    gray=interference_line(gray)
    cv.imshow("gray2",gray)

    ret,binary=cv.threshold(gray,0,255,cv.THRESH_BINARY_INV|cv.THRESH_OTSU)
    # binary = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)
    kernel=cv.getStructuringElement(cv.MORPH_RECT,(3,4))
    open_out=cv.morphologyEx(binary,cv.MORPH_OPEN,kernel)
    # open_out=cv.morphologyEx(open_out,cv.MORPH_CLOSE,kernel)

    cv.imshow("binary_image",open_out)

    cv.bitwise_not(open_out,open_out)
    cv.imshow("dd",open_out)

    result = np.array(open_out)
    ss = cv.medianBlur(result, 5)
    cv.imshow('66666.png', ss)

    textImage=Image.fromarray(ss)

    target = tess.image_to_string(textImage)
    print("識別結果:%s "%target)

 

 

 

但是由於,tesseract這個庫識別的效果並不是很理想,他會自動把數字識別成其他的符號或者字母

或者直接識別不出來,不同的驗證碼,需要選取不同的opencv圖像處理方式

所以上網查閱資料,自己創建庫

(4)tesseract訓練

大體流程為:安裝jTessBoxEditor -> 獲取樣本文件 -> Merge樣本文件 –> 生成BOX文件 -> 定義字符配置文件 -> 字符矯正 -> 執行批處理文件 -> 將生成的traineddata放入tessdata中

1、用jTessBoxEditor把要訓練樣本圖片文件合並成tif文件(樣本圖片一定要為有效的格式圖片)

       運行jTessBoxEditor程序,界面如下: 

 

點擊頂欄的Tools選項,選擇Merge TIFF..   進入你要訓練的樣本圖片所在的目錄,點擊Ctrl+Alt+A,選擇所有圖片點擊打開:

 

然后保存文件名到指定目錄,我這里保存的文件名為: langyp.font.exp0.tif

2、生成Box文件

 打開cmd,到你langyp.font.exp0.tif文件所在目錄,執行:

  tesseract langyp.font.exp0.tif langyp.font.exp0 batch.nochop makebox

 

結果生成了langyp.font.exp0.box文件

3、 對樣本圖片用jTessBoxEditor工具進行矯正

點擊jTessBoxEditor工具的Box Editor選項,點擊下方的open選項,打開剛剛生成的langyp.font.exp0.tif文件,結果如下: 

 

 

右側為對應的Box文件數據,如果char的字符和當前的樣本圖片一致時就進行矯正,修改char里的字符,然后進行save,這樣就矯正了,進入下張樣本圖片時,同樣,矯正后點擊save,當所有樣本圖片都矯正了,這一步也就完成了

4、生成font_properties文件(該文件沒有后綴名)
 
在命令行執行:echo font 0 0 0 0 0 >font_properties
 結果生成了font_properties文件 

 

 內容為字體名font,后面帶5個0,分別代表字體的粗體、斜體等屬性,這里全部是0

5、生成.tr訓練文件
在命令行執行: tesseract langyp.font.exp0.tif langyp.font.exp0 -l eng -psm 7 nobatch box.train

 

 6、生成字符集文件
在命令行執行 : unicharset_extractor langyp.font.exp0.box

 

 

結果生成了unicharset文件

7、生成shape文件
在命令行執行 : shapeclustering -F font_properties -U unicharset -O langyp.unicharset langyp.font.exp0.tr

 

結果生成了shapetable文件和langyp.unicharset文件

8、生成聚集字符特征文件
在命令行執行: mftraining -F font_properties -U unicharset -O langyp.unicharset langyp.font.exp0.tr

結果生成了pffmtable,inttemp,unicharset文件

9、生成字符正常化特征文件
在命令行執行: cntraining langyp.font.exp0.tr

 

結果生成了normproto文件

10、把h,i步驟生成的文件用rename命令進行更名
在命令行執行:  
**rename normproto fontyp.normproto  
rename inttemp fontyp.inttemp  
rename pffmtable fontyp.pffmtable  
rename unicharset fontyp.unicharset  
rename shapetable fontyp.shapetable** 

11、合並訓練文件
在命令行執行: combine_tessdata fontyp

 

12、將fontyp.traineddata文件拷貝至Tesseract-OCR文件夾里的tessdata語言包文件夾里

windows下面:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM