我现在继续来研究验证码的识别之类的话题,现在要研究的是针对有倾斜的验证码,比如一张验证码上面有4个字符。每个字符都是有一定角度的偏移(这个偏移是小于90°的),我想知道这个字符是向左偏,还是向右偏,偏移量是多少,不知道各位高手有什么见解?
解决方案 »
- ()=>obj.PropertyName转换成delegate描述的话应该是怎样子?
- c#的一个小问题 没弄清楚 帮忙解决下
- 那位高手在使用waveInOpen&waveOutOpen时用过线程作回调使用,即使用CALLBACK_THREAD了参数?有c++的代码,但.net不知道怎么写?
- 关于在Winform中拖拽文件夹及文件
- 求一条SQL语句
- 用DataTable如何在DataGrid中实现列求和?
- 为什么插入图片的时候会出错,而且没有插入记录的时候,记录越来越多啊?
- 大型文件的切分方法
- 简单问题,怎么在一个web页面中点击事件中使另一个web页面show。
- C# 点样可以罗到当前的日期时间的啊。
- 删除gridview中的某一行
- 关于网站CSS内联元素
Bitmap curBitmap = new Bitmap(pictureBox2.Image.Width, pictureBox2.Image.Height);
Graphics g = Graphics.FromImage(curBitmap);
Matrix X = new Matrix();
// X.Rotate(30);
X.Shear((float)0.16666666667, 0); // 2/12
//X.Shear((float)0, 0); // 2/12
g.Transform = X;
// Draw image
//Rectangle cloneRect = GetPicValidByValue(128); //Get Valid Pic Rectangle
Rectangle cloneRect = new Rectangle(6, 5, 40, 12);
//Rectangle cloneRect = new Rectangle(0,0, curBitmap.Width, curBitmap.Height);
Bitmap tmpBmp = ((Bitmap)pictureBox2.Image).Clone(cloneRect, pictureBox2.Image.PixelFormat);
g.DrawImage(tmpBmp,
new Rectangle(6, 5, 40, 12),
//cloneRect,
0, 0, tmpBmp.Width,
tmpBmp.Height,
GraphicsUnit.Pixel); pictureBox3.Image = curBitmap;
其中 X.Shear((float)0.16666666667, 0); // 2/12
这里的偏移量的设置是固定的,也就是要自己不断的一个一个的试。而且也不知道到底是左偏移,还是右偏移。所以就想到要是有能直接的求偏移量的算法就好了,而且能求出是左偏移还是有便宜的。
另外我想问个问题就是怎么可以在这里插入图片呢?不是插入外部的,是我电脑上的。我想给图片放上来让高手看看,并给小弟一些宝贵的建议!
主调方法:
/// <summary>
/// 返回识别结果
/// </summary>
/// <param name="maps"></param>
/// <param name="dgGrayValue"></param>
/// <returns></returns>
public string get_checkResult(Bitmap[] maps, int dgGrayValue)
{
string result = "";
for (int i = 0; i < maps.Length; i++)
{
Bitmap bmp = maps[i];
result += Similarity_calculation(bmp, dgGrayValue);
}
return result;
}Similarity_calculation 方法:
/// <summary>
/// 计算图片的相似度
/// </summary>
/// <param name="maps"></param>
/// <param name="dgGrayValue"></param>
/// <returns></returns>
public string Similarity_calculation(Bitmap map, int dgGrayValue)
{
string result = "";
if (map != null)
{ #region 第一步:1.将每张图片按像素存放到一个长度为32的32位整型数组里面,每个整数存放一行,整数的每位存放一个像素值(0或者1)
//将当前的图片转化成 0 1码
int[] charCode = GetTraitCode_array(map, dgGrayValue);//一共是1024位
List<Int32[]> recList = new List<Int32[]>();//要是别的图片 长度为32的 32位整型数组
int tempIndex = 0;
for (int i = 0; i < 32; i++)
{
Int32[] rec_bmp = new Int32[32];
for (int j = 0; j < 32; j++)
{ rec_bmp[j] = charCode[tempIndex];
tempIndex++;
}
recList.Add(rec_bmp); }
#endregion
//将要识别的
foreach (DictionaryEntry de in TraitCodeHT)//逐条记录对比
{
double res = 0d;//对比结果
string[] valueArray = de.Value.ToString().Split(',');//当前key下面的value集合
for (int s = 0; s < valueArray.Length; s++)//循环每个value
{
List<Int32[]> traitList = new List<Int32[]>();//将要作为参照对比的 长度为32的 32位整型数组
tempIndex = 0;
for (int i = 0; i < 32; i++)
{
Int32[] trait_bmp = new Int32[32];
for (int j = 0; j < 32; j++)
{
trait_bmp[j] = valueArray[s].ToString()[tempIndex];
}
traitList.Add(trait_bmp);
}
//在此刻已经得到 两个 List<Int32[]> 了
//循环求余弦对比
for (int i = 0; i < 32; i++)
{
res += GetCosine((int[])traitList[i],(int[])recList[i]);
}
if (res > 0.7)
{
break;
} } if (res > 0.7)
{
result = de.Key.ToString();
break;
}
} } return result;
}GetTraitCode_array 方法:
/// <summary>
/// 返回灰度图片的0或1特征码,1表示灰点,0表示背景 32×32
/// </summary>
/// <param name="singlepic">灰度图</param>
/// <param name="dgGrayValue">背前景灰色界限</param>
/// <returns>特征码</returns>
public int[] GetTraitCode_array(Bitmap bmp, int dgGrayValue)
{
Color piexl;
int[] code = new int[bmp.Width * bmp.Height];
int temp = 0;
if (bmp != null && bmp.Width != 0 && bmp.Height != 0)
{
for (int posy = 0; posy < bmp.Height; posy++)
{
for (int posx = 0; posx < bmp.Width; posx++)
{
piexl = bmp.GetPixel(posx, posy);
if (piexl.R < dgGrayValue) // Color.Black )
{ code[temp] = 1;
}
else
{ code[temp] = 0;
}
temp++;
}
}
}
return code;
}GetCosine 方法:
/// <summary>
/// 计算相似度(相似度越高,图片相同的概率越大)
/// 2.计算分子时,将两个这样的数组中的整数按照对应的索引分别按位与,然后将计算结果按位相加;
/// 3.计算分母时,将每个数组中的所有整数按位相加,然后开根号,最后相乘;
/// 4.分子除以分母,得出余弦值。
/// </summary>
/// <param name="e1"></param>
/// <param name="e2"></param>
/// <returns></returns>
public double GetCosine(int[] e1, int[] e2)
{
int a = 0;//分母1
int b = 0;//分母2
int c = 0;//分子
for (int y = 0; y < 32; ++y)
{
//两个数组中的整数按位与
int i = e2[y] & e1[y];
//按位加
for (int x = 1; x < 33; ++x)
{
c += (i >> x) & 1;
a += (e2[y] >> x) & 1;
b += (e1[y] >> x) & 1;
}
} //计算分母
int d = a * b;
return d == 0 ? 0 : c / Math.Sqrt(d);
}
{
res += GetCosine((int[])traitList[i],(int[])recList[i]);
}
你没理解博客里面写的内容,仔细再看看。
要接分的朋友们赶快来哦。明天上午我就结贴。呵呵。