成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Python驗(yàn)證碼函數(shù),python 驗(yàn)證碼

請(qǐng)教生成如圖驗(yàn)證碼的python算法

def gene_text():

創(chuàng)新互聯(lián)是一家專業(yè)提供扶綏企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、H5場景定制、小程序制作等業(yè)務(wù)。10年已為扶綏眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進(jìn)行中。

source = list(string.letters)

for index in range(0,10):

source.append(str(index))

return ''.join(random.sample(source,number))#number是生成驗(yàn)證碼的位數(shù)

然后我們要?jiǎng)?chuàng)建一個(gè)圖片,寫入字符串,需要說明的這里面的字體是不同系統(tǒng)而定,如果沒有找到系統(tǒng)字體路徑的話,也可以不設(shè)置

def gene_code():

width,height = size #寬和高

image = Image.new('RGBA',(width,height),bgcolor) #創(chuàng)建圖片

font = ImageFont.truetype(font_path,25) #驗(yàn)證碼的字體和字體大小

draw = ImageDraw.Draw(image) #創(chuàng)建畫筆

text = gene_text() #生成字符串

font_width, font_height = font.getsize(text)

draw.text(((width - font_width) / number, (height - font_height) / number),text,

font= font,fill=fontcolor) #填充字符串

接下來,我們要在圖片上畫幾條干擾線

#用來繪制干擾線

def gene_line(draw,width,height):

begin = (random.randint(0, width), random.randint(0, height))

end = (random.randint(0, width), random.randint(0, height))

draw.line([begin, end], fill = linecolor)

最后創(chuàng)建扭曲,加上濾鏡,用來增強(qiáng)驗(yàn)證碼的效果。

image = image.transform((width+20,height+10), Image.AFFINE, (1,-0.3,0,-0.1,1,0),Image.BILINEAR) #創(chuàng)建扭曲

image = image.filter(ImageFilter.EDGE_ENHANCE_MORE) #濾鏡,邊界加強(qiáng)

image.save('idencode.png') #保存驗(yàn)證碼圖片

python怎樣調(diào)用第三方平臺(tái)識(shí)別驗(yàn)證碼

一、pytesseract介紹

1、pytesseract說明

pytesseract最新版本0.1.6,網(wǎng)址:h

Python-tesseract is a wrapper for google's Tesseract-OCR

( ht-ocr/ ). It is also useful as a

stand-alone invocation script to tesseract, as it can read all image types

supported by the Python Imaging Library, including jpeg, png, gif, bmp, tiff,

and others, whereas tesseract-ocr by default only supports tiff and bmp.

Additionally, if used as a script, Python-tesseract will print the recognized

text in stead of writing it to a file. Support for confidence estimates and

bounding box data is planned for future releases.

翻譯一下大意:

a、Python-tesseract是一個(gè)基于google's Tesseract-OCR的獨(dú)立封裝包;

b、Python-tesseract功能是識(shí)別圖片文件中文字,并作為返回參數(shù)返回識(shí)別結(jié)果;

c、Python-tesseract默認(rèn)支持tiff、bmp格式圖片,只有在安裝PIL之后,才能支持jpeg、gif、png等其他圖片格式;

2、pytesseract安裝

INSTALLATION:

Prerequisites:

* Python-tesseract requires python 2.5 or later or python 3.

* You will need the Python Imaging Library (PIL). Under Debian/Ubuntu, this is

the package "python-imaging" or "python3-imaging" for python3.

* Install google tesseract-ocr from hsseract-ocr/ .

You must be able to invoke the tesseract command as "tesseract". If this

isn't the case, for example because tesseract isn't in your PATH, you will

have to change the "tesseract_cmd" variable at the top of 'tesseract.py'.

Under Debian/Ubuntu you can use the package "tesseract-ocr".

Installing via pip:?

See the [pytesseract package page](hi/pytesseract)?

