C#识别出图片里的数字和字母
作者:hebedich 发布时间:2023-04-12 08:21:41
标签:C#,识别,图片
一个图片识别小工具,原先主要是识别以前公司的软件注册码截图里的数字和字母(每次要一个一个框复制出来粘贴到注册器里,很麻烦!),因为注册码出现的字母和数字基本就那几个,所以识别库的范围设定的比较少。
原理和算法在代码中做了详细说明,功能存在很大的局限性,但我的想法是把这个思路和实现的办法共享出来。
源码下载地址:
http://git.oschina.net/bobo2cj/iamge2text
/*
* 开发思路:图片灰度处理,二进制,然后和图片中的字二进制库精确对比
*
* 获取字库:通过下面代码中generateLicense(Bitmap singlepic)方法获得,具体操作:
* 从图片中截图出(抠出)一个字符,然后处理得到二维的二进制矩阵,比如下面的字符1对应的二维矩阵
* 00000
* 00100
* 11100
* 00100
* 00100
* 00100
* 00100
* 00100
* 00100
* 11111
* 00000
* 00000
*
* 注意:【相同字符,比如1,不同字体,字号,不同缩放大小的图片,获得到的二位矩阵中0、1排列和数量都是不同的!
* 故按照此方法来写出匹配所有字的话,那字库就大了。。。】
*
*
*/
/// <summary>
/// 提取出该图片内的字符(将进过灰度处理的图片转化为0、1的二位数组)
/// </summary>
/// <param name="singlepic">图片来源</param>
public void generateLicense(Bitmap singlepic)
{
try
{
char[,] charArray = new char[singlepic.Height, singlepic.Width]; //定义个chai型的二维数组记录每个像素上0/1的值,形成一个矩形
int imageWidth = 0; //记录图片的像素宽度
int imageHeight = 0; //记录图片的像素高度
int dgGrayValue = 128; //灰度值
Color piexl;
//string code = ""; //存储每个像素的0/1
for (int posy = 0; posy < singlepic.Height; posy++)
{//从上到下
string codeCache = ""; //存储每行的像素的0/1
for (int posx = 0; posx < singlepic.Width; posx++)
{//从左到右
piexl = singlepic.GetPixel(posx, posy);
if (piexl.R < dgGrayValue)
{// 如果该像素的颜色为黑色,值就为“1”
codeCache = codeCache + "1";
}
else
{// 否则该像素的颜色为白色,值就为“0”
codeCache = codeCache + "0";
}
}
char[] array = codeCache.ToCharArray(); //每行的0/1的值用数字保存,以便于进行循环处理
//code += codeCache + "\n";
for (imageWidth = 0; imageWidth < array.Length; imageWidth++)
charArray[imageHeight, imageWidth] = array[imageWidth]; //通过循环将每行值转存到二维数组中
imageHeight++;
} //*********************以上代码可用来获取一个字的图片二进制数组,即字库*****************************
//开始和字库进行匹配(我的工具中只需要下面的几个字符)
findWord(charArray, char0, imageHeight, imageWidth, BinaryWidth0, BinaryHeight0, '0');
findWord(charArray, char1, imageHeight, imageWidth, BinaryWidth1, BinaryHeight1, '1');
findWord(charArray, char2, imageHeight, imageWidth, BinaryWidth2, BinaryHeight2, '2');
findWord(charArray, char3, imageHeight, imageWidth, BinaryWidth3, BinaryHeight3, '3');
findWord(charArray, char4, imageHeight, imageWidth, BinaryWidth4, BinaryHeight4, '4');
findWord(charArray, char5, imageHeight, imageWidth, BinaryWidth5, BinaryHeight5, '5');
findWord(charArray, char6, imageHeight, imageWidth, BinaryWidth6, BinaryHeight6, '6');
findWord(charArray, char7, imageHeight, imageWidth, BinaryWidth7, BinaryHeight7, '7');
findWord(charArray, char8, imageHeight, imageWidth, BinaryWidth8, BinaryHeight8, '8');
findWord(charArray, char9, imageHeight, imageWidth, BinaryWidth9, BinaryHeight9, '9');
findWord(charArray, charA, imageHeight, imageWidth, BinaryWidthA, BinaryHeightA, 'a');
findWord(charArray, charB, imageHeight, imageWidth, BinaryWidthB, BinaryHeightB, 'b');
findWord(charArray, charC, imageHeight, imageWidth, BinaryWidthC, BinaryHeightC, 'c');
findWord(charArray, charD, imageHeight, imageWidth, BinaryWidthD, BinaryHeightD, 'd');
findWord(charArray, charE, imageHeight, imageWidth, BinaryWidthE, BinaryHeightE, 'e');
findWord(charArray, charF, imageHeight, imageWidth, BinaryWidthF, BinaryHeightF, 'f');
findWord(charArray, charP, imageHeight, imageWidth, BinaryWidthP, BinaryHeightP, 'p');
findWord(charArray, charY, imageHeight, imageWidth, BinaryWidthY, BinaryHeightY, 'y');
//------------------------------------END---------------------------------------------
richTextBoxLicense.Text += identifySort(); //执行identifySort方法,将我需要的格式在richTextBoxLicense文本框中显示
richTextBoxLicense.SelectionStart = richTextBoxLicense.TextLength; //将光标移到最后面
}
catch { }
}
以上所述就是本文的全部内容了,希望大家能够喜欢。


