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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

网页验证码识别实例VB.NET2019(二)

發(fā)布時間:2023/12/20 asp.net 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网页验证码识别实例VB.NET2019(二) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

??上一節(jié),獲取了網(wǎng)頁驗(yàn)證碼。這一節(jié)開始講講怎么識別驗(yàn)證碼。

??2、獲取36個字符的特征碼

??2.1 分析驗(yàn)證碼特征

驗(yàn)證碼圖片:

??經(jīng)研究,發(fā)現(xiàn)該網(wǎng)頁驗(yàn)證碼的圖片中字符是由數(shù)字和大寫字母組成,每張驗(yàn)證碼4個字符。其中由于數(shù)字0、1和和字母O和I比較接近,所以這四個字符沒有出現(xiàn),再加上和2比較像的字母Z一共有5個字符沒有,所以出現(xiàn)的字符只有35個。
??驗(yàn)證碼字符沒有變形,大小一致。背景有噪點(diǎn),大小不一。

??2.3驗(yàn)證碼字符特征碼必須的流程:

圖片灰度化圖片二值化圖片分割圖片特征碼提取

圖片特征碼提取參考louislong007兄弟的博文做了修改(https://blog.csdn.net/louislong007/article/details/47683035)

??2.4 圖片灰度化


??圖片灰度化就是利用特定算法,將彩色圖片中的每一個像素點(diǎn)R、G、B三個顏色分量轉(zhuǎn)換為相同的色值(0-255)。
?? 根據(jù)YUV的顏色空間中,Y的分量的物理意義是點(diǎn)的亮度,由該值反映亮度等級,根據(jù)RGB和YUV顏色空間的變化關(guān)系可建立亮度Y與R、G、B三個顏色分量的對應(yīng):Y=0.3R+0.59G+0.11B,以這個亮度值表達(dá)圖像的灰度值。

''' <summary>''' 函數(shù)功能:灰度化bitmap圖像''' </summary>''' <param name="bmp">bitmap對象</param>''' <returns>返回灰度化的bitmap對象</returns>Public Function ConvertToGrayImage(ByVal bmp As Bitmap) As BitmapDim bm As Bitmap = New Bitmap(bmp.Width, bmp.Height)Dim i As IntegerDim j As IntegerFor i = 0 To bmp.Width - 1For j = 0 To bmp.Height - 1Dim color As Color = bmp.GetPixel(i, j) '獲取該點(diǎn)的像素的RGB的顏色'利用公式計(jì)算灰度值'根據(jù)YUV的顏色空間中,Y的分量的物理意義是點(diǎn)的亮度,由該值反映亮度等級,'根據(jù)RGB和YUV顏色空間的變化關(guān)系可建立亮度Y與R、G、B三個顏色分量的對應(yīng):'Y=0.3R+0.59G+0.11B,以這個亮度值表達(dá)圖像的灰度值Dim gray As Integer = Int(color.R * 0.3 + color.G * 0.59 + color.B * 0.11)Dim newcolor As Color = Color.FromArgb(gray, gray, gray)bm.SetPixel(i, j, newcolor)NextNextReturn bmbm.Dispose()End Function

??2.5 圖片二值化


??所謂二值化,就是將灰度化的圖片轉(zhuǎn)變?yōu)橹挥袃煞N顏色的圖片,即黑色(0,0,0)和白色(255,255,255)。取圖片的平均灰度值,遍歷圖片中每一個像素點(diǎn),大于該值設(shè)為白色,小于該值設(shè)為黑色。
??二值化代碼:

''' <summary>''' 二值化已灰度化的bmp圖像。''' </summary>''' <param name="bmp">已灰度化的位圖</param>''' <returns>二值化后的bimmap對象</returns>Public Function ConvertToBinaryImage(ByVal bmp As Bitmap) As Bitmap '。'圖像二值化:取圖片的平均灰度作為閾值, 低于該值的全都為0, 高于該值的全都為255' 在進(jìn)行了灰度化處理之后,圖像中的每個象素只有一個值,那就是象素的灰度值。它的大小決定了象素的亮暗程度。' 為了更加便利的開展下面的圖像處理操作,還需要對已經(jīng)得到的灰度圖像做一個二值化處理。' 圖像的二值化就是把圖像中的象素根據(jù)一定的標(biāo)準(zhǔn)分化成兩種顏色。在系統(tǒng)中是根據(jù)象素的灰度值處理成黑白兩種顏色。'和灰度化相似的, 圖像的二值化也有很多成熟的算法。它可以采用自適應(yīng)閥值法,也可以采用給定閥值法。Dim bm As Bitmap = New Bitmap(bmp.Width, bmp.Height)Dim average As Integer = 0For i = 0 To bmp.Width - 1For j = 0 To bmp.Height - 1Dim color As Color = bmp.GetPixel(i, j) '獲取該點(diǎn)的像素的RGB的顏色average += color.B '獲取該點(diǎn)像素的灰度值并累加NextNextaverage = Int(average / (bmp.Width * bmp.Height))'圖片平均灰度值For i = 0 To bmp.Width - 1For j = 0 To bmp.Height - 1Dim color As Color = bmp.GetPixel(i, j) '獲取該點(diǎn)的像素的RGB的顏色Dim value As Integer = 255 - averageDim newcolor As ColorIf color.B > average Then'大于平均灰度值,則設(shè)為白點(diǎn)(255,255,255)newcolor = Color.FromArgb(255, 255, 255)Else'小于平均灰度值,則設(shè)為黑點(diǎn)(0,0,0)newcolor = Color.FromArgb(0, 0, 0)End Ifbm.SetPixel(i, j, newcolor)NextNextReturn bmbm.Dispose()End Function

??2.6 圖片去噪

先看看去噪效果圖片:

??2.6.1 噪點(diǎn)的判定

??這里由于我處理的網(wǎng)頁驗(yàn)證碼比較簡單,只涉及到噪點(diǎn)的去除,沒有涉及到干擾線的去除。所以下面所講的只涉及到噪點(diǎn)的去除,對干擾線的去除方法網(wǎng)上有很多,有需要的可以自己去百度。
??我們怎么去判定噪點(diǎn)和字符呢?也就是噪點(diǎn)和字符的區(qū)別。
??從前面經(jīng)過二值化處理可知,如果一個pixel是驗(yàn)證碼或者干擾因素的一部分,那么這個pixel在二值化結(jié)果中其灰度值一定是0,即黑色;如果一個pixel是背景,則其灰度值應(yīng)該是255是白色。因此對于孤立的噪點(diǎn),其周圍應(yīng)該都是白色,或者大多數(shù)點(diǎn)都是白色pixel。

??2.6.2 去除噪點(diǎn)的方法及原理

??噪點(diǎn)去除的方法比較多,這里介紹比較簡單的兩種方法:8鄰域去噪和連通域去噪。

??2.6.2.1 8鄰域去噪

??原理:對一個噪點(diǎn)來講,其周圍的pixel應(yīng)該全是白色的背景才對,準(zhǔn)確來講就是一個噪點(diǎn)pixel是黑色的并且外包的8個相鄰pixel全是白色。當(dāng)然,如果圖片分辨率夠高,一個噪點(diǎn)實(shí)際上可能是有很多個pixel組成,所以此時的判斷條件應(yīng)該放寬,即一個pixel是黑色的并且相鄰的8個pixel白色的大于一個固定值,那么這個pixel就是噪點(diǎn)。對于不同的驗(yàn)證碼,這個閥值是不固定的,所以在這可以設(shè)置大小,多試幾次,找到最佳的閥值。
??我們看看效果:

??去噪強(qiáng)度是指噪點(diǎn)判斷標(biāo)準(zhǔn),例如,去噪強(qiáng)度為3,表示如果黑點(diǎn)周圍8鄰域中黑點(diǎn)的個數(shù)為3個或者3個以下,則判定此黑點(diǎn)為噪點(diǎn),將其顏色設(shè)為白色(即背景色)。
??隨著去噪強(qiáng)度的增加,噪點(diǎn)去除了,但是字符也被部分去除了,經(jīng)對比,去噪強(qiáng)度為4效果較好。即便這樣,字符部分仍有部分損失。
以下為8鄰域去噪代碼:

Public Function RemoveNoise8Neighbours(ByVal bmp As Bitmap, ByVal number As Integer) As Bitmap 'number為去噪強(qiáng)度'8鄰域降噪法,適合單個噪點(diǎn)和小噪點(diǎn)'這種方法類似均值濾波,不過對于每個pixel,' 不是取其周圍像素的灰度平均值,'而是統(tǒng)計(jì)其周圍像素點(diǎn)的灰度值為0或255的個數(shù)。'從前面經(jīng)過二值化處理可知,'如果一個pixel是驗(yàn)證碼或者干擾因素的一部分,'那么這個pixel在二值化結(jié)果中其灰度值一定是0, 即黑色;'如果一個pixel是背景, 則其灰度值應(yīng)該是255是白色。'因此對于孤立的噪點(diǎn), 其周圍應(yīng)該都是白色'所以對一個噪點(diǎn)來講,其周圍的pixel應(yīng)該全是白色的背景才對,'準(zhǔn)確來講就是一個噪點(diǎn)pixel是黑色的并且外包的8個相鄰pixel全是白色。'當(dāng)然, 如果圖片分辨率夠高, 一個噪點(diǎn)實(shí)際上可能是有很多個pixel組成, '所以此時的判斷條件應(yīng)該放寬, '即一個pixel是黑色的并且相鄰的8個pixel黑色的小于等于一個固定值, '那么這個pixel就是噪點(diǎn)。對于不同的驗(yàn)證碼, 這個閥值是不固定的,'所以在這可以設(shè)置大小, 多試幾次, 找到最佳的閥值。'經(jīng)過測試, 8領(lǐng)域降噪法對于小的噪點(diǎn)的去除是很有效的, 而且計(jì)算量不大Dim bm As Bitmap = New Bitmap(bmp.Width, bmp.Height)'把圖像的四邊像素點(diǎn)變成白色,即(255,255,255)Dim white As Color = Color.FromArgb(255, 255, 255)For i = 0 To bmp.Width - 1 '上下邊取白色bmp.SetPixel(i, 0, white)bmp.SetPixel(i, bmp.Height - 1, white)NextFor j = 0 To bmp.Height - 1 '左右邊取白色bmp.SetPixel(0, j, white)bmp.SetPixel(bmp.Width - 1, j, white)Next'某點(diǎn)的相鄰點(diǎn)為白色,而此點(diǎn)為黑色,刪除黑點(diǎn)For i = 0 To bmp.Width - 1For j = 0 To bmp.Height - 1Dim color As Color = bmp.GetPixel(i, j) '獲取該點(diǎn)的像素的RGB的顏色Dim count As Integer = 0If color.B = 0 Then '發(fā)現(xiàn)黑點(diǎn)(0,0,0)For m = i - 1 To i + 1For n = j - 1 To j + 1Dim colorneighbour As Color = bmp.GetPixel(m, n)If colorneighbour.B = 0 Then '在某黑點(diǎn)的相鄰8點(diǎn)中發(fā)現(xiàn)黑點(diǎn)count += 1End IfNextNextEnd IfIf count <= number Thenbm.SetPixel(i, j, white) ' 如果黑點(diǎn)周圍的黑點(diǎn)不超過number,則把黑點(diǎn)變成白點(diǎn)Elsebm.SetPixel(i, j, color)End IfNextNextReturn bmEnd Function
??2.6.2.2 連通域去噪

??原理:字符是由很多個黑色像素點(diǎn)組成的一大片連通域,而噪點(diǎn)是黑色像素點(diǎn)組成的一小片連通域。連通域去噪就是將小面積(即黑色像素點(diǎn)的個數(shù))的連通域去掉(背景色化),保留面積較大的連通域(字符區(qū)域)。
看看效果:

??通過以上,字符面積在50到100之間。也就是說,連通域面積小于50的都可以認(rèn)定為噪點(diǎn),可以去除。其實(shí),這個例子中,噪點(diǎn)面積最大也沒有超過10。
??從效果對比來看,連通域去噪字符部分沒有損失,而8鄰域去噪,字符部分會有損失,可能會影響驗(yàn)證碼的識別。所以這里我選擇了連通域去噪方法去噪。
連通域去噪代碼:

'' <summary>''' 二值化圖片的連通域去噪,前景顏色為(0,0,0),背景顏色為(255,255,255)。函數(shù)返回去噪后的bitmap對象。''' 此函數(shù)采用自定義漫水填充法(mxdFloodFill,利用種子填充原理)。''' </summary>''' <param name="bmp">二值化bitmap對象</param>''' <param name="area">連通域面積(像素點(diǎn)個數(shù))此參數(shù)可選,默認(rèn)為0,不去噪</param>''' <returns></returns>Public Function RemoveNoiseConnectedRegion(ByVal bmp As Bitmap, Optional ByVal area As Integer = 0) As Bitmap '二值化圖片連通域去噪Dim bm As Bitmap = bmpDim Cr As IntegerCr = 1If area <> 0 ThenFor x = 0 To bm.Width - 1For y = 0 To bm.Height - 1If bmp.GetPixel(x, y) = Color.FromArgb(000) Then '發(fā)現(xiàn)黑點(diǎn)Dim p As Pointp.X = xp.Y = ymxdFloodFill(bm, p, Color.FromArgb(Cr, Cr, Cr)) 'FloodFill each point in connect area using different colorCr += 1End IfNextNextDim ColorCount(255) As Integer 'caculate the area of each area For x = 0 To bm.Width - 1For y = 0 To bm.Height - 1If bm.GetPixel(x, y) <> Color.FromArgb(255, 255, 255) ThenColorCount(bm.GetPixel(x, y).B) += 1End IfNextNext'get rid of noise domain(<= area)For x = 0 To bm.Width - 1For y = 0 To bm.Height - 1If ColorCount(bm.GetPixel(x, y).B) <= area Thenbm.SetPixel(x, y, Color.FromArgb(255, 255, 255)) '如果這種顏色的domain小于閾值,則將其設(shè)為白色,即背景色,除掉。Elsebm.SetPixel(x, y, Color.FromArgb(0, 0, 0)) '否則認(rèn)為它是字符區(qū)域的點(diǎn),設(shè)為黑色。End IfNextNextEnd IfReturn bmEnd Function

自定義泛水填充函數(shù)代碼,詳細(xì)內(nèi)容可參考我的博客《 vb.net 自定義的FloodFill函數(shù)(泛水填充)》

Public Function mxdFloodFill(ByVal bm As Bitmap, ByVal SeedPoint As Point, ByVal Cr As Color) As Boolean 'seed-fill,4-neighbours,以種子點(diǎn)顏色相同的連通區(qū)域進(jìn)行填充。' a、將B(x,y)作為種子(像素位置),并賦予其一個label,然后將該種子相鄰的所有前景像素都壓入棧中;' b、彈出棧頂像素,賦予其相同的label,然后再將與該棧頂像素相鄰的所有前景像素都壓入棧中;' c、重復(fù)b步驟,直到棧為空;' 此時, 便找到了圖像B中的一個連通區(qū)域, 該區(qū)域內(nèi)的像素值被標(biāo)記為label;Dim newColor As Color = CrDim seedColor As Color = bm.GetPixel(SeedPoint.X, SeedPoint.Y)Dim StackSeed As New StackDim FourNeighbours As List(Of Point)If SeedPoint.X > bm.Width - 1 Or SeedPoint.Y > bm.Height - 1 ThenReturn FalseExit FunctionEnd IfStackSeed.Push(SeedPoint)Do While StackSeed.Count <> 0Dim PopSeed As Point = StackSeed.PopFourNeighbours = GetFourNeighbourSeeds(bm, PopSeed) '上下左右四鄰點(diǎn)For Each point In FourNeighboursIf Not StackSeed.Contains(point) ThenStackSeed.Push(point)End IfNextbm.SetPixel(PopSeed.X, PopSeed.Y, newColor)LoopReturn TrueEnd Function

未完待續(xù)!

總結(jié)

以上是生活随笔為你收集整理的网页验证码识别实例VB.NET2019(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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