```

$ sudo pip install pytesseract

翻譯一下:

a、Python-tesseract支持python2.5及更高版本;

b、Python-tesseract需要安裝PIL(Python Imaging Library) ,來支持更多的圖片格式;

c、Python-tesseract需要安裝tesseract-ocr安裝包,具體參看上一篇博文。

綜上,Pytesseract原理:

1、上一篇博文中提到,執(zhí)行命令行 tesseract.exe 1.png output -l eng ,可以識(shí)別1.png中文字,并把識(shí)別結(jié)果輸出到output.txt中;

2、Pytesseract對(duì)上述過程進(jìn)行了二次封裝,自動(dòng)調(diào)用tesseract.exe,并讀取output.txt文件的內(nèi)容,作為函數(shù)的返回值進(jìn)行返回。

二、pytesseract使用

USAGE:

```

try:

import Image

except ImportError:

from PIL import Image

import pytesseract

print(pytesseract.image_to_string(Image.open('test.png')))

print(pytesseract.image_to_string(Image.open('test-european.jpg'),))

可以看到:

1、核心代碼就是image_to_string函數(shù),該函數(shù)還支持-l eng 參數(shù),支持-psm 參數(shù)。

用法:

image_to_string(Image.open('test.png'),lang="eng" config="-psm 7")

2、pytesseract里調(diào)用了image,所以才需要PIL,其實(shí)tesseract.exe本身是支持jpeg、png等圖片格式的。

實(shí)例代碼,識(shí)別某公共網(wǎng)站的驗(yàn)證碼(大家千萬別干壞事啊,思慮再三,最后還是隱掉網(wǎng)站域名,大家去找別的網(wǎng)站試試吧……):

View Code

三、pytesseract代碼優(yōu)化

上述程序在windows平臺(tái)運(yùn)行時(shí),會(huì)發(fā)現(xiàn)有黑色的控制臺(tái)窗口一閃而過的畫面,不太友好。

略微修改了pytesseract.py(C:\Python27\Lib\site-packages\pytesseract目錄下),把上述過程進(jìn)行了隱藏。

# modified by zhongtang hide console window

# new code

IS_WIN32 = 'win32' in str(sys.platform).lower()

if IS_WIN32:

startupinfo = subprocess.STARTUPINFO()

startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

startupinfo.wShowWindow = subprocess.SW_HIDE

proc = subprocess.Popen(command,

stderr=subprocess.PIPE,startupinfo=startupinfo)

'''

# old code

proc = subprocess.Popen(command,

stderr=subprocess.PIPE)

'''

# modified end

為了方便初學(xué)者,把pytesseract.py也貼出來,高手自行忽略。

View Code

如何利用Python做簡單的驗(yàn)證碼識(shí)別

1???摘要

驗(yàn)證碼是目前互聯(lián)網(wǎng)上非常常見也是非常重要的一個(gè)事物,充當(dāng)著很多系統(tǒng)的?防火墻?功能,但是隨時(shí)OCR技術(shù)的發(fā)展,驗(yàn)證碼暴露出來的安全問題也越來越嚴(yán)峻。本文介紹了一套字符驗(yàn)證碼識(shí)別的完整流程,對(duì)于驗(yàn)證碼安全和OCR識(shí)別技術(shù)都有一定的借鑒意義。

然后經(jīng)過了一年的時(shí)間,筆者又研究和get到了一種更強(qiáng)大的基于CNN卷積神經(jīng)網(wǎng)絡(luò)的直接端到端的驗(yàn)證識(shí)別技術(shù)(文章不是我的,然后我把源碼整理了下,介紹和源碼在這里面):

基于python語言的tensorflow的‘端到端’的字符型驗(yàn)證碼識(shí)別源碼整理(github源碼分享)

2???關(guān)鍵詞

關(guān)鍵詞:安全,字符圖片,驗(yàn)證碼識(shí)別,OCR,Python,SVM,PIL

