最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python用 KNN 進(jìn)行驗(yàn)證碼識(shí)別的實(shí)現(xiàn)方法

 更新時(shí)間:2018年02月06日 16:41:49   投稿:mrr  
這篇文章主要介紹了Python用 KNN 進(jìn)行驗(yàn)證碼識(shí)別的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下

前言

之前做了一個(gè)校園交友的APP,其中一個(gè)邏輯是通過(guò)用戶的教務(wù)系統(tǒng)來(lái)確認(rèn)用戶是一名在校大學(xué)生,基本的想法是通過(guò)用戶的賬號(hào)和密碼,用爬蟲的方法來(lái)確認(rèn)信息,但是許多教務(wù)系統(tǒng)都有驗(yàn)證碼,當(dāng)時(shí)是通過(guò)本地服務(wù)器去下載驗(yàn)證碼,然后分發(fā)給客戶端,然后讓用戶自己填寫驗(yàn)證碼,與賬號(hào)密碼一并提交給服務(wù)器,然后服務(wù)器再去模擬登錄教務(wù)系統(tǒng)以確認(rèn)用戶能否登錄該教務(wù)系統(tǒng)。驗(yàn)證碼無(wú)疑讓我們想使得用戶快速認(rèn)證的想法破滅了,但是當(dāng)時(shí)也沒(méi)辦法,最近看了一些機(jī)器學(xué)習(xí)的內(nèi)容,覺(jué)得對(duì)于大多數(shù)學(xué)校的那些極簡(jiǎn)單的驗(yàn)證碼應(yīng)該是可以用KNN這種方法來(lái)破解的,于是整理了一下思緒,擼起袖子做起來(lái)!

分析

我們學(xué)校的驗(yàn)證碼是這樣的:,其實(shí)就是簡(jiǎn)單地把字符進(jìn)行旋轉(zhuǎn)然后加上一些微弱的噪點(diǎn)形成的。我們要識(shí)別,就得逆行之,具體思路就是,首先二值化去掉噪點(diǎn),然后把單個(gè)字符分割出來(lái),最后旋轉(zhuǎn)至標(biāo)準(zhǔn)方向,然后從這些處理好的圖片中選出模板,最后每次新來(lái)一張驗(yàn)證碼就按相同方式處理,然后和這些模板進(jìn)行比較,選擇判別距離最近的一個(gè)模板作為其判斷結(jié)果(亦即KNN的思想,本文取K=1)。接下來(lái)按步驟進(jìn)行說(shuō)明。

獲得驗(yàn)證碼

首先得有大量的驗(yàn)證碼,我們通過(guò)爬蟲來(lái)實(shí)現(xiàn),代碼如下

#-*- coding:UTF-8 -*-
import urllib,urllib2,cookielib,string,Image
def getchk(number):
 #創(chuàng)建cookie對(duì)象
 cookie = cookielib.LWPCookieJar()
 cookieSupport= urllib2.HTTPCookieProcessor(cookie)
 opener = urllib2.build_opener(cookieSupport, urllib2.HTTPHandler)
 urllib2.install_opener(opener)
 #首次與教務(wù)系統(tǒng)鏈接獲得cookie#
 #偽裝browser
 headers = {
 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
 'Accept-Encoding':'gzip,deflate',
 'Accept-Language':'zh-CN,zh;q=0.8',
 'User-Agent':'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36'
 }
 req0 = urllib2.Request(
  url ='http://mis.teach.ustc.edu.cn',
  headers = headers  #請(qǐng)求頭
 )
 # 捕捉http錯(cuò)誤
 try :
 result0 = urllib2.urlopen(req0)
 except urllib2.HTTPError,e:
 print e.code
 #提取cookie
 getcookie = ['',]
 for item in cookie:
 getcookie.append(item.name)
 getcookie.append("=")
 getcookie.append(item.value)
 getcookie = "".join(getcookie)
 
 #修改headers
 headers["Origin"] = "http://mis.teach.ustc.edu.cn"
 headers["Referer"] = "http://mis.teach.ustc.edu.cn/userinit.do"
 headers["Content-Type"] = "application/x-www-form-urlencoded"
 headers["Cookie"] = getcookie
 for i in range(number):
 req = urllib2.Request(
  url ="http://mis.teach.ustc.edu.cn/randomImage.do?date='1469451446894'",
  headers = headers   #請(qǐng)求頭
 )
 response = urllib2.urlopen(req)
 status = response.getcode()
 picData = response.read()
 if status == 200:
  localPic = open("./source/"+str(i)+".jpg", "wb")
  localPic.write(picData)
  localPic.close()
 else:
  print "failed to get Check Code "
