應用C#的aforge類庫辨認驗證碼實例。本站提示廣大學習愛好者:(應用C#的aforge類庫辨認驗證碼實例)文章只能為提供參考,不一定能成為您想要的結果。以下是應用C#的aforge類庫辨認驗證碼實例正文
時光過得真快啊,轉眼本年就要曩昔了,年夜半年都沒有寫博客了,要說時光嘛,花在泡妹子和弄英語去了,哈哈。。。頭幾天老邁問我
怎樣這麼長時光都沒寫博客了,好吧,持續保持,持續分享我的心得領會。
這個系列我們玩玩aforge.net,套用官方都話就是一個專門為開辟者和研討者基於C#框架設計的,這個框架供給了分歧的類庫和關於類庫的
資本,還有許多運用法式例子,包含盤算機視覺與人工智能,圖象處置,神經收集,遺傳算法,機械進修,機械人等范疇,這個系列研討的重點
就是瞎幾把弄下AForge.Imaging這個定名空間上面的東東,下載網址:http://www.aforgenet.com/framework/downloads.html
對了,不曉得有若干公司是用得仕卡作為員工的福利卡,我們公司就是如許的,每一個月公司都邑充值一些money,然後我們這些屁碼農每一個月15號就都高興的去看看發了若干。
上去看了後,喲呵~ 還有個90年月的驗證碼,我想這歲首估量找到如許驗證碼的網站曾經不多了,假如懂一點圖象處置都話,這張驗證碼
跟沒有一個樣,感謝。。。這篇我們看看怎樣去辨認它。
一: 驗證碼處置
1. 普通處置准繩
這類驗證碼為何說跟沒有一樣,第一點:字體標准工整,第二點:不扭轉歪曲粘連,第三點:字體色彩單一,上面看處置步調。
這裡要留意的是,aforge只接收像素格局為24/32bpp的像素格局圖片,所以處置前,先輩行格局轉化。
//轉化圖片像素格局
var bnew = new Bitmap(b.Width, b.Height, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(bnew);
g.DrawImage(b, 0, 0);
g.Dispose();
<1>圖片灰度化
這是圖象辨認平日都要走的第一步,圖片灰度化有助於削減後續對rgb的盤算量,同時也便利我們停止二值化,在aforge中我們有專門的類一步弄定,簡練便利。
//灰度化
b = new Grayscale(0.2125, 0.7154, 0.0721).Apply(b);
<2>二值化
二值化望文生義就是二種值,好比非白即黑,非黑即白,那末白和黑的尺度就須要供給一個阈值,年夜於或許小於怎樣樣,在aforge異樣也有類似的類停止處置
//二值化
b = new Threshold(50).Apply(b);
<3> 去噪點
從下面的圖片可以發明有許多紅點點,弄得像皮膚病一樣,細心不雅察可以看到這類噪點具有自力,體積小的特點,所以斷定的尺度就是假如圖中某個區塊的年夜小在我設置的阈值內,就將其去失落,異樣也有專門的類停止處置。
//去噪點
new BlobsFiltering(1, 1, b.Width, b.Height).Apply(b);
這裡詳細怎樣傳遞參數,後續系列會漸漸解讀。
<4>切割圖片
切圖片的利益在於我們須要曉得真正要辨認的元素的有用規模是多年夜,同時也便利我們將這些圖片作為模板保留上去。
代碼以下:
/// <summary>
/// 依照 Y 軸線 切割
/// (拋棄等於號)
/// </summary>
/// <param name="?"></param>
/// <returns></returns>
public List<Bitmap> Crop_Y(Bitmap b)
{
var list = new List<Bitmap>();
//統計每列的“1”的個數,便利切除
int[] cols = new int[b.Width];
/*
* 縱向切割
*/
for (int x = 0; x < b.Width; x++)
{
for (int y = 0; y < b.Height; y++)
{
//獲得以後像素點像素
var pixel = b.GetPixel(x, y);
//解釋是黑色點
if (pixel.R == 0)
{
cols[x] = ++cols[x];
}
}
}
int left = 0, right = 0;
for (int i = 0; i < cols.Length; i++)
{
//解釋該列有像素值(為了避免像素攪擾,去噪後湧現空白的成績,所以多斷定一下,避免切割成多個)
if (cols[i] > 0 || (i + 1 < cols.Length && cols[i + 1] > 0))
{
if (left == 0)
{
//切上去圖片的橫坐標left
left = i;
}
else
{
//切上去圖片的橫坐標right
right = i;
}
}
else
{
//解釋曾經有切割圖了,上面我們停止切割處置
if ((left > 0 || right > 0))
{
Crop corp = new Crop(new Rectangle(left, 0, right - left + 1, b.Height));
var small = corp.Apply(b);
//居中,將圖片放在20*50的像素外面
list.Add(small);
}
left = right = 0;
}
}
return list;
}
/// <summary>
/// 依照 X 軸線 切割
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public List<Bitmap> Crop_X(List<Bitmap> list)
{
var corplist = new List<Bitmap>();
//再對朋分的圖停止高低切割,掏出高低的白邊
foreach (var segb in list)
{
//統計每行的“1”的個數,便利切除
int[] rows = new int[segb.Height];
/*
* 橫向切割
*/
for (int y = 0; y < segb.Height; y++)
{
for (int x = 0; x < segb.Width; x++)
{
//獲得以後像素點像素
var pixel = segb.GetPixel(x, y);
//解釋是黑色點
if (pixel.R == 0)
{
rows[y] = ++rows[y];
}
}
}
int bottom = 0, top = 0;
for (int y = 0; y < rows.Length; y++)
{
//解釋該行有像素值(為了避免像素攪擾,去噪後湧現空白的成績,所以多斷定一下,避免切割成多個)
if (rows[y] > 0 || (y + 1 < rows.Length && rows[y + 1] > 0))
{
if (top == 0)
{
//切上去圖片的top坐標
top = y;
}
else
{
//切上去圖片的bottom坐標
bottom = y;
}
}
else
{
//解釋曾經有切割圖了,上面我們停止切割處置
if ((top > 0 || bottom > 0) && bottom - top > 0)
{
Crop corp = new Crop(new Rectangle(0, top, segb.Width, bottom - top + 1));
var small = corp.Apply(segb);
corplist.Add(small);
}
top = bottom = 0;
}
}
}
return corplist;
}
<5> 圖片精處置
這裡要留意的是,好比數字“2”,切除高低閣下的空白後,再加上噪點的攪擾,紛歧定每次切上去的圖片年夜小都一樣,所以這裡為了便利更好的辨認,我們須要重置下圖片的年夜小,而且將“數字2”停止文字居中。
/// <summary>
/// 重置圖片的指定年夜小而且居中
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
public List<Bitmap> ToResizeAndCenterIt(List<Bitmap> list, int w = 20, int h = 20)
{
List<Bitmap> resizeList = new List<Bitmap>();
for (int i = 0; i < list.Count; i++)
{
//反轉一下圖片
list[i] = new Invert().Apply(list[i]);
int sw = list[i].Width;
int sh = list[i].Height;
Crop corpFilter = new Crop(new Rectangle(0, 0, w, h));
list[i] = corpFilter.Apply(list[i]);
//再反轉歸去
list[i] = new Invert().Apply(list[i]);
//盤算中間地位
int centerX = (w - sw) / 2;
int centerY = (h - sh) / 2;
list[i] = new CanvasMove(new IntPoint(centerX, centerY), Color.White).Apply(list[i]);
resizeList.Add(list[i]);
}
return resizeList;
}
其實精處置後,這些圖片便可以作為我們的模板庫的圖片了,可以將每張模板圖都標志下詳細的數字,後續我們再碰到時,盤算下其類似度便可以了,上面就是曾經制造好的模板。
<6> 模板婚配辨認
既然模板圖片都制造好了,一切都差不多瓜熟蒂落了,下次來的驗證碼我都切好後做成精圖片後跟模板停止婚配,在afroge外面
有一個ExhaustiveTemplateMatching,專門用來停止模板婚配用的,很便利。
ExhaustiveTemplateMatching templateMatching = new ExhaustiveTemplateMatching(0.9f);
這裡的0.9f就是設定的阈值,只要年夜於0.9的阈值,我才以為該模板與目的圖片類似,然後在一切年夜於0.9的類似度中取到最年夜的一個作為
我們最初辨認的圖象。
var files = Directory.GetFiles(Environment.CurrentDirectory + "\\Template\\");
var templateList = files.Select(i => { return new Bitmap(i); }).ToList();
var templateListFileName = files.Select(i => { return i.Substring(30, 1); }).ToList();
var result = new List<string>();
ExhaustiveTemplateMatching templateMatching = new ExhaustiveTemplateMatching(0.9f);
//這外面有四張圖片,停止四張圖的模板婚配
for (int i = 0; i < list.Count; i++)
{
float max = 0;
int index = 0;
for (int j = 0; j < templateList.Count; j++)
{
var compare = templateMatching.ProcessImage(list[i], templateList[j]);
if (compare.Length > 0 && compare[0].Similarity > max)
{
//記載下最類似的
max = compare[0].Similarity;
index = j;
}
}
result.Add(templateListFileName[index]);
}
最初的後果照樣不錯的,辨認率根本100%吧。