3???免責(zé)聲明

本文研究所用素材來自于某舊Web框架的網(wǎng)站?完全對(duì)外公開?的公共圖片資源。

本文只做了該網(wǎng)站對(duì)外公開的公共圖片資源進(jìn)行了爬取,?并未越權(quán)?做任何多余操作。

本文在書寫相關(guān)報(bào)告的時(shí)候已經(jīng)?隱去?漏洞網(wǎng)站的身份信息。

本文作者?已經(jīng)通知?網(wǎng)站相關(guān)人員此系統(tǒng)漏洞,并積極向新系統(tǒng)轉(zhuǎn)移。

本報(bào)告的主要目的也僅是用于?OCR交流學(xué)習(xí)?和引起大家對(duì)?驗(yàn)證安全的警覺?。

4???引言

關(guān)于驗(yàn)證碼的非技術(shù)部分的介紹,可以參考以前寫的一篇科普類的文章:

互聯(lián)網(wǎng)安全防火墻(1)--網(wǎng)絡(luò)驗(yàn)證碼的科普

里面對(duì)驗(yàn)證碼的種類,使用場景,作用,主要的識(shí)別技術(shù)等等進(jìn)行了講解,然而并沒有涉及到任何技術(shù)內(nèi)容。本章內(nèi)容則作為它的?技術(shù)補(bǔ)充?來給出相應(yīng)的識(shí)別的解決方案,讓讀者對(duì)驗(yàn)證碼的功能及安全性問題有更深刻的認(rèn)識(shí)。

5???基本工具

要達(dá)到本文的目的,只需要簡單的編程知識(shí)即可,因?yàn)楝F(xiàn)在的機(jī)器學(xué)習(xí)領(lǐng)域的蓬勃發(fā)展,已經(jīng)有很多封裝好的開源解決方案來進(jìn)行機(jī)器學(xué)習(xí)。普通程序員已經(jīng)不需要了解復(fù)雜的數(shù)學(xué)原理,即可以實(shí)現(xiàn)對(duì)這些工具的應(yīng)用了。

主要開發(fā)環(huán)境:

python3.5

python SDK版本

PIL

圖片處理庫

libsvm

開源的svm機(jī)器學(xué)習(xí)庫

關(guān)于環(huán)境的安裝,不是本文的重點(diǎn),故略去。

6???基本流程

一般情況下,對(duì)于字符型驗(yàn)證碼的識(shí)別流程如下:

準(zhǔn)備原始圖片素材

圖片預(yù)處理

圖片字符切割

圖片尺寸歸一化

圖片字符標(biāo)記

字符圖片特征提取

生成特征和標(biāo)記對(duì)應(yīng)的訓(xùn)練數(shù)據(jù)集

訓(xùn)練特征標(biāo)記數(shù)據(jù)生成識(shí)別模型

使用識(shí)別模型預(yù)測新的未知圖片集

達(dá)到根據(jù)“圖片”就能返回識(shí)別正確的字符集的目標(biāo)

7???素材準(zhǔn)備

7.1???素材選擇

由于本文是以初級(jí)的學(xué)習(xí)研究目的為主,要求?“有代表性,但又不會(huì)太難”?,所以就直接在網(wǎng)上找個(gè)比較有代表性的簡單的字符型驗(yàn)證碼(感覺像在找漏洞一樣)。

最后在一個(gè)比較舊的網(wǎng)站(估計(jì)是幾十年前的網(wǎng)站框架)找到了這個(gè)驗(yàn)證碼圖片。

原始圖:

放大清晰圖:

此圖片能滿足要求,仔細(xì)觀察其具有如下特點(diǎn)。

有利識(shí)別的特點(diǎn)?:

由純阿拉伯?dāng)?shù)字組成

字?jǐn)?shù)為4位

字符排列有規(guī)律

字體是用的統(tǒng)一字體

