欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Python用 KNN 進行驗證碼識別的實現方法

系統 2144 0

前言

之前做了一個校園交友的APP,其中一個邏輯是通過用戶的教務系統來確認用戶是一名在校大學生,基本的想法是通過用戶的賬號和密碼,用爬蟲的方法來確認信息,但是許多教務系統都有驗證碼,當時是通過本地服務器去下載驗證碼,然后分發給客戶端,然后讓用戶自己填寫驗證碼,與賬號密碼一并提交給服務器,然后服務器再去模擬登錄教務系統以確認用戶能否登錄該教務系統。驗證碼無疑讓我們想使得用戶快速認證的想法破滅了,但是當時也沒辦法,最近看了一些機器學習的內容,覺得對于大多數學校的那些極簡單的驗證碼應該是可以用KNN這種方法來破解的,于是整理了一下思緒,擼起袖子做起來!

分析

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

獲得驗證碼

首先得有大量的驗證碼,我們通過爬蟲來實現,代碼如下

            
#-*- coding:UTF-8 -*-
import urllib,urllib2,cookielib,string,Image
def getchk(number):
 #創建cookie對象
 cookie = cookielib.LWPCookieJar()
 cookieSupport= urllib2.HTTPCookieProcessor(cookie)
 opener = urllib2.build_opener(cookieSupport, urllib2.HTTPHandler)
 urllib2.install_opener(opener)
 #首次與教務系統鏈接獲得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  #請求頭
 )
 # 捕捉http錯誤
 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   #請求頭
 )
 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張驗證碼到source目錄下面。如圖:

Python用 KNN 進行驗證碼識別的實現方法_第1張圖片

二值化