if __name__ == '__main__':
 getchk(500)

這里下載了500張驗(yàn)證碼到source目錄下面。如圖:

二值化

matlab豐富的圖像處理函數(shù)能給我們省下很多時(shí)間,,我們遍歷source文件夾,對(duì)每一張驗(yàn)證碼圖片進(jìn)行二值化處理,把處理過(guò)的圖片存入bw目錄下。代碼如下

mydir='./source/';
bw = './bw/';
if mydir(end)~='\'
 mydir=[mydir,'\'];
end
DIRS=dir([mydir,'*.jpg']); %擴(kuò)展名
n=length(DIRS);
for i=1:n
 if ~DIRS(i).isdir
 img = imread(strcat(mydir,DIRS(i).name ));
 img = rgb2gray(img);%灰度化
 img = im2bw(img);%0-1二值化
 name = strcat(bw,DIRS(i).name)
 imwrite(img,name);
 end
end

處理結(jié)果如圖:

分割

mydir='./bw/';
letter = './letter/';
if mydir(end)~='\'
 mydir=[mydir,'\'];
end
DIRS=dir([mydir,'*.jpg']); %擴(kuò)展名
n=length(DIRS);
for i=1:n
 if ~DIRS(i).isdir
 img = imread(strcat(mydir,DIRS(i).name ));
 img = im2bw(img);%二值化
 img = 1-img;%顏色反轉(zhuǎn)讓字符成為聯(lián)通域,方便去除噪點(diǎn)
 for ii = 0:3
  region = [ii*20+1,1,19,20];%把一張驗(yàn)證碼分成四個(gè)20*20大小的字符圖片
  subimg = imcrop(img,region);
  imlabel = bwlabel(subimg);
%  imshow(imlabel);
 
  if max(max(imlabel))>1 % 說(shuō)明有噪點(diǎn),要去除
%   max(max(imlabel))
 
%   imshow(subimg);
 
  stats = regionprops(imlabel,'Area');
  area = cat(1,stats.Area);
  maxindex = find(area == max(area));
  area(maxindex) = 0;  
  secondindex = find(area == max(area)); 
  imindex = ismember(imlabel,secondindex);
  subimg(imindex==1)=0;%去掉第二大連通域,噪點(diǎn)不可能比字符大,所以第二大的就是噪點(diǎn)
  end
  name = strcat(letter,DIRS(i).name(1:length(DIRS(i).name)-4),'_',num2str(ii),'.jpg')
  imwrite(subimg,name);
 end
 end
end

處理結(jié)果如圖:

旋轉(zhuǎn)

接下來(lái)進(jìn)行旋轉(zhuǎn),哪找一個(gè)什么標(biāo)準(zhǔn)呢?據(jù)觀察,這些字符旋轉(zhuǎn)不超過(guò)60度,那么在正負(fù)60度之間,統(tǒng)一旋轉(zhuǎn)至字符寬度最小就行了。代碼如下

if mydir(end)~='\'
 mydir=[mydir,'\'];
end
DIRS=dir([mydir,'*.jpg']); %擴(kuò)展名
n=length(DIRS);
for i=1:n
 if ~DIRS(i).isdir
 img = imread(strcat(mydir,DIRS(i).name ));
 img = im2bw(img);
 minwidth = 20;
 for angle = -60:60
  imgr=imrotate(img,angle,'bilinear','crop');%crop 避免圖像大小變化
  imlabel = bwlabel(imgr);
  stats = regionprops(imlabel,'Area');
  area = cat(1,stats.Area);
  maxindex = find(area == max(area));
  imindex = ismember(imlabel,maxindex);%最大連通域?yàn)?
  [y,x] = find(imindex==1);
  width = max(x)-min(x)+1;
  if width<minwidth
  minwidth = width;
  imgrr = imgr;
  end
 end
 name = strcat(rotate,DIRS(i).name)
 imwrite(imgrr,name);
 end
end

處理結(jié)果如圖,一共2000個(gè)字符的圖片存在rotate文件夾中

模板選取

現(xiàn)在從rotate文件夾中選取一套模板,涵蓋每一個(gè)字符,一個(gè)字符可以選取多個(gè)圖片,因?yàn)榧词褂星懊娴闹T多處理也不能保證一個(gè)字符的最終呈現(xiàn)形式只有一種,多選幾個(gè)才能保證覆蓋率。把選出來(lái)的模板圖片存入samples文件夾下,這個(gè)過(guò)程很耗時(shí)耗力。可以找同學(xué)幫忙~,如圖

測(cè)試

測(cè)試代碼如下:首先對(duì)測(cè)試驗(yàn)證碼進(jìn)行上述操作,然后和選出來(lái)的模板進(jìn)行比較,采用差分值最小的模板作為測(cè)試樣本的字符選擇,代碼如下

% 具有差分最小值的圖作為答案 

mydir='./test/';
samples = './samples/';
if mydir(end)~='\'
 mydir=[mydir,'\'];
end
if samples(end)~='\'
 samples=[samples,'\'];
end
DIRS=dir([mydir,'*.jpg']); %擴(kuò)展?
DIRS1=dir([samples,'*.jpg']); %擴(kuò)展名
n=length(DIRS);%驗(yàn)證碼總圖數(shù)
singleerror = 0;%單個(gè)錯(cuò)誤
uniterror = 0;%一張驗(yàn)證碼錯(cuò)誤個(gè)數(shù)
for i=1:n
 if ~DIRS(i).isdir
 realcodes = DIRS(i).name(1:4);
 fprintf('驗(yàn)證碼實(shí)際字符:%s\n',realcodes);
 img = imread(strcat(mydir,DIRS(i).name ));
 img = rgb2gray(img);
 img = im2bw(img);
 img = 1-img;%顏色反轉(zhuǎn)讓字符成為聯(lián)通域
 subimgs = [];
 for ii = 0:3
  region = [ii*20+1,1,19,20];%奇怪,為什么這樣才能均分?
  subimg = imcrop(img,region);
  imlabel = bwlabel(subimg);
  if max(max(imlabel))>1 % 說(shuō)明有雜點(diǎn)
  stats = regionprops(imlabel,'Area');
  area = cat(1,stats.Area);
  maxindex = find(area == max(area));
  area(maxindex) = 0;  
  secondindex = find(area == max(area)); 
  imindex = ismember(imlabel,secondindex);
  subimg(imindex==1)=0;%去掉第二大連通域
  end
  subimgs = [subimgs;subimg];
 end
 codes = [];
 for ii = 0:3
  region = [ii*20+1,1,19,20];
  subimg = imcrop(img,region);
  minwidth = 20;
  for angle = -60:60
  imgr=imrotate(subimg,angle,'bilinear','crop');%crop 避免圖像大小變化
  imlabel = bwlabel(imgr);
  stats = regionprops(imlabel,'Area');
  area = cat(1,stats.Area);
  maxindex = find(area == max(area));
  imindex = ismember(imlabel,maxindex);%最大連通域?yàn)?
  [y,x] = find(imindex==1);
  width = max(x)-min(x)+1;
  if width<minwidth
   minwidth = width;
   imgrr = imgr;
  end
  end
  mindiffv = 1000000;
  for jj = 1:length(DIRS1)
  imgsample = imread(strcat(samples,DIRS1(jj).name ));
  imgsample = im2bw(imgsample);
  diffv = abs(imgsample-imgrr);
  alldiffv = sum(sum(diffv));
  if alldiffv<mindiffv
   mindiffv = alldiffv;
   code = DIRS1(jj).name;
   code = code(1);
  end
  end
  codes = [codes,code];
 end
 fprintf('驗(yàn)證碼測(cè)試字符:%s\n',codes);
 num = codes-realcodes;
 num = length(find(num~=0));
 singleerror = singleerror + num;
 if num>0
  uniterror = uniterror +1;
 end
 fprintf('錯(cuò)誤個(gè)數(shù):%d\n',num);
 end
end
fprintf('\n-----結(jié)果統(tǒng)計(jì)如下-----\n\n');
fprintf('測(cè)試驗(yàn)證碼的字符數(shù)量:%d\n',n*4);
fprintf('測(cè)試驗(yàn)證碼的字符錯(cuò)誤數(shù)量:%d\n',singleerror);
fprintf('單個(gè)字符識(shí)別正確率:%.2f%%\n',(1-singleerror/(n*4))*100);
fprintf('測(cè)試驗(yàn)證碼圖的數(shù)量:%d\n',n);
fprintf('測(cè)試驗(yàn)證碼圖的錯(cuò)誤數(shù)量:%d\n',uniterror);
fprintf('填對(duì)驗(yàn)證碼的概率:%.2f%%\n',(1-uniterror/n)*100);

結(jié)果:

驗(yàn)證碼實(shí)際字符:2B4E
驗(yàn)證碼測(cè)試字符:2B4F
錯(cuò)誤個(gè)數(shù):1
驗(yàn)證碼實(shí)際字符:4572
驗(yàn)證碼測(cè)試字符:4572
錯(cuò)誤個(gè)數(shù):0
驗(yàn)證碼實(shí)際字符:52CY
驗(yàn)證碼測(cè)試字符:52LY
錯(cuò)誤個(gè)數(shù):1
驗(yàn)證碼實(shí)際字符:83QG
驗(yàn)證碼測(cè)試字符:85QG
錯(cuò)誤個(gè)數(shù):1
驗(yàn)證碼實(shí)際字符:9992
驗(yàn)證碼測(cè)試字符:9992
錯(cuò)誤個(gè)數(shù):0
驗(yàn)證碼實(shí)際字符:A7Y7
驗(yàn)證碼測(cè)試字符:A7Y7
錯(cuò)誤個(gè)數(shù):0
驗(yàn)證碼實(shí)際字符:D993
驗(yàn)證碼測(cè)試字符:D995
錯(cuò)誤個(gè)數(shù):1
驗(yàn)證碼實(shí)際字符:F549
驗(yàn)證碼測(cè)試字符:F5A9
錯(cuò)誤個(gè)數(shù):1
驗(yàn)證碼實(shí)際字符:FMC6
驗(yàn)證碼測(cè)試字符:FMLF
錯(cuò)誤個(gè)數(shù):2
驗(yàn)證碼實(shí)際字符:R4N4
驗(yàn)證碼測(cè)試字符:R4N4
錯(cuò)誤個(gè)數(shù):0 

-----結(jié)果統(tǒng)計(jì)如下----- 

測(cè)試驗(yàn)證碼的字符數(shù)量:40
測(cè)試驗(yàn)證碼的字符錯(cuò)誤數(shù)量:7
單個(gè)字符識(shí)別正確率:82.50%
測(cè)試驗(yàn)證碼圖的數(shù)量:10
測(cè)試驗(yàn)證碼圖的錯(cuò)誤數(shù)量:6
填對(duì)驗(yàn)證碼的概率:40.00%

可見單個(gè)字符準(zhǔn)確率是比較高的的了,但是綜合準(zhǔn)確率還是不行,觀察結(jié)果至,錯(cuò)誤的字符就是那些易混淆字符,比如E和F,C和L,5和3,4和A等,所以我們能做的事就是增加模板中的樣本數(shù)量,以期盡量減少混淆。

增加了幾十個(gè)樣本過(guò)后再次試驗(yàn),結(jié)果:

驗(yàn)證碼實(shí)際字符:2B4E
驗(yàn)證碼測(cè)試字符:2B4F
錯(cuò)誤個(gè)數(shù):1
驗(yàn)證碼實(shí)際字符:4572
驗(yàn)證碼測(cè)試字符:4572
錯(cuò)誤個(gè)數(shù):0
驗(yàn)證碼實(shí)際字符:52CY
驗(yàn)證碼測(cè)試字符:52LY
錯(cuò)誤個(gè)數(shù):1
驗(yàn)證碼實(shí)際字符:83QG
驗(yàn)證碼測(cè)試字符:83QG
錯(cuò)誤個(gè)數(shù):0
驗(yàn)證碼實(shí)際字符:9992
驗(yàn)證碼測(cè)試字符:9992
錯(cuò)誤個(gè)數(shù):0
驗(yàn)證碼實(shí)際字符:A7Y7
驗(yàn)證碼測(cè)試字符:A7Y7
錯(cuò)誤個(gè)數(shù):0
驗(yàn)證碼實(shí)際字符:D993
驗(yàn)證碼測(cè)試字符:D993
錯(cuò)誤個(gè)數(shù):0
驗(yàn)證碼實(shí)際字符:F549
驗(yàn)證碼測(cè)試字符:F5A9
錯(cuò)誤個(gè)數(shù):1
驗(yàn)證碼實(shí)際字符:FMC6
驗(yàn)證碼測(cè)試字符:FMLF
錯(cuò)誤個(gè)數(shù):2
驗(yàn)證碼實(shí)際字符:R4N4
驗(yàn)證碼測(cè)試字符:R4N4
錯(cuò)誤個(gè)數(shù):0 

-----結(jié)果統(tǒng)計(jì)如下----- 

測(cè)試驗(yàn)證碼的字符數(shù)量:40
測(cè)試驗(yàn)證碼的字符錯(cuò)誤數(shù)量:5
單個(gè)字符識(shí)別正確率:87.50%
測(cè)試驗(yàn)證碼圖的數(shù)量:10
測(cè)試驗(yàn)證碼圖的錯(cuò)誤數(shù)量:4
填對(duì)驗(yàn)證碼的概率:60.00%

可見無(wú)論是單個(gè)字符識(shí)別正確率還是整個(gè)驗(yàn)證碼正確的概率都有了提升。能夠預(yù)見:隨著模板數(shù)量的增多,正確率會(huì)不斷地提高。

總結(jié)

這種方法的可擴(kuò)展性很弱,而且只適用于簡(jiǎn)單的驗(yàn)證碼,12306那種根本就別提了。

相關(guān)文章

  • Python實(shí)現(xiàn)自動(dòng)化網(wǎng)頁(yè)操作步驟

    Python實(shí)現(xiàn)自動(dòng)化網(wǎng)頁(yè)操作步驟

    這篇文章主要介紹Python如何實(shí)現(xiàn)自動(dòng)化網(wǎng)頁(yè)操作,文中有詳細(xì)的流程步驟和代碼示例,對(duì)我們的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-06-06
  • Python+pytorch實(shí)現(xiàn)天氣識(shí)別

    Python+pytorch實(shí)現(xiàn)天氣識(shí)別

    這篇文章主要為大家詳細(xì)介紹了如何利用Python+pytorch實(shí)現(xiàn)天氣識(shí)別功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下
    2022-10-10
  • 關(guān)于tensorflow的幾種參數(shù)初始化方法小結(jié)

    關(guān)于tensorflow的幾種參數(shù)初始化方法小結(jié)

    今天小編就為大家分享一篇關(guān)于tensorflow的幾種參數(shù)初始化方法小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-01-01
  • Python操作MySQL的方法詳細(xì)解讀

    Python操作MySQL的方法詳細(xì)解讀

    這篇文章主要介紹了Python操作MySQL的方法詳細(xì)解讀,在Python中,通過(guò)使用第三方庫(kù):pymysql,完成對(duì)MySQL數(shù)據(jù)庫(kù)的操作,Python操作MySQL并不難,難點(diǎn)是如何編寫合適的SQL語(yǔ)句,需要的朋友可以參考下
    2023-11-11
  • Python操作lxml庫(kù)之基礎(chǔ)使用篇

    Python操作lxml庫(kù)之基礎(chǔ)使用篇

    lxml庫(kù)是python的第三方庫(kù),安裝方式也是十分簡(jiǎn)單,下面這篇文章主要給大家介紹了關(guān)于Python操作lxml庫(kù)之基礎(chǔ)使用篇的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • 基于python實(shí)現(xiàn)FTP文件上傳與下載操作(ftp&sftp協(xié)議)

    基于python實(shí)現(xiàn)FTP文件上傳與下載操作(ftp&sftp協(xié)議)

    這篇文章主要介紹了基于python實(shí)現(xiàn)FTP文件上傳與下載操作(ftp&sftp協(xié)議),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Python圖像處理利Pillow庫(kù)使用實(shí)戰(zhàn)指南

    Python圖像處理利Pillow庫(kù)使用實(shí)戰(zhàn)指南

    Pillow庫(kù)是Python編程中用于圖像處理的重要工具,作為Python?Imaging?Library(PIL)的一個(gè)分支,Pillow庫(kù)提供了豐富的功能和易用的API,用于處理圖像的各種操作
    2023-12-12
  • pydantic?resolve解決嵌套數(shù)據(jù)結(jié)構(gòu)生成痛點(diǎn)分析

    pydantic?resolve解決嵌套數(shù)據(jù)結(jié)構(gòu)生成痛點(diǎn)分析

    這篇文章主要為大家介紹了pydantic?resolve解決嵌套數(shù)據(jù)結(jié)構(gòu)生成痛點(diǎn)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • 使用python爬蟲實(shí)現(xiàn)抓取動(dòng)態(tài)加載數(shù)據(jù)

    使用python爬蟲實(shí)現(xiàn)抓取動(dòng)態(tài)加載數(shù)據(jù)

    這篇文章主要給大家介紹了如何用python爬蟲抓取豆瓣電影“分類排行榜”中的電影數(shù)據(jù),比如輸入“犯罪”則會(huì)輸出所有犯罪影片的電影名稱、評(píng)分,文中通過(guò)代碼示例和圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • Django框架視圖層URL映射與反向解析實(shí)例分析

    Django框架視圖層URL映射與反向解析實(shí)例分析

    這篇文章主要介紹了Django框架視圖層URL映射與反向解析,結(jié)合實(shí)例形式分析了Django框架普通url映射、命名URL參數(shù)映射、分布式URL映射、反向解析等相關(guān)操作技巧,需要的朋友可以參考下
    2019-07-07

最新評(píng)論

北票市| 婺源县| 夏津县| 赤水市| 平遥县| 静宁县| 汾西县| 甘洛县| 宁海县| 元江| 黎川县| 郴州市| 大田县| 墨玉县| 德江县| 托克逊县| 夹江县| 宁河县| 水富县| 峡江县| 商城县| 灵台县| 禄丰县| 江安县| 滦南县| 麟游县| 阿图什市| 苏州市| 东阿县| 双辽市| 涟源市| 遂溪县| 特克斯县| 都兰县| 阿勒泰市| 黄平县| 屏东市| 巴林左旗| 庆元县| 杭州市| 印江|