以上就是本文所說的此驗(yàn)證碼簡單的重要原因,后續(xù)代碼實(shí)現(xiàn)中會(huì)用到

不利識(shí)別的特點(diǎn)?:

圖片背景有干擾噪點(diǎn)

這雖然是不利特點(diǎn),但是這個(gè)干擾門檻太低,只需要簡單的方法就可以除去

7.2???素材獲取

由于在做訓(xùn)練的時(shí)候,需要大量的素材,所以不可能用手工的方式一張張?jiān)跒g覽器中保存,故建議寫個(gè)自動(dòng)化下載的程序。

主要步驟如下:

通過瀏覽器的抓包功能獲取隨機(jī)圖片驗(yàn)證碼生成接口

批量請(qǐng)求接口以獲取圖片

將圖片保存到本地磁盤目錄中

這些都是一些IT基本技能,本文就不再詳細(xì)展開了。

關(guān)于網(wǎng)絡(luò)請(qǐng)求和文件保存的代碼,如下:

def downloads_pic(**kwargs):

pic_name = kwargs.get('pic_name', None)

url = 'httand_code_captcha/'

res = requests.get(url, stream=True)

with open(pic_path + pic_name+'.bmp', 'wb') as f: ? ? ? ?for chunk in res.iter_content(chunk_size=1024): ? ? ? ? ? ?if chunk: ?# filter out keep-alive new chunks ? ? ? ? ? ? ? ?f.write(chunk)

? ? ? ? ?f.flush()

?f.close()

循環(huán)執(zhí)行N次,即可保存N張驗(yàn)證素材了。

下面是收集的幾十張素材庫保存到本地文件的效果圖:

8???圖片預(yù)處理

雖然目前的機(jī)器學(xué)習(xí)算法已經(jīng)相當(dāng)先進(jìn)了,但是為了減少后面訓(xùn)練時(shí)的復(fù)雜度,同時(shí)增加識(shí)別率,很有必要對(duì)圖片進(jìn)行預(yù)處理,使其對(duì)機(jī)器識(shí)別更友好。

針對(duì)以上原始素材的處理步驟如下:

讀取原始圖片素材

將彩色圖片二值化為黑白圖片

去除背景噪點(diǎn)

8.1???二值化圖片

主要步驟如下:

將RGB彩圖轉(zhuǎn)為灰度圖

將灰度圖按照設(shè)定閾值轉(zhuǎn)化為二值圖

image = Image.open(img_path)

imgry = image.convert('L') ?# 轉(zhuǎn)化為灰度圖table = get_bin_table()

out = imgry.point(table, '1')

上面引用到的二值函數(shù)的定義如下:

1234567891011121314? ?def?get_bin_table(threshold=140):????"""????獲取灰度轉(zhuǎn)二值的映射table????:param threshold:????:return:????"""????table?=?[]????for?i?in?range(256):????????if?i threshold:????????????table.append(0)????????else:????????????table.append(1)?????return?table? ?

由PIL轉(zhuǎn)化后變成二值圖片:0表示黑色,1表示白色。二值化后帶噪點(diǎn)的?6937?的像素點(diǎn)輸出后如下圖:

1111000111111000111111100001111100000011

1110111011110111011111011110111100110111

1001110011110111101011011010101101110111

1101111111110110101111110101111111101111

1101000111110111001111110011111111101111

1100111011111000001111111001011111011111

1101110001111111101011010110111111011111

1101111011111111101111011110111111011111

1101111011110111001111011110111111011100

1110000111111000011101100001110111011111

如果你是近視眼,然后離屏幕遠(yuǎn)一點(diǎn),可以隱約看到?6937?的骨架了。

8.2???去除噪點(diǎn)

在轉(zhuǎn)化為二值圖片后,就需要清除噪點(diǎn)。本文選擇的素材比較簡單,大部分噪點(diǎn)也是最簡單的那種?孤立點(diǎn),所以可以通過檢測這些孤立點(diǎn)就能移除大量的噪點(diǎn)。

