python驗證碼去噪
㈠ python抓取網頁時是如何處理驗證碼的
python抓取網頁時是如何處理驗證碼的?下面給大家介紹幾種方法:
1、輸入式驗證碼
這種驗證碼主要是通過用戶輸入圖片中的字母、數字、漢字等進行驗證。如下圖:
解決思路:這種是最簡單的一種,只要識別出裡面的內容,然後填入到輸入框中即可。這種識別技術叫OCR,這里我們推薦使用Python的第三方庫,tesserocr。對於沒有什麼背影影響的驗證碼如圖2,直接通過這個庫來識別就可以。但是對於有嘈雜的背景的驗證碼這種,直接識別識別率會很低,遇到這種我們就得需要先處理一下圖片,先對圖片進行灰度化,然後再進行二值化,再去識別,這樣識別率會大大提高。
相關推薦:《Python入門教程》
2、滑動式驗證碼
這種是將備選碎片直線滑動到正確的位置,如下圖:
解決思路:對於這種驗證碼就比較復雜一點,但也是有相應的辦法。我們直接想到的就是模擬人去拖動驗證碼的行為,點擊按鈕,然後看到了缺口的位置,最後把拼圖拖到缺口位置處完成驗證。
第一步:點擊按鈕。然後我們發現,在你沒有點擊按鈕的時候那個缺口和拼圖是沒有出現的,點擊後才出現,這為我們找到缺口的位置提供了靈感。
第二步:拖到缺口位置。
我們知道拼圖應該拖到缺口處,但是這個距離如果用數值來表示?
通過我們第一步觀察到的現象,我們可以找到缺口的位置。這里我們可以比較兩張圖的像素,設置一個基準值,如果某個位置的差值超過了基準值,那我們就找到了這兩張圖片不一樣的位置,當然我們是從那塊拼圖的右側開始並且從左到右,找到第一個不一樣的位置時就結束,這是的位置應該是缺口的left,所以我們使用selenium拖到這個位置即可。
這里還有個疑問就是如何能自動的保存這兩張圖?
這里我們可以先找到這個標簽,然後獲取它的location和size,然後 top,bottom,left,right = location['y'] ,location['y']+size['height']+ location['x'] + size['width'] ,然後截圖,最後摳圖填入這四個位置就行。
具體的使用可以查看selenium文檔,點擊按鈕前摳張圖,點擊後再摳張圖。最後拖動的時候要需要模擬人的行為,先加速然後減速。因為這種驗證碼有行為特徵檢測,人是不可能做到一直勻速的,否則它就判定為是機器在拖動,這樣就無法通過驗證了。
3、點擊式的圖文驗證和圖標選擇
圖文驗證:通過文字提醒用戶點擊圖中相同字的位置進行驗證。
圖標選擇: 給出一組圖片,按要求點擊其中一張或者多張。借用萬物識別的難度阻擋機器。
這兩種原理相似,只不過是一個是給出文字,點擊圖片中的文字,一個是給出圖片,點出內容相同的圖片。
這兩種沒有特別好的方法,只能藉助第三方識別介面來識別出相同的內容,推薦一個超級鷹,把驗證碼發過去,會返回相應的點擊坐標。
然後再使用selenium模擬點擊即可。具體怎麼獲取圖片和上面方法一樣。
4、宮格驗證碼
這種就很棘手,每一次出現的都不一樣,但是也會出現一樣的。而且拖動順序都不一樣。
但是我們發現不一樣的驗證碼個數是有限的,這里採用模版匹配的方法。我覺得就好像暴力枚舉,把所有出現的驗證碼保存下來,然後挑出不一樣的驗證碼,按照拖動順序命名,我們從左到右上下到下,設為1,2,3,4。上圖的滑動順序為4,3,2,1,所以我們命名4_3_2_1.png,這里得手動搞。當驗證碼出現的時候,用我們保存的圖片一一枚舉,與出現這種比較像素,方法見上面。如果匹配上了,拖動順序就為4,3,2,1。然後使用selenium模擬即可。
㈡ python pil 怎麼去掉驗證碼線條
一、驗證碼識別的概念
機器識別圖片主要的三個步驟為消去背景、切割字元、識別字元。而現有的字元驗證碼也針對這三個方面來設計強壯的驗證碼。
以下簡圖幫助大家理解驗證碼識別的流程:
二、處理流程
其中最為關鍵的就是好圖像處理這一步了。圖像處理功能模塊包括圖像的灰度化、二值化、離散雜訊點的去除、傾斜度校正、字元的切割、圖像的歸一化等圖像處理技術 。
1、 圖像的灰度化
由於 256 色的點陣圖的調色板內容比較復雜,使得圖像處理的許多演算法都沒有辦法展開,因此有必要對它進行灰度處理。所謂灰度圖像就是圖像的每一個像素的 R、G、B 分量的值是相等的。彩色圖像的每個像素的 R、G、B 值是不相同的,所以顯示出紅綠藍等各種顏色。灰度圖像沒有這些顏色差異,有的只是亮度上的不同。灰度值大的像素點比較亮(像素值最大為 255,為白色),反之比較暗(像素值最小為 0,為黑色)。圖像灰度化有各種不同的演算法,比較直接的一種就是給像素的 RGB 值各自一個加權系數,然後求和;同時還要對調色板表項進行相應的處理。
2、 圖像的二值化
要注意的是,最後得到的結果一定要歸一到 0-255 之內。因為這是每個位元組表示
圖像數據的極限。
3、 去噪
圖像可能在生成、傳輸或者採集過程中夾帶了雜訊,去雜訊是圖像處理中常用的手法。通常去雜訊用濾波的方法,比如中值濾波、均值濾波。但是那樣的演算法不適合用在處理字元這樣目標狹長的圖像中,因為在濾波的過程中很有可能會去掉字元本身的像素。
一個採用的是去除雜點的方法來進行去雜訊處理的。具體演算法如下:掃描整個圖像,當發現一個黑色點的時候,就考察和該黑色點間接或者直接相連接的黑色點的個數有多少,如果大於一定的值,那就說明該點不是離散點,否則就是離散點,把它去掉。在考察相連的黑色點的時候用的是遞歸的方法。此處,我簡單的用python實現了,大家可以參考以下。
#coding=utf-8"""
creat time:2015.09.14
"""import cv2import numpy as npfrom matplotlib import pyplot as pltfrom PIL import Image,ImageEnhance,ImageFilter
img_name = '2+.png'#去除干擾線im = Image.open(img_name)#圖像二值化enhancer = ImageEnhance.Contrast(im)
im = enhancer.enhance(2)
im = im.convert('1')
data = im.getdata()
w,h = im.size#im.show()black_point = 0for x in xrange(1,w-1): for y in xrange(1,h-1):
mid_pixel = data[w*y+x] #中央像素點像素值
if mid_pixel == 0: #找出上下左右四個方向像素點像素值
top_pixel = data[w*(y-1)+x]
left_pixel = data[w*y+(x-1)]
down_pixel = data[w*(y+1)+x]
right_pixel = data[w*y+(x+1)] #判斷上下左右的黑色像素點總個數
if top_pixel == 0:
black_point += 1
if left_pixel == 0:
black_point += 1
if down_pixel == 0:
black_point += 1
if right_pixel == 0:
black_point += 1
if black_point >= 3:
im.putpixel((x,y),0) #print black_point
black_point = 0im.show()041424344
原驗證碼:
4、分割
圖像中一般會含有多個數字,識別的時候只能根據每個字元的特徵來進行判斷,所以還要進行字元切割的工作。這一步工作就是把圖像中的字元獨立的切割出來。
具體的演算法如下:
第一步,先自下而上對圖像進行逐行掃描直至遇到第一個黑色的像素點。記錄下來。然後再自上而下對圖像進行逐行掃描直至找到第一個黑色像素,這樣就找到圖像大致的高度范圍。
第二步,在這個高度范圍之內再自左向右逐列進行掃描,遇到第一個黑色像素時認為是字元切割的起始位置,然後繼續掃描,直至遇到有一列中沒有黑色像素,則認為這個字元切割結束,然後繼續掃描,按照上述的方法一直掃描直至圖像的最右端。這樣就得到了每個字元的比較精確寬度范圍。
第三步,在已知的每個字元比較精確的寬度范圍內,按照第一步的方法,分別進行自上而下和自下而上的逐行掃描來獲取每個字元精確的高度范圍。
5、 圖像的歸一化
因為採集的圖像中字元大小有可能存在較大的差異,或者是經過切割後的字元尺寸不統一,而相對來說,統一尺寸的字元識別的標准性更強,准確率自然也更高,歸一化圖像就是要把原來各不相同的字元統一到同一尺寸,在系統實現中是統一到同一高度,然後根據高度來調整字元的寬度。具體演算法如下:先得到原來字元的高度,跟系統要求的高度做比較,得出要變換的系數,然後根據得到的系數求得變換後應有得寬度。在得到寬度和高度之後,把新圖像裡面的點按照插值的方法映射到原圖像中。
不少人認為把每個字元圖像歸一化為 5×9 像素的二值圖像是最理想的,因為圖像的尺寸越小,識別速度就越高,網路訓練也越快。而實際上,相對於要識別的字元圖像, 5×9 像素圖太小了。歸一化後,圖像信息丟失了很多,這時進行圖像識別,准確率不高。實驗證明,將字元圖像歸一化為 10×18 像素的二值圖像是現實中是比較理想的,達到了識別速度快和識別准確率高的較好的平衡點。
三、識別
圖像識別包括特徵提取、樣本訓練和識別三大塊內容。
驗證碼識別其中最為關鍵的就是去噪和分割,這對你的訓練和識別的精度都有著很大的影響。這里只講了大致的流程,其中每個細節都有很多工作要做,這里碼字也很難講清楚,大家可以以這個流程為主線,一步步的實現,最終也就能完成你的需求。
㈢ 驗證碼識別之模板匹配方法
在寫爬蟲的時候難免會遇到驗證碼識別的問題,常見的驗證碼識別的流程為:
- 圖像灰度化
- 圖像去噪(如圖像二值化)
- 切割圖片
- 提取特徵
- 訓練
但這種方法要切割圖片,而且破解驗證碼的重點和難點就在於 能否成功分割字元 。
本文要介紹的演算法 不需要進行圖片切割,也不需要進行機器訓練 ,這種方法就是模板匹配:將待識別的文字切割成一個個模板,在待識別的圖像中去匹配模板。
這篇文章將分為兩個部分:
第一部分介紹模板匹配的基本概念以及模板匹配的一種實現演算法:快速歸一化互相關匹配演算法;
第二部分是一個具體實例。
模板匹配是在圖像中尋找目標的方法之一,目的就是在一幅圖像中尋找和模板圖像最相似的區域。
模板匹配的大致過程是這樣的:通過在輸入圖像上滑動圖像塊對實際的圖像塊和輸入圖像進行匹配。
假設我們有一張100x100的輸入圖像,有一張10x10的模板圖像,查找的過程是這樣的:
從輸入圖像的左上角(0,0)開始,切割一塊(0,0)至(10,10)的臨時圖像;
用某種方法得出臨時圖像與模板的相似度c,存放到相似度矩陣中(矩陣大小為91 x91);
切割輸入圖像從(0,1)至(10,11)的臨時圖像,對比,並記錄到相似度矩陣;
重復上述步驟,直到輸入圖像的右下角。
最終得到一個相似度矩陣,找到矩陣中的最大或最小值,最大值(最小值)對應的臨時圖像即為與模板最相似的圖像。
在步驟b中,求模板與圖像的相似度有多種方法,如平均絕對差演算法(MAD)、絕對誤差和演算法(SAD)、誤差平方和演算法(SSD)、歸一化互相關演算法(NCC),本文使用的是歸一化互相關演算法。
什麼是歸一化互相關?
從幾何圖形上來看,空間中的兩個向量,同方向平行時,歸一化互相關系數為1,表示兩個向量最相似,反方向平行時歸一化互相關系數為-1,垂直時為0,表示最不相似(用互相垂直的三個向量來代表整個空間也是這個道理,垂直的向量之間不包含對方的信息,相關系數為0),存在一定夾角時處於(-1,1),是不是跟餘弦函數很像,cos(0)=1,cos(pi/2)=0,cos(pi)=-1。就是這個樣子的,相關系數可以看作是兩個向量之間夾角的cosine函數。
在數學中是這么計算cosine函數的,假設兩個n維向量X,Y,對應的坐標分別為(x1,x2,…xn), (y1,y2,…yn) 則:
(如果想要了解更多,請參考文獻【2】)
但這是一維的,在模板匹配中要再加一個維度 (具體演算法請參考文獻【3】) ,簡要說一下文獻【3】的內容:如果直接計算二維相似度的話計算復雜度會非常高,文獻【3】利用快速傅里葉變換與積分圖像快速演算法來降低計算復雜度。
接下來讓我們看一個具體的應用。
模板匹配識別驗證碼的具體步驟為:
1. 找出圖片中所有可能出現的字元,製作成模板集合
2. 圖像灰度化
3. 圖片去噪(二值化)
4. 模板匹配
5. 匹配結果優化
要識別的圖片如下,以識別圖片中的加字為例:
要從image中找到與模板最匹配的部分,Template圖像是事先從image圖像中截取的一部分。所用的為python模塊skimage中的match_template方法,match_template方法使用的是快速歸一化互相關演算法 【2】 。
遍歷模板圖像集合,與圖像匹配,如果dist大於閾值h,則認為此模板在圖像中存在,否則不存在,繼續匹配下一個模板,直到遍歷完所有模板。
以模板『加』為例,圖像大小為40x260,模板大小27x27,result是一個大小為(14,234)的矩陣,即上文提到的相似度矩陣,矩陣中的數值屬於[-1,1],找到result中最大值所處的對應位置即為與模板最匹配的圖像位置:x=66,y=11,正好對應模板圖像在image中所處的位置。 (更多內容請參閱參考文獻【4】)
但這是比較好的情況,因為在匹配時遍歷了所有的模板,而一張圖片中出現的模板數量是有限的,比如數字』四』在圖片中是沒有的,這時就要根據某種規則去掉這些在圖片中沒有出現的模板:程序中使用dist變數來過濾匹配結果,如果dist變數大於某個值則認為此模板在圖像中不存在。
最後的result_list中可能仍然存在一些圖片中不存在的模板或者匹配不精確的模板,比如數字『一』在模板中不存在,但仍然可以匹配到,因為數字『二』中可以匹配到『一』,需要進一步優化,優化方法有很多,比如當匹配到的兩個模板距離過近時,選擇較大的那個模板,其餘方法留給讀者自行考慮吧。
後續將會推出如何使用深度學習識別驗證碼,敬請期待~
參考文獻:
http://www.cnblogs.com/beer/p/5672678.html
http://www.ruanyifeng.com/blog/2013/03/cosine_similarity.html
J. P. Lewis, 「Fast Normalized Cross-Correlation」, Instrial Light and Magic.
http://scikit-image.org/docsjinhqin/dev/auto_examples/plot_template.html
本文作者 :李暉(點融黑幫),畢業於電子科技大學,現就職於點融成都Data部門,對一切新鮮事物充滿好奇,對跳舞毫無抵抗力的活力女青年一枚。
㈣ 如何用python svd降噪
from recsys.algorithm.factorize import SVD
svd = SVD()
svd.load_data(dataset)
svd.compute(k=100, mean_center=True)
ITEMID1 = 1 # Toy Story
svd.similar(ITEMID1)
# Returns:
# [(1, 1.0), # Toy Story
# (3114, 0.87060391051018071), # Toy Story 2
# (2355, 0.67706936677315799), # A bug's life
# (588, 0.5807351496754426), # Aladdin
# (595, 0.46031829709743477), # Beauty and the Beast
# (1907, 0.44589398718134365), # Mulan
# (364, 0.42908159895574161), # The Lion King
# (2081, 0.42566581277820803), # The Little Mermaid
# (3396, 0.42474056361935913), # The Muppet Movie
# (2761, 0.40439361857585354)] # The Iron Giant
ITEMID2 = 2355 # A bug's life
svd.similarity(ITEMID1, ITEMID2)
# 0.67706936677315799
㈤ 如何利用Python做簡單的驗證碼識別
1摘要
驗證碼是目前互聯網上非常常見也是非常重要的一個事物,充當著很多系統的防火牆功能,但是隨時OCR技術的發展,驗證碼暴露出來的安全問題也越來越嚴峻。本文介紹了一套字元驗證碼識別的完整流程,對於驗證碼安全和OCR識別技術都有一定的借鑒意義。
然後經過了一年的時間,筆者又研究和get到了一種更強大的基於CNN卷積神經網路的直接端到端的驗證識別技術(文章不是我的,然後我把源碼整理了下,介紹和源碼在這裡面):
基於python語言的tensorflow的『端到端』的字元型驗證碼識別源碼整理(github源碼分享)
2關鍵詞
關鍵詞:安全,字元圖片,驗證碼識別,OCR,Python,SVM,PIL
3免責聲明
本文研究所用素材來自於某舊Web框架的網站完全對外公開的公共圖片資源。
本文只做了該網站對外公開的公共圖片資源進行了爬取,並未越權做任何多餘操作。
本文在書寫相關報告的時候已經隱去漏洞網站的身份信息。
本文作者已經通知網站相關人員此系統漏洞,並積極向新系統轉移。
本報告的主要目的也僅是用於OCR交流學習和引起大家對驗證安全的警覺。
4引言
關於驗證碼的非技術部分的介紹,可以參考以前寫的一篇科普類的文章:
互聯網安全防火牆(1)--網路驗證碼的科普
裡面對驗證碼的種類,使用場景,作用,主要的識別技術等等進行了講解,然而並沒有涉及到任何技術內容。本章內容則作為它的技術補充來給出相應的識別的解決方案,讓讀者對驗證碼的功能及安全性問題有更深刻的認識。
5基本工具
要達到本文的目的,只需要簡單的編程知識即可,因為現在的機器學習領域的蓬勃發展,已經有很多封裝好的開源解決方案來進行機器學習。普通程序員已經不需要了解復雜的數學原理,即可以實現對這些工具的應用了。
主要開發環境:
python3.5
python SDK版本
PIL
圖片處理庫
libsvm
開源的svm機器學習庫
准備原始圖片素材
圖片預處理
圖片字元切割
圖片尺寸歸一化
圖片字元標記
字元圖片特徵提取
生成特徵和標記對應的訓練數據集
訓練特徵標記數據生成識別模型
使用識別模型預測新的未知圖片集
達到根據「圖片」就能返回識別正確的字元集的目標
- def get_feature(img): """
- 獲取指定圖片的特徵值,
- 1. 按照每排的像素點,高度為10,則有10個維度,然後為6列,總共16個維度
- :param img_path:
- :return:一個維度為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: # 黑色點
- 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: # 黑色點
- pix_cnt_y += 1
- pixel_cnt_list.append(pix_cnt_y) return pixel_cnt_list
關於環境的安裝,不是本文的重點,故略去。
6基本流程
一般情況下,對於字元型驗證碼的識別流程如下:
7素材准備
7.1素材選擇
由於本文是以初級的學習研究目的為主,要求「有代表性,但又不會太難」,所以就直接在網上找個比較有代表性的簡單的字元型驗證碼(感覺像在找漏洞一樣)。
最後在一個比較舊的網站(估計是幾十年前的網站框架)找到了這個驗證碼圖片。
原始圖:
然後就將圖片素材特徵化,按照libSVM指定的格式生成一組帶特徵值和標記值的向量文
㈥ 怎樣用python實現圖像去噪
#coding:utf-8
importsys,os
fromPILimportImage,ImageDraw
#二值數組
t2val={}
deftwoValue(image,G):
foryinxrange(0,image.size[1]):
forxinxrange(0,image.size[0]):
g=image.getpixel((x,y))
ifg>G:
t2val[(x,y)]=1
else:
t2val[(x,y)]=0
#降噪
#根據一個點A的RGB值,與周圍的8個點的RBG值比較,設定一個值N(0<N<8),當A的RGB值與周圍8個點的RGB相等數小於N時,此點為噪點
#G:Integer圖像二值化閥值
#N:Integer降噪率0<N<8
#Z:Integer降噪次數
#輸出
#0:降噪成功
#1:降噪失敗
defclearNoise(image,N,Z):
foriinxrange(0,Z):
t2val[(0,0)]=1
t2val[(image.size[0]-1,image.size[1]-1)]=1
forxinxrange(1,image.size[0]-1):
foryinxrange(1,image.size[1]-1):
nearDots=0
L=t2val[(x,y)]
ifL==t2val[(x-1,y-1)]:
nearDots+=1
ifL==t2val[(x-1,y)]:
nearDots+=1
ifL==t2val[(x-1,y+1)]:
nearDots+=1
ifL==t2val[(x,y-1)]:
nearDots+=1
ifL==t2val[(x,y+1)]:
nearDots+=1
ifL==t2val[(x+1,y-1)]:
nearDots+=1
ifL==t2val[(x+1,y)]:
nearDots+=1
ifL==t2val[(x+1,y+1)]:
nearDots+=1
ifnearDots<N:
t2val[(x,y)]=1
defsaveImage(filename,size):
image=Image.new("1",size)
draw=ImageDraw.Draw(image)
forxinxrange(0,size[0]):
foryinxrange(0,size[1]):
draw.point((x,y),t2val[(x,y)])
image.save(filename)
image=Image.open("d:/1.jpg").convert("L")
twoValue(image,100)
clearNoise(image,4,1)
saveImage("d:/5.jpg",image.size)