日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python 验证码识别训练_Python爬虫笔记【一】模拟用户访问之Tesseract-ocr验证码训练(5)...

發(fā)布時(shí)間:2024/8/5 python 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 验证码识别训练_Python爬虫笔记【一】模拟用户访问之Tesseract-ocr验证码训练(5)... 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

驗(yàn)證碼處理之后就需要對(duì)處理的驗(yàn)證碼進(jìn)行識(shí)別訓(xùn)練,這里用Tesseract-ocr工具進(jìn)行識(shí)別,用jTessBoxeditor進(jìn)行訓(xùn)練生成模板。

一,對(duì)圖片進(jìn)行處理

利用上一篇代碼對(duì)圖片進(jìn)行降噪處理,得到較為清晰地圖片。

這里需要你在需要登入的網(wǎng)站中提取大量的驗(yàn)證碼圖片,在獲取圖片時(shí),查看網(wǎng)站的登入框是否在iframe標(biāo)簽中,已經(jīng)圖片是否有需要點(diǎn)擊輸入框才會(huì)出現(xiàn),若是如此,可以用selenium中driver來(lái)跳轉(zhuǎn)iframe標(biāo)簽,用點(diǎn)擊事件來(lái)顯示驗(yàn)證碼,然后再獲取src屬性進(jìn)行下載。

二,生成tif文件

在獲取一定數(shù)量驗(yàn)證碼后(儲(chǔ)存在images中),打開(kāi)jTessBoxeditor,Tools>Merge TIFF

選擇之前保存圖片的文件,shift將文件全選,注意文件顯示的格式

之后選擇生成fift路徑以及設(shè)置名稱此處名稱要設(shè)置為這樣的格式[lang].[fontname].exp[num].tif

其中l(wèi)ang為語(yǔ)言名稱,fontname為字體名稱,num為序號(hào),可以隨便定義。

三,生成box文件

這樣遍將多個(gè)jpg文件合成一個(gè)tif文件(可能顯示的是一個(gè)驗(yàn)證碼),然后我們需要利用tif文件來(lái)生成box文件。

再打開(kāi)jTessBoxEditor(如果之前有其他好點(diǎn)的模板就選擇其他的,這樣自動(dòng)識(shí)別的會(huì)多一點(diǎn),省之后的人力)。

這一步之后就會(huì)在 tif 文件目錄下生成一個(gè)box文件,在jTessBoxEditor中打開(kāi)(如圖 ↓ )

四,調(diào)整位置

如果模板較好的話會(huì)出現(xiàn)這樣的文件(也許位置可能沒(méi)有識(shí)別的這么準(zhǔn),那個(gè)就需要人工調(diào)節(jié),記得保存,下面可以翻頁(yè))

也有可能是這樣

如果是這樣的話,你需要用文本方式打開(kāi)box文件(六列分別對(duì)應(yīng),值,位置*4,頁(yè)碼值-1),我們需要?jiǎng)?chuàng)建的1~7頁(yè)的那四行,隨便找四行復(fù)制一下,然后改一下頁(yè)碼,沒(méi)有框的幾個(gè)驗(yàn)證碼有了,然后再調(diào)整位置。(注意最后的一列為? 頁(yè)碼數(shù)-1 )

在調(diào)整完所有驗(yàn)證碼后,在tif文件目錄下建立一個(gè)新建名為下xxx.font_properties的文本文件(xxx與自定義語(yǔ)言名稱相同)內(nèi)容為 font 0 0 0 0 0

之后再去txt后綴

五,訓(xùn)練

這樣 tif,box,font_properties文件都有了,就可以生成模板了

訓(xùn)練完之后就在tif文件下生成了tessdata文件夾,里面便是訓(xùn)練完成模板mob.traineddata,將模板移動(dòng)到Tesseract—ocr>tessdata目錄下,這樣便可以用Tesseract-ocr識(shí)別驗(yàn)證碼

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矩陣點(diǎn)是反的

#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):"""點(diǎn)降噪

9鄰域框,以當(dāng)前點(diǎn)為中心的田字框,黑點(diǎn)個(gè)數(shù)

:param x:

:param y:

:return:"""

#todo 判斷圖片的長(zhǎng)寬度下限

cur_pixel = img[x,y]#當(dāng)前像素點(diǎn)的值

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: #左上頂點(diǎn),4鄰域

#中心點(diǎn)旁邊3個(gè)點(diǎn)

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: #右上頂點(diǎn)

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: #最上非頂點(diǎn),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: #左下頂點(diǎn)

#中心點(diǎn)旁邊3個(gè)點(diǎn)

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: #右下頂點(diǎn)

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: #最下非頂點(diǎn),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: #左邊非頂點(diǎn)

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: #右邊非頂點(diǎn)

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領(lǐng)域條件的

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):'''自適應(yīng)閥值二值化'''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' #驗(yàn)證碼路jing

for file inos.listdir(filedir):if fnmatch(file, '*.jpg'):

img_name=file#自適應(yīng)閾值二值化

im =_get_dynamic_binary_image(filedir,img_name)#去除邊框

im =clear_border(im,img_name)#對(duì)圖片進(jìn)行干擾線降噪

im =interference_line(im,img_name)#對(duì)圖片進(jìn)行點(diǎn)降噪

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矩陣點(diǎn)是反的

# img[1,2] 1:圖片的高度,2:圖片的寬度f(wàn)or 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):"""點(diǎn)降噪

9鄰域框,以當(dāng)前點(diǎn)為中心的田字框,黑點(diǎn)個(gè)數(shù)

:param x:

:param y:

:return:"""# todo 判斷圖片的長(zhǎng)寬度下限

cur_pixel=img[x,y]# 當(dāng)前像素點(diǎn)的值

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: # 左上頂點(diǎn),4鄰域

# 中心點(diǎn)旁邊3個(gè)點(diǎn)

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: # 右上頂點(diǎn)

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: # 最上非頂點(diǎn),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: # 左下頂點(diǎn)

# 中心點(diǎn)旁邊3個(gè)點(diǎn)

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: # 右下頂點(diǎn)

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: # 最下非頂點(diǎn),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: # 左邊非頂點(diǎn)

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: # 右邊非頂點(diǎn)

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領(lǐng)域條件的

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):'''自適應(yīng)閥值二值化''' 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'#驗(yàn)證碼路jingfor file inos.listdir(filedir):if fnmatch(file, '*.jpg'):

img_name=file

# 自適應(yīng)閾值二值化

im=_get_dynamic_binary_image(filedir,img_name)

# 去除邊框

im=clear_border(im,img_name)

# 對(duì)圖片進(jìn)行干擾線降噪

im=interference_line(im,img_name)

# 對(duì)圖片進(jìn)行點(diǎn)降噪

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('

查閱過(guò)的博客:

總結(jié)

以上是生活随笔為你收集整理的python 验证码识别训练_Python爬虫笔记【一】模拟用户访问之Tesseract-ocr验证码训练(5)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。