關(guān)于如何去除更復(fù)雜的噪點(diǎn)甚至干擾線和色塊,有比較成熟的算法:?洪水填充法 Flood Fill?,后面有興趣的時(shí)間可以繼續(xù)研究一下。

本文為了問題簡單化,干脆就用一種簡單的自己想的?簡單辦法?來解決掉這個(gè)問題:

對(duì)某個(gè)?黑點(diǎn)?周邊的九宮格里面的黑色點(diǎn)計(jì)數(shù)

如果黑色點(diǎn)少于2個(gè)則證明此點(diǎn)為孤立點(diǎn),然后得到所有的孤立點(diǎn)

對(duì)所有孤立點(diǎn)一次批量移除。

下面將詳細(xì)介紹關(guān)于具體的算法原理。

將所有的像素點(diǎn)如下圖分成三大類

頂點(diǎn)A

非頂點(diǎn)的邊界點(diǎn)B

內(nèi)部點(diǎn)C

種類點(diǎn)示意圖如下:

其中:

A類點(diǎn)計(jì)算周邊相鄰的3個(gè)點(diǎn)(如上圖紅框所示)

B類點(diǎn)計(jì)算周邊相鄰的5個(gè)點(diǎn)(如上圖紅框所示)

C類點(diǎn)計(jì)算周邊相鄰的8個(gè)點(diǎn)(如上圖紅框所示)

當(dāng)然,由于基準(zhǔn)點(diǎn)在計(jì)算區(qū)域的方向不同,A類點(diǎn)和B類點(diǎn)還會(huì)有細(xì)分:

A類點(diǎn)繼續(xù)細(xì)分為:左上,左下,右上,右下

B類點(diǎn)繼續(xù)細(xì)分為:上,下,左,右

C類點(diǎn)不用細(xì)分

然后這些細(xì)分點(diǎn)將成為后續(xù)坐標(biāo)獲取的準(zhǔn)則。

主要算法的python實(shí)現(xiàn)如下:

def sum_9_region(img, x, y): ? ?"""

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

:param x:

:param y:

:return: ? ?"""

# todo 判斷圖片的長寬度下限

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

width = img.width

height = img.height ? ?if cur_pixel == 1: ?# 如果當(dāng)前點(diǎn)為白色區(qū)域,則不統(tǒng)計(jì)鄰域值

?return 0 ? ?if y == 0: ?# 第一行

?if x == 0: ?# 左上頂點(diǎn),4鄰域

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

? ? ?sum = cur_pixel \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x, y + 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x + 1, y)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x + 1, y + 1)) ? ? ? ? ? ?return 4 - sum ? ? ? ?elif x == width - 1: ?# 右上頂點(diǎn)

? ? ?sum = cur_pixel \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x, y + 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x - 1, y)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x - 1, y + 1)) ? ? ? ? ? ?return 4 - sum ? ? ? ?else: ?# 最上非頂點(diǎn),6鄰域

? ? ?sum = img.getpixel((x - 1, y)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x - 1, y + 1)) \ ? ? ? ? ? ? ? ? ?+ cur_pixel \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x, y + 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x + 1, y)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x + 1, y + 1)) ? ? ? ? ? ?return 6 - sum ? ?elif y == height - 1: ?# 最下面一行

?if x == 0: ?# 左下頂點(diǎn)

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

? ? ?sum = cur_pixel \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x + 1, y)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x + 1, y - 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x, y - 1)) ? ? ? ? ? ?return 4 - sum ? ? ? ?elif x == width - 1: ?# 右下頂點(diǎn)

? ? ?sum = cur_pixel \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x, y - 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x - 1, y)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x - 1, y - 1)) ? ? ? ? ? ?return 4 - sum ? ? ? ?else: ?# 最下非頂點(diǎn),6鄰域

