自从在http://www.cnblogs.com/zcsor上写了一点东东就很久很久没有在CSDN的博客上写东西了。
这篇所说的都是基于VB.NET的。还是从最基础的东西说,“高级”的带旋转啥的的,大家都不说,我也就不要说,免得挨骂,毕竟我不是指望这个糊口的。先从最最基本的开始:
一、白底上绘制几个黑字符——固定字体(包含大小),固定字色和底色。
这个想识别最简单不过的了。提出几个思路:
1、模板匹配:这是最经典的手段之一了。这个模板是很好建立的,只需要把黑色的字整个保存起来作为标准,或者把边缘进行保存作为标准,或者……取一些恰当的样点,都完全可行,不过一般都是用边缘的,因为运算数量少一些,特征完整。
2、其他特征:这里不讲封闭特征直线特征,对于我们这些新手来言实在是太晦涩的代码了。我讲一个简单的思路:我们可以用快速填充或者经其改进的边缘检索,来提取特征,然后进行数组比较。还可以把提取出来的点进行归类,归类方式有很多了,按象限看每个象限的比例或与中心的距离;也可以分成若干块……发挥你的想象力吧。
3、神经网络:ANN嘛,这个东东用在这里很恰当。只是封装ANN的时候从一个神经到一个层到一个网络,加之BP什么的理解起来也需要点抽象思维,可能不是特适合我们新人。
以上,对付一点黑杂点杂线啥的都没有任何问题(除了你用快速填充和边缘检索,所以这个思路虽然机械化程度高,代码寥寥几十行,但是适应性也不令人满意)
二、带点色彩
这个带点色彩说的是字符带点色彩,啥色彩?只要人眼分辨容易的,你是带过渡啊,你是带杂点啊,杂线啊,只要能和背景分开别旋转就好说。
就以每个字符都是黑色边框来说。
1、模板匹配:话说你怎么还模板匹配呢?还能匹配出来吗?当然能了,只是模板稍微改进一下,有必要的话可以手工做模板(呵呵,有时重复而简单的手工劳动确实比编写一些完成这些工作的代码休闲很多)。如何改进呢,看具体情况了。
2、神经网络:已经不太建议用了,还是要和颜色灰度啥的打交道,不如模板匹配了。
如果再没有黑色边框呢?还是能够区分吧!
利用经典的灰度化,而且建议用那个心理学公式,哪个?就是那个0.59什么什么的,好像大概差不多可能吧。
最后提出一点小建议:
1、模板匹配的代码在编写时注意一下从0-9循环查找固定X,Y值,然后取匹配度高于阀值且最高的,别写成遍历X,Y寻找0,然后遍历X,Y寻找1,那是自找麻烦。
2、处理图像时灰度化不是写回图像,那样你读的时候不又要读像素,很慢的(当然你非用BITMAP类的内存读写方法我也没办法),把灰度结果记录到一个数组中速度要快,而且很多。
3、模板可以灵活一些,其实一个数字可以代表很多意义,不知道你有没有考虑过为什么很多API在用的时候都是OR,OR,OR各个参数到一起成一个就传递了?观察一下,他们(同一类别的几个常量定义)是不是这样的1,2,4,8,16成2的倍数增加?这是必须的,要不然你给OR一起去了,意义就丢失了(从二进制理解下就明白)。那我们也可以如此定义,例如说:
DIM A=1
DIM B=2
DIM X=4
DIM Y=8
DIM Z=16
这里AB是一组,XYZ是一组的,也许用枚举更好。。。那我想表示AX的话,只需要K=A OR X即可了,这里的OR就是或:
A用二进制表示就是0001
X用二进制表示就是1000
OR运算就是只要有一个参与运算的该位是1结果中就是1
AX的结果就是 1001
其实很简单,我多嘴了,不过打了好几分钟,留着吧……
接下来。。。。还得“解码”咱把意义放入一个数这倒是好事,可我们怎么分离他们呢?
答案:去OD哪些API怎么分离参数的。赶快去吧,回来往下看。。。
呵呵,不会去了吧啊?OR的反运算是什么来着?好像是AND吧。。。。那也许代码就该这么写:
IF (K AND X )= X THEN ‘如果K中含有X则
K用二进制表示就是1001
X用二进制表示就是1000
A用二进制表示就是0001
AND运算就是必须参与运算的两个该位都为1结果中才为1
那么K AND X就是 1000
K AND A就是 0001
所以只需要用AND运算来进行测试就可以了。而上面例子中有两组:AB,XYZ你就需要进行分别解码,多写几个IF或者CASE。
只是想给新手一些思路上的帮助,抛砖引玉。
原文链接:https://www.f2er.com/vb/262207.html