猜你喜欢
- 在安卓开发导入项目过程中,出现错误再所难免。最近导入项目就遇到如下错误,具体如下图所示。出现如上错误,最初设想先看下项目能不能运行。经尝试可
- 项目中需要判断传入的日期是否在未来的一年以内,百度了一下网上没有找到好的方式,写了,方便自己和他人:int datecompareAfter
- spring security用了也有一段时间了,弄过异步和多数据源登录,也看过一点源码,最近弄rest,然后顺便搭oauth2,前端用js
- 给对象按照字符串属性进行排序在java中对象进行排序,排序的属性是string,我们只需要实现Comparator接口,然后实现比较的方式。
- 博主最近在做一个内网项目,内部可以访问外部数据,但是外部访问不了内部数据,这也就造成了可能文件无法上传,所以博主另辟蹊径,在本地服务器上建立
- 本文实例为大家分享了百度人脸识别之人脸识别FaceIdentify,供大家参考,具体内容如下using System.Collections
- 🚀 ChatGPT是最近很热门的AI智能聊天机器人🚀 本文使用SpringBoot+OpenAI的官方API接口,自己实现一个可以返回对话数
- 函数InternetGetConnectedState返回本地系统的网络连接状态。语法:BOOL InternetGetConnectedS
- 本文实例讲述了在类库或winform项目中打开另一个winform项目窗体的方法。分享给大家供大家参考。具体如下:一、问题:假设类库或win
- Spring中添加计时器的时候根据业务需求可能会需要动态处理触发时间;import org.slf4j.Logger; import org
- 本文实例讲述了C#图像伪彩色处理方法。分享给大家供大家参考。具体如下://灰度图转伪彩色图像函数public Bitmap PGrayToC
- 用来记录自己所用到的知识前两天在做项目的时候发现有时候在访问网络数据的时候由于后台要做的工作较多,给我们返回数据的时间较长,所以老大叫我加了
- 刚开始学习Service的时候以为它是一个线程的封装,也可以执行耗时操作。其实不然,Service是运行在主线程的。直接执行耗时操作是会阻塞
- 案例说明:使用Java实现简单的斗地主洗牌发牌的操作;具体规则:共有54张牌,顺序打乱;三个玩家参与游戏,三人交替摸牌,每人17张牌,最后留
- 本文实例讲述了java swing实现的扫雷游戏及改进版。分享给大家供大家参考,具体如下:版本1:package awtDemo;impor
- 概述在 Linux 平台下使用搜狗输入法在 IDEA 中输入中文时,输入法候选框总是静止在 IDEA 的左下角,而不能跟随光标进行移动。虽然
- 01: 异步任务02: 定时任务一、SpringBoot--任务:邮件任务1.1 添加依赖(增加邮件支持)pom.xml <depen
- 本文实例为大家分享了Android画画板展示的具体代码,供大家参考,具体内容如下main.xml布局<RelativeLayout x
- 我们经常在项目中使用的线程池,但是是否关心过线程池的关闭呢,可能很多时候直接再项目中直接创建线程池让它一直运行当任务执行结束不在需要了也不去
- •静态构造函数既没有访问修饰符,也没有参数。•如果没有编写静态构造函数,而这时类中包含带有初始值设定的静态字段,那么编译器会自动生成默认的静