? ? ?sum = cur_pixel \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x - 1, y)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x + 1, y)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x, y - 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x - 1, y - 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x + 1, y - 1)) ? ? ? ? ? ?return 6 - sum ? ?else: ?# y不在邊界

?if x == 0: ?# 左邊非頂點(diǎn)

? ? ?sum = img.getpixel((x, y - 1)) \ ? ? ? ? ? ? ? ? ?+ cur_pixel \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x, y + 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x + 1, y - 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x + 1, y)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x + 1, y + 1)) ? ? ? ? ? ?return 6 - sum ? ? ? ?elif x == width - 1: ?# 右邊非頂點(diǎn)

? ? ?# print('%s,%s' % (x, y))

? ? ?sum = img.getpixel((x, y - 1)) \ ? ? ? ? ? ? ? ? ?+ cur_pixel \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x, y + 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x - 1, y - 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x - 1, y)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x - 1, y + 1)) ? ? ? ? ? ?return 6 - sum ? ? ? ?else: ?# 具備9領(lǐng)域條件的

? ? ?sum = img.getpixel((x - 1, y - 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x - 1, y)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x - 1, y + 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x, y - 1)) \ ? ? ? ? ? ? ? ? ?+ cur_pixel \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x, y + 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x + 1, y - 1)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x + 1, y)) \ ? ? ? ? ? ? ? ? ?+ img.getpixel((x + 1, y + 1)) ? ? ? ? ? ?return 9 - sum

Tips:這個(gè)地方是相當(dāng)考驗(yàn)人的細(xì)心和耐心程度了,這個(gè)地方的工作量還是蠻大的,花了半個(gè)晚上的時(shí)間才完成的。

計(jì)算好每個(gè)像素點(diǎn)的周邊像素黑點(diǎn)(注意:PIL轉(zhuǎn)化的圖片黑點(diǎn)的值為0)個(gè)數(shù)后,只需要篩選出個(gè)數(shù)為?1或者2?的點(diǎn)的坐標(biāo)即為?孤立點(diǎn)?。這個(gè)判斷方法可能不太準(zhǔn)確,但是基本上能夠滿足本文的需求了。

經(jīng)過預(yù)處理后的圖片如下所示:

對(duì)比文章開頭的原始圖片,那些?孤立點(diǎn)?都被移除掉,相對(duì)比較?干凈?的驗(yàn)證碼圖片已經(jīng)生成。

9???圖片字符切割

由于字符型?驗(yàn)證碼圖片?本質(zhì)就可以看著是由一系列的?單個(gè)字符圖片?拼接而成,為了簡化研究對(duì)象,我們也可以將這些圖片分解到?原子級(jí)?,即:?只包含單個(gè)字符的圖片。

于是,我們的研究對(duì)象由?“N種字串的組合對(duì)象”?變成?“10種阿拉伯?dāng)?shù)字”?的處理,極大的簡化和減少了處理對(duì)象。

9.1???分割算法

現(xiàn)實(shí)生活中的字符驗(yàn)證碼的產(chǎn)生千奇百怪,有各種扭曲和變形。關(guān)于字符分割的算法,也沒有很通用的方式。這個(gè)算法也是需要開發(fā)人員仔細(xì)研究所要識(shí)別的字符圖片的特點(diǎn)來制定的。

當(dāng)然,本文所選的研究對(duì)象盡量簡化了這個(gè)步驟的難度,下文將慢慢進(jìn)行介紹。

使用圖像編輯軟件(PhoneShop或者其它)打開驗(yàn)證碼圖片,放大到像素級(jí)別,觀察其它一些參數(shù)特點(diǎn):

可以得到如下參數(shù):

整個(gè)圖片尺寸是 40*10

單個(gè)字符尺寸是 6*10

左右字符和左右邊緣相距2個(gè)像素

字符上下緊挨邊緣(即相距0個(gè)像素)

