python 验证码识别训练_Python爬虫笔记【一】模拟用户访问之Tesseract-ocr验证码训练(5)...
驗證碼處理之后就需要對處理的驗證碼進行識別訓練,這里用Tesseract-ocr工具進行識別,用jTessBoxeditor進行訓練生成模板。
一,對圖片進行處理
利用上一篇代碼對圖片進行降噪處理,得到較為清晰地圖片。
這里需要你在需要登入的網站中提取大量的驗證碼圖片,在獲取圖片時,查看網站的登入框是否在iframe標簽中,已經圖片是否有需要點擊輸入框才會出現,若是如此,可以用selenium中driver來跳轉iframe標簽,用點擊事件來顯示驗證碼,然后再獲取src屬性進行下載。
二,生成tif文件
在獲取一定數量驗證碼后(儲存在images中),打開jTessBoxeditor,Tools>Merge TIFF
選擇之前保存圖片的文件,shift將文件全選,注意文件顯示的格式
之后選擇生成fift路徑以及設置名稱此處名稱要設置為這樣的格式[lang].[fontname].exp[num].tif
其中lang為語言名稱,fontname為字體名稱,num為序號,可以隨便定義。
三,生成box文件
這樣遍將多個jpg文件合成一個tif文件(可能顯示的是一個驗證碼),然后我們需要利用tif文件來生成box文件。
再打開jTessBoxEditor(如果之前有其他好點的模板就選擇其他的,這樣自動識別的會多一點,省之后的人力)。
這一步之后就會在 tif 文件目錄下生成一個box文件,在jTessBoxEditor中打開(如圖 ↓ )
四,調整位置
如果模板較好的話會出現這樣的文件(也許位置可能沒有識別的這么準,那個就需要人工調節,記得保存,下面可以翻頁)
也有可能是這樣
如果是這樣的話,你需要用文本方式打開box文件(六列分別對應,值,位置*4,頁碼值-1),我們需要創建的1~7頁的那四行,隨便找四行復制一下,然后改一下頁碼,沒有框的幾個驗證碼有了,然后再調整位置。(注意最后的一列為? 頁碼數-1 )
在調整完所有驗證碼后,在tif文件目錄下建立一個新建名為下xxx.font_properties的文本文件(xxx與自定義語言名稱相同)內容為 font 0 0 0 0 0
之后再去txt后綴
五,訓練
這樣 tif,box,font_properties文件都有了,就可以生成模板了
訓練完之后就在tif文件下生成了tessdata文件夾,里面便是訓練完成模板mob.traineddata,將模板移動到Tesseract—ocr>tessdata目錄下,這樣便可以用Tesseract-ocr識別驗證碼
from PIL importImagefrom pytesseract import *
from fnmatch importfnmatchfrom queue importQueueimportmatplotlib.pyplot as pltimportcv2importtimeimportosdefclear_border(img,img_name):'''去除邊框'''h, w= img.shape[:2]for y inrange(0, w):for x inrange(0, h):#if y ==0 or y == w -1 or y == w - 2:
if y < 4 or y > w -4:
img[x, y]= 255
#if x == 0 or x == h - 1 or x == h - 2:
if x < 4 or x > h - 4:
img[x, y]= 255
returnimgdefinterference_line(img, img_name):'''干擾線降噪'''h, w= img.shape[:2]#!!!opencv矩陣點是反的
#img[1,2] 1:圖片的高度,2:圖片的寬度
for r in range(0,2):for y in range(1, w - 1):for x in range(1, h - 1):
count=0if img[x, y - 1] > 245:
count= count + 1
if img[x, y + 1] > 245:
count= count + 1
if img[x - 1, y] > 245:
count= count + 1
if img[x + 1, y] > 245:
count= count + 1
if count > 2:
img[x, y]= 255
returnimgdef interference_point(img,img_name, x = 0, y =0):"""點降噪
9鄰域框,以當前點為中心的田字框,黑點個數
:param x:
:param y:
:return:"""
#todo 判斷圖片的長寬度下限
cur_pixel = img[x,y]#當前像素點的值
height,width = img.shape[:2]for y in range(0, width - 1):for x in range(0, height - 1):if y == 0: #第一行
if x == 0: #左上頂點,4鄰域
#中心點旁邊3個點
sum =int(cur_pixel) \+ int(img[x, y + 1]) \+ int(img[x + 1, y]) \+ int(img[x + 1, y + 1])if sum <= 2 * 245:
img[x, y]=0elif x == height - 1: #右上頂點
sum =int(cur_pixel) \+ int(img[x, y + 1]) \+ int(img[x - 1, y]) \+ int(img[x - 1, y + 1])if sum <= 2 * 245:
img[x, y]=0else: #最上非頂點,6鄰域
sum = int(img[x - 1, y]) \+ int(img[x - 1, y + 1]) \+int(cur_pixel) \+ int(img[x, y + 1]) \+ int(img[x + 1, y]) \+ int(img[x + 1, y + 1])if sum <= 3 * 245:
img[x, y]=0elif y == width - 1: #最下面一行
if x == 0: #左下頂點
#中心點旁邊3個點
sum =int(cur_pixel) \+ int(img[x + 1, y]) \+ int(img[x + 1, y - 1]) \+ int(img[x, y - 1])if sum <= 2 * 245:
img[x, y]=0elif x == height - 1: #右下頂點
sum =int(cur_pixel) \+ int(img[x, y - 1]) \+ int(img[x - 1, y]) \+ int(img[x - 1, y - 1])if sum <= 2 * 245:
img[x, y]=0else: #最下非頂點,6鄰域
sum =int(cur_pixel) \+ int(img[x - 1, y]) \+ int(img[x + 1, y]) \+ int(img[x, y - 1]) \+ int(img[x - 1, y - 1]) \+ int(img[x + 1, y - 1])if sum <= 3 * 245:
img[x, y]=0else: #y不在邊界
if x == 0: #左邊非頂點
sum = int(img[x, y - 1]) \+int(cur_pixel) \+ int(img[x, y + 1]) \+ int(img[x + 1, y - 1]) \+ int(img[x + 1, y]) \+ int(img[x + 1, y + 1])if sum <= 3 * 245:
img[x, y]=0elif x == height - 1: #右邊非頂點
sum = int(img[x, y - 1]) \+int(cur_pixel) \+ int(img[x, y + 1]) \+ int(img[x - 1, y - 1]) \+ int(img[x - 1, y]) \+ int(img[x - 1, y + 1])if sum <= 3 * 245:
img[x, y]=0else: #具備9領域條件的
sum = int(img[x - 1, y - 1]) \+ int(img[x - 1, y]) \+ int(img[x - 1, y + 1]) \+ int(img[x, y - 1]) \+int(cur_pixel) \+ int(img[x, y + 1]) \+ int(img[x + 1, y - 1]) \+ int(img[x + 1, y]) \+ int(img[x + 1, y + 1])if sum <= 4 * 245:
img[x, y]=0returnimgdef_get_dynamic_binary_image(filedir,img_name):'''自適應閥值二值化'''filename= './easy_code/' + img_name.split('.')[0] + '-binary.jpg'img_name= filedir + '/' +img_name
im=cv2.imread(img_name)
im=cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
th1= cv2.adaptiveThreshold(im, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 1)returnth1defrecognize():
i=0
filedir= './images' #驗證碼路jing
for file inos.listdir(filedir):if fnmatch(file, '*.jpg'):
img_name=file#自適應閾值二值化
im =_get_dynamic_binary_image(filedir,img_name)#去除邊框
im =clear_border(im,img_name)#對圖片進行干擾線降噪
im =interference_line(im,img_name)#對圖片進行點降噪
im =interference_point(im,img_name)#easy_code為圖片清理后保存路徑
filename = './easy_code/' + img_name.split('.')[0] + '-interferencePoint.jpg'cv2.imwrite(filename,im)#'mob'為模板
str_img = pytesseract.image_to_string(im, lang='mob')
code= str_img.encode("GBK","ignore").decode('GBK')if code.replace(' ','') == img_name.split('.')[0]:
i= i + 1
print(code)print('---' +str(i))
recognize()
View Code
fromPIL import Imagefrom pytesseract import *
fromfnmatch import fnmatchfromqueue import Queue
import matplotlib.pyplotasplt
import cv2
import time
import os
def clear_border(img,img_name):'''去除邊框
'''h, w= img.shape[:2]for y in range(0, w):for x in range(0, h):
#if y ==0 or y == w -1 or y == w - 2:if y < 4 or y > w -4:
img[x, y]= 255#if x == 0 or x == h - 1 or x == h - 2:if x < 4 or x > h - 4:
img[x, y]= 255
returnimg
def interference_line(img, img_name):'''干擾線降噪'''h, w= img.shape[:2]
# !!!opencv矩陣點是反的
# img[1,2] 1:圖片的高度,2:圖片的寬度for r in range(0,2):for y in range(1, w - 1):for x in range(1, h - 1):
count= 0
if img[x, y - 1] > 245:
count= count + 1
if img[x, y + 1] > 245:
count= count + 1
if img[x - 1, y] > 245:
count= count + 1
if img[x + 1, y] > 245:
count= count + 1
if count > 2:
img[x, y]= 255
returnimg
def interference_point(img,img_name, x= 0, y = 0):"""點降噪
9鄰域框,以當前點為中心的田字框,黑點個數
:param x:
:param y:
:return:"""# todo 判斷圖片的長寬度下限
cur_pixel=img[x,y]# 當前像素點的值
height,width= img.shape[:2]for y in range(0, width - 1):for x in range(0, height - 1):if y == 0: # 第一行if x == 0: # 左上頂點,4鄰域
# 中心點旁邊3個點
sum= int(cur_pixel) \+ int(img[x, y + 1]) \+ int(img[x + 1, y]) \+ int(img[x + 1, y + 1])if sum <= 2 * 245:
img[x, y]= 0elif x== height - 1: # 右上頂點
sum= int(cur_pixel) \+ int(img[x, y + 1]) \+ int(img[x - 1, y]) \+ int(img[x - 1, y + 1])if sum <= 2 * 245:
img[x, y]= 0
else: # 最上非頂點,6鄰域
sum= int(img[x - 1, y]) \+ int(img[x - 1, y + 1]) \+ int(cur_pixel) \+ int(img[x, y + 1]) \+ int(img[x + 1, y]) \+ int(img[x + 1, y + 1])if sum <= 3 * 245:
img[x, y]= 0elif y== width - 1: # 最下面一行if x == 0: # 左下頂點
# 中心點旁邊3個點
sum= int(cur_pixel) \+ int(img[x + 1, y]) \+ int(img[x + 1, y - 1]) \+ int(img[x, y - 1])if sum <= 2 * 245:
img[x, y]= 0elif x== height - 1: # 右下頂點
sum= int(cur_pixel) \+ int(img[x, y - 1]) \+ int(img[x - 1, y]) \+ int(img[x - 1, y - 1])if sum <= 2 * 245:
img[x, y]= 0
else: # 最下非頂點,6鄰域
sum= int(cur_pixel) \+ int(img[x - 1, y]) \+ int(img[x + 1, y]) \+ int(img[x, y - 1]) \+ int(img[x - 1, y - 1]) \+ int(img[x + 1, y - 1])if sum <= 3 * 245:
img[x, y]= 0
else: # y不在邊界if x == 0: # 左邊非頂點
sum= int(img[x, y - 1]) \+ int(cur_pixel) \+ int(img[x, y + 1]) \+ int(img[x + 1, y - 1]) \+ int(img[x + 1, y]) \+ int(img[x + 1, y + 1])if sum <= 3 * 245:
img[x, y]= 0elif x== height - 1: # 右邊非頂點
sum= int(img[x, y - 1]) \+ int(cur_pixel) \+ int(img[x, y + 1]) \+ int(img[x - 1, y - 1]) \+ int(img[x - 1, y]) \+ int(img[x - 1, y + 1])if sum <= 3 * 245:
img[x, y]= 0
else: # 具備9領域條件的
sum= int(img[x - 1, y - 1]) \+ int(img[x - 1, y]) \+ int(img[x - 1, y + 1]) \+ int(img[x, y - 1]) \+ int(cur_pixel) \+ int(img[x, y + 1]) \+ int(img[x + 1, y - 1]) \+ int(img[x + 1, y]) \+ int(img[x + 1, y + 1])if sum <= 4 * 245:
img[x, y]= 0
returnimg
def _get_dynamic_binary_image(filedir,img_name):'''自適應閥值二值化''' filename = './easy_code/' + img_name.split('.')[0] + '-binary.jpg'img_name= filedir + '/' +img_name
im=cv2.imread(img_name)
im=cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
th1= cv2.adaptiveThreshold(im, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 1)returnth1
def recognize():
i= 0filedir= './images'#驗證碼路jingfor file inos.listdir(filedir):if fnmatch(file, '*.jpg'):
img_name=file
# 自適應閾值二值化
im=_get_dynamic_binary_image(filedir,img_name)
# 去除邊框
im=clear_border(im,img_name)
# 對圖片進行干擾線降噪
im=interference_line(im,img_name)
# 對圖片進行點降噪
im=interference_point(im,img_name)
# easy_code為圖片清理后保存路徑
filename= './easy_code/' + img_name.split('.')[0] + '-interferencePoint.jpg'cv2.imwrite(filename,im)
#'mob'為模板
str_img= pytesseract.image_to_string(im, lang='mob')
code= str_img.encode("GBK","ignore").decode('GBK')if code.replace('
查閱過的博客:
總結
以上是生活随笔為你收集整理的python 验证码识别训练_Python爬虫笔记【一】模拟用户访问之Tesseract-ocr验证码训练(5)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《燕云十六声》祁氏家驯任务完成攻略
- 下一篇: python对象模型映射_看例子,学 P