matlab豐富的圖像處理函數能給我們省下很多時間,,我們遍歷source文件夾,對每一張驗證碼圖片進行二值化處理,把處理過的圖片存入bw目錄下。代碼如下

            
mydir='./source/';
bw = './bw/';
if mydir(end)~='\'
 mydir=[mydir,'\'];
end
DIRS=dir([mydir,'*.jpg']); %擴展名
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
          

處理結果如圖:

Python用 KNN 進行驗證碼識別的實現方法_第2張圖片

分割

            
mydir='./bw/';
letter = './letter/';
if mydir(end)~='\'
 mydir=[mydir,'\'];
end
DIRS=dir([mydir,'*.jpg']); %擴展名
n=length(DIRS);
for i=1:n
 if ~DIRS(i).isdir
 img = imread(strcat(mydir,DIRS(i).name ));
 img = im2bw(img);%二值化
 img = 1-img;%顏色反轉讓字符成為聯通域,方便去除噪點
 for ii = 0:3
  region = [ii*20+1,1,19,20];%把一張驗證碼分成四個20*20大小的字符圖片
  subimg = imcrop(img,region);
  imlabel = bwlabel(subimg);
%  imshow(imlabel);
 
  if max(max(imlabel))>1 % 說明有噪點,要去除
%   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;%去掉第二大連通域,噪點不可能比字符大,所以第二大的就是噪點
  end
  name = strcat(letter,DIRS(i).name(1:length(DIRS(i).name)-4),'_',num2str(ii),'.jpg')
  imwrite(subimg,name);
 end
 end
end
          

處理結果如圖:

Python用 KNN 進行驗證碼識別的實現方法_第3張圖片

旋轉

接下來進行旋轉,哪找一個什么標準呢?據觀察,這些字符旋轉不超過60度,那么在正負60度之間,統一旋轉至字符寬度最小就行了。代碼如下

            
if mydir(end)~='\'
 mydir=[mydir,'\'];
end
DIRS=dir([mydir,'*.jpg']); %擴展名
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);%最大連通域為1
  [y,x] = find(imindex==1);
  width = max(x)-min(x)+1;
  if width
            
            
          

處理結果如圖,一共2000個字符的圖片存在rotate文件夾中

Python用 KNN 進行驗證碼識別的實現方法_第4張圖片

模板選取

現在從rotate文件夾中選取一套模板,涵蓋每一個字符,一個字符可以選取多個圖片,因為即使有前面的諸多處理也不能保證一個字符的最終呈現形式只有一種,多選幾個才能保證覆蓋率。把選出來的模板圖片存入samples文件夾下,這個過程很耗時耗力??梢哉彝瑢W幫忙~,如圖

Python用 KNN 進行驗證碼識別的實現方法_第5張圖片

測試

測試代碼如下:首先對測試驗證碼進行上述操作,然后和選出來的模板進行比較,采用差分值最小的模板作為測試樣本的字符選擇,代碼如下

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

            
mydir='./test/';
samples = './samples/';
if mydir(end)~='\'
 mydir=[mydir,'\'];
end
if samples(end)~='\'
 samples=[samples,'\'];
end
DIRS=dir([mydir,'*.jpg']); %擴展?
DIRS1=dir([samples,'*.jpg']); %擴展名
n=length(DIRS);%驗證碼總圖數
singleerror = 0;%單個錯誤
uniterror = 0;%一張驗證碼錯誤個數
for i=1:n
 if ~DIRS(i).isdir
 realcodes = DIRS(i).name(1:4);
 fprintf('驗證碼實際字符:%s\n',realcodes);
 img = imread(strcat(mydir,DIRS(i).name ));
 img = rgb2gray(img);
 img = im2bw(img);
 img = 1-img;%顏色反轉讓字符成為聯通域
 subimgs = [];
 for ii = 0:3
  region = [ii*20+1,1,19,20];%奇怪,為什么這樣才能均分?
  subimg = imcrop(img,region);
  imlabel = bwlabel(subimg);
  if max(max(imlabel))>1 % 說明有雜點
  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);%最大連通域為1
  [y,x] = find(imindex==1);
  width = max(x)-min(x)+1;
  if width
            
              0
  uniterror = uniterror +1;
 end
 fprintf('錯誤個數:%d\n',num);
 end
end
fprintf('\n-----結果統計如下-----\n\n');
fprintf('測試驗證碼的字符數量:%d\n',n*4);
fprintf('測試驗證碼的字符錯誤數量:%d\n',singleerror);
fprintf('單個字符識別正確率:%.2f%%\n',(1-singleerror/(n*4))*100);
fprintf('測試驗證碼圖的數量:%d\n',n);
fprintf('測試驗證碼圖的錯誤數量:%d\n',uniterror);
fprintf('填對驗證碼的概率:%.2f%%\n',(1-uniterror/n)*100);
            
          

結果:

驗證碼實際字符:2B4E
驗證碼測試字符:2B4F
錯誤個數:1
驗證碼實際字符:4572
驗證碼測試字符:4572
錯誤個數:0
驗證碼實際字符:52CY
驗證碼測試字符:52LY
錯誤個數:1
驗證碼實際字符:83QG
驗證碼測試字符:85QG
錯誤個數:1
驗證碼實際字符:9992
驗證碼測試字符:9992
錯誤個數:0
驗證碼實際字符:A7Y7
驗證碼測試字符:A7Y7
錯誤個數:0
驗證碼實際字符:D993
驗證碼測試字符:D995
錯誤個數:1
驗證碼實際字符:F549
驗證碼測試字符:F5A9
錯誤個數:1
驗證碼實際字符:FMC6
驗證碼測試字符:FMLF
錯誤個數:2
驗證碼實際字符:R4N4
驗證碼測試字符:R4N4
錯誤個數:0?

-----結果統計如下-----?

測試驗證碼的字符數量:40
測試驗證碼的字符錯誤數量:7
單個字符識別正確率:82.50%
測試驗證碼圖的數量:10
測試驗證碼圖的錯誤數量:6
填對驗證碼的概率:40.00%

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

增加了幾十個樣本過后再次試驗,結果:

驗證碼實際字符:2B4E
驗證碼測試字符:2B4F
錯誤個數:1
驗證碼實際字符:4572
驗證碼測試字符:4572
錯誤個數:0
驗證碼實際字符:52CY
驗證碼測試字符:52LY
錯誤個數:1
驗證碼實際字符:83QG
驗證碼測試字符:83QG
錯誤個數:0
驗證碼實際字符:9992
驗證碼測試字符:9992
錯誤個數:0
驗證碼實際字符:A7Y7
驗證碼測試字符:A7Y7
錯誤個數:0
驗證碼實際字符:D993
驗證碼測試字符:D993
錯誤個數:0
驗證碼實際字符:F549
驗證碼測試字符:F5A9
錯誤個數:1
驗證碼實際字符:FMC6
驗證碼測試字符:FMLF
錯誤個數:2
驗證碼實際字符:R4N4
驗證碼測試字符:R4N4
錯誤個數:0?

-----結果統計如下-----?

測試驗證碼的字符數量:40
測試驗證碼的字符錯誤數量:5
單個字符識別正確率:87.50%
測試驗證碼圖的數量:10
測試驗證碼圖的錯誤數量:4
填對驗證碼的概率:60.00%

可見無論是單個字符識別正確率還是整個驗證碼正確的概率都有了提升。能夠預見:隨著模板數量的增多,正確率會不斷地提高。

總結

這種方法的可擴展性很弱,而且只適用于簡單的驗證碼,12306那種根本就別提了。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美午夜免费观看福利片 | 亚洲一区二区色情苍井空 | 色悠久久久久综合网伊人男男 | 免费观看黄色a一级视频播放 | 天天干夜夜噜 | 久久久久中文字幕 | 欧美日韩高清不卡免费观看 | 欧美高清69hd | 国产精品国产精品国产专区不卡 | 欧美日韩一区二区三区四区五区 | 亚洲午夜精品A片久久WWW软件 | 亚洲第一区视频在线观看 | 成人欧美一区二区三区在线播放 | 黄工厂精品视频在线观看 | 国产一区二区在线免费观看 | 欧美二级毛片免费高清电影 | 亚洲国产系列 | 激情网站免费观看 | 激情中文网 | 日本亚洲国产精品久久 | 在线国产视频 | 夜本色| 97热久久| 亚洲综合色站 | 亚洲性人人天天夜夜摸 | 精品热久久 | 国产成人免费高清激情明星 | 国产午夜精品AV一区二区 | 波多野结衣免费视频观看 | 欧美日一区二区三区 | 鲁在线视频| 99影视在线视频免费观看 | 日本a级大片 | 91tm视频| 久久免费精品视频在线观看 | 国产成人精品免费影视大全 | 国产成人综合在线观看网站 | 奇米视频在线观看 | 日韩一二区| 欧美国产日韩在线观看 | 亚洲偷 |