這樣就可以很容易就定位到每個(gè)字符在整個(gè)圖片中占據(jù)的像素區(qū)域,然后就可以進(jìn)行分割了,具體代碼如下:

def get_crop_imgs(img): ? ?"""

按照?qǐng)D片的特點(diǎn),進(jìn)行切割,這個(gè)要根據(jù)具體的驗(yàn)證碼來進(jìn)行工作. # 見原理圖

:param img:

:return: ? ?"""

child_img_list = [] ? ?for i in range(4):

?x = 2 + i * (6 + 4) ?# 見原理圖

?y = 0

?child_img = img.crop((x, y, x + 6, y + 10))

?child_img_list.append(child_img) ? ?return child_img_list

然后就能得到被切割的?原子級(jí)?的圖片元素了:

9.2???內(nèi)容小結(jié)

基于本部分的內(nèi)容的討論,相信大家已經(jīng)了解到了,如果驗(yàn)證碼的干擾(扭曲,噪點(diǎn),干擾色塊,干擾線……)做得不夠強(qiáng)的話,可以得到如下兩個(gè)結(jié)論:

4位字符和40000位字符的驗(yàn)證碼區(qū)別不大

純字母

不區(qū)分大小寫。分類數(shù)為26

區(qū)分大小寫。分類數(shù)為52

純數(shù)字。分類數(shù)為10

數(shù)字和區(qū)分大小寫的字母組合。分類數(shù)為62

純數(shù)字?和?數(shù)字及字母組合?的驗(yàn)證碼區(qū)別不大

在沒有形成?指數(shù)級(jí)或者幾何級(jí)?的難度增加,而只是?線性有限級(jí)?增加計(jì)算量時(shí),意義不太大。

10???尺寸歸一

本文所選擇的研究對(duì)象本身尺寸就是統(tǒng)一狀態(tài):6*10的規(guī)格,所以此部分不需要額外處理。但是一些進(jìn)行了扭曲和縮放的驗(yàn)證碼,則此部分也會(huì)是一個(gè)圖像處理的難點(diǎn)。

11???模型訓(xùn)練步驟

在前面的環(huán)節(jié),已經(jīng)完成了對(duì)單個(gè)圖片的處理和分割了。后面就開始進(jìn)行?識(shí)別模型?的訓(xùn)練了。

整個(gè)訓(xùn)練過程如下:

大量完成預(yù)處理并切割到原子級(jí)的圖片素材準(zhǔn)備

對(duì)素材圖片進(jìn)行人為分類,即:打標(biāo)簽

定義單張圖片的識(shí)別特征

使用SVM訓(xùn)練模型對(duì)打了標(biāo)簽的特征文件進(jìn)行訓(xùn)練,得到模型文件

12???素材準(zhǔn)備

本文在訓(xùn)練階段重新下載了同一模式的4數(shù)字的驗(yàn)證圖片總計(jì):3000張。然后對(duì)這3000張圖片進(jìn)行處理和切割,得到12000張?jiān)蛹?jí)圖片。

在這12000張圖片中刪除一些會(huì)影響訓(xùn)練和識(shí)別的強(qiáng)干擾的干擾素材,切割后的效果圖如下:

13???素材標(biāo)記

由于本文使用的這種識(shí)別方法中,機(jī)器在最開始是不具備任何 數(shù)字的觀念的。所以需要人為的對(duì)素材進(jìn)行標(biāo)識(shí),告訴?機(jī)器什么樣的圖片的內(nèi)容是 1……。

這個(gè)過程叫做?“標(biāo)記”。

具體打標(biāo)簽的方法是:

為0~9每個(gè)數(shù)字建立一個(gè)目錄,目錄名稱為相應(yīng)數(shù)字(相當(dāng)于標(biāo)簽)

人為判定?圖片內(nèi)容,并將圖片拖到指定數(shù)字目錄中

每個(gè)目錄中存放100張左右的素材

一般情況下,標(biāo)記的素材越多,那么訓(xùn)練出的模型的分辨能力和預(yù)測能力越強(qiáng)。例如本文中,標(biāo)記素材為十多張的時(shí)候,對(duì)新的測試圖片識(shí)別率基本為零,但是到達(dá)100張時(shí),則可以達(dá)到近乎100%的識(shí)別率

14???特征選擇

對(duì)于切割后的單個(gè)字符圖片,像素級(jí)放大圖如下:

從宏觀上看,不同的數(shù)字圖片的本質(zhì)就是將黑色按照一定規(guī)則填充在相應(yīng)的像素點(diǎn)上,所以這些特征都是最后圍繞像素點(diǎn)進(jìn)行。

字符圖片?寬6個(gè)像素,高10個(gè)像素?,理論上可以最簡單粗暴地可以定義出60個(gè)特征:60個(gè)像素點(diǎn)上面的像素值。但是顯然這樣高維度必然會(huì)造成過大的計(jì)算量,可以適當(dāng)?shù)慕稻S。

通過查閱相應(yīng)的文獻(xiàn)?[2],給出另外一種簡單粗暴的特征定義:

每行上黑色像素的個(gè)數(shù),可以得到10個(gè)特征

每列上黑色像素的個(gè)數(shù),可以得到6個(gè)特征

最后得到16維的一組特征,實(shí)現(xiàn)代碼如下:

def get_feature(img): ? ?"""

獲取指定圖片的特征值,

1. 按照每排的像素點(diǎn),高度為10,則有10個(gè)維度,然后為6列,總共16個(gè)維度

:param img_path:

:return:一個(gè)維度為10(高度)的列表 ? ?"""

width, height = img.size

pixel_cnt_list = []

height = 10 ? ?for y in range(height):

?pix_cnt_x = 0 ? ? ? ?for x in range(width): ? ? ? ? ? ?if img.getpixel((x, y)) == 0: ?# 黑色點(diǎn)

? ? ? ? ?pix_cnt_x += 1

?pixel_cnt_list.append(pix_cnt_x) ? ?for x in range(width):

?pix_cnt_y = 0 ? ? ? ?for y in range(height): ? ? ? ? ? ?if img.getpixel((x, y)) == 0: ?# 黑色點(diǎn)

? ? ? ? ?pix_cnt_y += 1

?pixel_cnt_list.append(pix_cnt_y) ? ?return pixel_cnt_list

然后就將圖片素材特征化,按照?libSVM?指定的格式生成一組帶特征值和標(biāo)記值的向量文

Python 設(shè)計(jì)一個(gè)函數(shù)產(chǎn)生指定長度的驗(yàn)證碼 length = len(base_str) - 1 ,這里為什么會(huì)減 1????

random.randint()

取的數(shù)的區(qū)間是前后封閉的。也就是可能會(huì)取到last_pos

如果不減1那么就會(huì)出錯(cuò)的。

all_chars[len(all_chars)]就出錯(cuò)了。

本文名稱:Python驗(yàn)證碼函數(shù),python 驗(yàn)證碼
轉(zhuǎn)載源于:http://jinyejixie.com/article18/hchhgp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、外貿(mào)建站、網(wǎng)站維護(hù)定制網(wǎng)站、ChatGPT品牌網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司
海盐县| 信丰县| 五大连池市| 右玉县| 定西市| 阿克陶县| 敖汉旗| 侯马市| 澄城县| 崇义县| 陇川县| 西乌珠穆沁旗| 宁蒗| 图们市| 宁夏| 桃园市| 嘉兴市| 九龙坡区| 元氏县| 枣庄市| 全州县| 阆中市| 明溪县| 广德县| 上虞市| 准格尔旗| 玛纳斯县| 青河县| 大英县| 缙云县| 贵南县| 湖北省| 南汇区| 稻城县| 崇礼县| 会泽县| 扎赉特旗| 广东省| 沙田区| 铜陵市| 白玉县|