ChinaUnix首页 > 精华文章 > C/C++ > 正文

[保留] 年终清货之HappyOCR


http://www.chinaunix.net 作者:醉卧水云间  发表于:2008-05-26 22:13:47
发表评论】 【查看原文】 【C/C++讨论区】【关闭

关于HappyOCR之一 

对于0CR感兴趣有许多年了,断断续续做了些研究,囊括起来就成了HAPPYOCR这个东西。从开始写点东西到现在,前后可能有8,9年了,一直也没有写过什么总结,近两年来也基本没怎么搞过,为了让感兴趣的人有所了解,为了让这个软件不浪费在我手并继续发展,现在开源出来供大家参考,供初学者学习,供高手指点。
 
OCR这个领域主要还是研究性的,相对成熟的商业产品是尚书和清华的两个东西吧。这个产业链相对小些,商业性也弱些,反正我做这个基本是研究性的。99年感兴趣人工智能,就开始写点零碎代码,慢慢累计了这些东西。关于整个思路,其实说起来很简单,没有什么神秘之处。
 
我是这样来看的,人识别一个字的时候,我认为在一瞬间对比了他所知道的每一个字(这方面大脑确实比机器快许多),哪个字最象这个字他就会认为这个字就是那个最象的字。如果碰到一个字象这个又象那个,那就看更象哪个。所以我的实现就是每个字都用一个小的神经网络去学习,每个字都对应一个识别网络,识别每个字都让每个字的神经网络去识别一次,哪个神经网络给出的结果最优就认为是这个结果。
 
因为不考虑手写体(无法收集到大量字库),所采用的训练字库,是找了一些有代表性的现成的字库,黑体,宋体等。再用这些标准字训练BP网络,得到每个字的识别网络,即可得到识别的基础。



 醉卧水云间 回复于:2007-12-28 15:37:09

关于HappyOCR之二

HappyOCR的识别率还是不错的,相对清晰的图象,大约在99%左右,差点的一般在95%以上,可以识别彩色图象(会转换处理),有水平校准,有版面分析,分块识别等,但没有表格识别,版面分析比较弱,因为没仔细研究过。曾经扫描过一本书来做测试,因为扫描质量还不错,识别率很高。可惜现在找不到那些扫描文件了,包括训练好的网络数据也没有备份下来,导致程序缺少数据而无法运行。下面我还要提到这一点。
 
整个系统在windows下做的,不过移植到linux也不是很难,只是目前我没有时间来做,熟悉wxWindows的可能两周可以做完。以前一直用sqlserver来学习和存储,这几天我把数据库改为sqlite了,方便些,不必装一个大型数据库了,从使用上来看,速度也没什么影响。
 
系统大约有这么一些东西:
 
1。字库转换工具,可以把windows下的字库转换成不同分辨率的点阵字库用于训练。整个系统采用的是24*24点阵,不过这个工具可以转换许多分辨率的点阵。
 
2。字库导入工具,可以把转换的字库导入到数据库里,这样方便训练网络。
 
3。训练工具,可以提取数据库中的字体训练网络,并且把训练好的网络写回数据库存放。
 
4。文件字体和数据库字体查看器。
 
5。主体程序HappyOCR,初始化时读进网络数据,然后读图象即可识别文字。


 醉卧水云间 回复于:2007-12-28 15:37:57

关于HappyOCR之三

HappyOCR的识别速度大约在5-8个/秒(1.7g单核CPU),是比较慢的,尚书就快的多,但是HappyOCR是纯网络识别,没有用到任何特征值来缩小范围,如果选2级字库来识别,则每个字都要交给6000多个网络去识别,这样一来当然会比较慢些。要优化速度则需要添加特征值过滤。内存占用也比较大,因为所有识别网络都需要装入内存来做,但512M内存的机器跑是没问题的,1G就更好了。
 
 
训练网络数据是比较麻烦的事,因为丢失了这些数据,所以这几天我又重新开始训练网络了。以前做过约30万字库的训练,三台机器(都不够快)跑大约两周训练出了所有二级字的识别网络。这次重写了训练程序,一来为求更快的训练速度,二来为求多线程支持,毕竟很多人都有双核机了,有多线程支持可以更快,早年很少,都是单核的就没必要。现在在我1.7g单核上跑,大约需要2小时做出一个文字区。这样算起来约需要150小时算完,当然,这样算出来的网络只是基本可用,因为这次只用了6万个字来训练,要想识别率更好,还需要导入更多字体和不同分辨率的字体,开源以后或许有人愿意去做吧,训练大的字库确实需要很长时间,我就不过分烧自己的CPU了,没效率,现在有双核的人还挺多。字库越多,则识别率越高,当然前提是输入的字是对的。如果我有大型机的话,我希望字库能做到2000万,不过在PC上计算,一两台是解决不了问题的。不过开源以后会好算点,因为可以分工来计算不同的字再合起来,有兴趣的可以算算,当前程序使用的是空闲时间,不影响正常程序。
 
单网络识别有个好处就是可以在学习新的字体时,不会过分干扰到其他已经训练好的网络,因为各网络的识别是独立的,这样,在识别过程中,随着新的不能识别的字添加到字库里,网络可以越来越准确。BP网络采用576*3*1的结构,3为隐层节点数,从经验来看够用了,学几十种字体没问题,2就似乎少了,4影响速度及空间。


 醉卧水云间 回复于:2007-12-28 15:38:50

关于HappyOCR之四

OCR一个很关键的问题是网络训练,字库越大训练时间越长,识别效果也越好。训练程序以前有一个,可以用,不过时不时会陷入极小点导致死循环训练不到结果,需要手工干预。这次发布出来的是新写的,支持多CPU,改进了一些算法,希望能适当的提高速度,看起来训练也不太容易陷入极小,可以比较放心的让它长时间跑。另外值得一提的是字体倒入到数据库是极其缓慢的过程,要倒入5万个字进入sqlite字库需要2个多小时,字库越大可能还会更慢,数据库的写入就是比较慢的,sqlserver似乎要更快点,不太记得了,不过也是个慢过程。所以将来如果有人自己从头做起的话,要注意这一点。字体转换很快,但倒入到数据库很慢。当然,训练网络就更慢了,那是核心部分。
 
关于BP网络,前面提到当前采用的是576*3*1的结构,即输入的是一个24*24的图象,输出是一个数值,正确输出确定为0.8,错误输出要求小于0.6,在识别时,所有网络输出自己的独立识别结果,最接近0.8的就是识别结果,当只有一个识别结果处于0.8左右,而其他都<0.6时,基本可以确定这个识别是准确的。结果在0.6-1.0之间的都是可疑识别,将这些可疑识别对0.8的距离排序,就可以得到一个识别序列供用户选择,正确的字基本上都会在10个最优结果里面。
 
关于训练网络的方法是这样的,先训练正确的字,穿插训练随机样本做反面训练,当全部正确的字都可以识别后,识别所有字库里的字,不正确的字输出必须让他小于0.5,否则就训练这个字直到所有不正确的字输出都小于0.5及所有正确的字输出都接近0.8为止,很多时间花在反复校验字库中所有字的识别上。字库越多,这种校验所费时间就越大。


 醉卧水云间 回复于:2007-12-28 15:39:40

关于HappyOCR之五

版面分析和前后处理是弱项或缺失,版面分析是比价困难的事,对于复杂的版面越是困难,这还不能用一种类似神经网络的通用方法来解决,基本上属于图象分析领域而不属于识别范畴,这部分只做了个简单的,自动分析不行时也可以手动分块排序。前处理指字的特征过滤,每次识别都用2级字的全部网络来依次识别是比较费事的,如果能加上特征过滤识别就会快很多,当然,如果特征取的不合适,也会因此导致判别失误,这方面我兴趣不大,所以没做。后处理是指根据识别的最终结果来进行上下文的调节,有时一个没有把握的识别可以依照上下文的词语关联来获得更好的确认,甚至可以修改识别错误,这方面需要做一个词频统计库,算是一个专门的领域了,如果能理解句子的含义并调节识别那就是一个更高的层次了,不过整句的理解似乎还没谁能做到,这是更高级别的人工智能范畴了,如果这方面有突破,则必将带动OCR突破,OCR要上台阶必须理解句子的意思,否则总会出现一些误判。

一级汉字区号从0xB0开始,往后40个区都是,每区94个字,二级字是之后的31个区,本软件训练包括全部2级汉字以及一个常用符号数字区0xA3,识别时如果只需要识别一级字则速度较快,但一般的文章都需要二级字,二级字里有一些还是比较常见的,没有二级字网络就会误判。

至于英文识别问题,目前有很多软件都解决的不错,相对汉字识别,英文要容易许多,毕竟只有26个字母需要训练,可以训练的很全面,训练也很方便。不过连字拆分可能比汉字的多些,总体比汉字容易做。我没有这方面的兴趣,这个软件目前只以汉字识别为目标。

[ 本帖最后由 醉卧水云间 于 2007-12-28 17:25 编辑 ]


 醉卧水云间 回复于:2007-12-28 15:40:23

关于HappyOCR之六
整个系统都是采用GB编码来做的,因为开始做时UNICODE尚不流行,考虑到如果考虑到移植,则转为使用UNICODE比较合适,转换很简单,可以整个系统转,也可以单独转主程序。
 
数据库中有两个表,一个字体表,一个网络表;字体表存放所有训练的字体,网络表存放网络权值。
 
数据库名:ocr.db
 
字体表:FontTable24
有三个字段:
Seq INTEGER 
Code INTEGER
FontImage BLOB
 
网络表:FloatWeight
Code INTEGER 
MidNum INTEGER
Weight BLOB
 
Code代表字的编码,MidNum代表网络的中间节点数,当前基本为3,可调节。为避免倒入相同的字,将来可以在字体表中加一个HASH项目。
 
当前主程序做识别时,直接从数据库导入网络数据,如需脱离数据库运行,需要有倒出网络的工具,目前没做。包含的程序在有关数据库时都是在操作本目录下的ocr.db,所有程序最好放在同一个目录下运行,字体转化工具不需要数据库,可独立运行。
 
编译需要一些库比如sqlite,cximage,可采用VC6编译,也许可以用2005。比较简单不详述。


 醉卧水云间 回复于:2007-12-28 15:44:48

界面图







 醉卧水云间 回复于:2007-12-28 15:47:34

具体的代码及程序将发到:

http://groups.google.com/group/multiget


 yangyufeng507 回复于:2007-12-28 15:59:43

牛人。s  f


 zhujiang73 回复于:2007-12-28 16:52:21

LZ 是高人。 :)  

目前我需要在任意背景当中识别出一个已知物体,请前辈给点建议。 :)


 醉卧水云间 回复于:2007-12-28 17:19:05

引用:原帖由 zhujiang73 于 2007-12-28 16:52 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7782505&ptid=1035636]
LZ 是高人。 :)  

目前我需要在任意背景当中识别出一个已知物体,请前辈给点建议。 :) 



你的问题主要是图象处理来解决,这方面我做的不多,只做过些简单的。也可以考虑用神经网络,不过要缩小图象。

这些年对OCR感兴趣的确实很少,我也只是兴趣。


 xi2008wang 回复于:2007-12-28 23:33:04

啊,楼主都编程九年了!:shock: 牛人啊


 okmmno1 回复于:2007-12-29 08:54:07

引用:原帖由 zhujiang73 于 2007-12-28 16:52 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7782505&ptid=1035636]
LZ 是高人。 :)  

目前我需要在任意背景当中识别出一个已知物体,请前辈给点建议。 :) 


听起来像是图像识别,帮女朋友做论文的时候知道有ADA,BOOST……


 nizvoo 回复于:2007-12-29 10:34:45

非常好,考虑的很好,特别是unicode,我现在基本上都用unicode。我看过你的奔流,这个happyOCR似乎没有原始代码下载


 seelook 回复于:2007-12-29 13:17:41

:em17: 

学习了


 醉卧水云间 回复于:2007-12-29 13:32:33

引用:原帖由 nizvoo 于 2007-12-29 10:34 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7784865&ptid=1035636]
非常好,考虑的很好,特别是unicode,我现在基本上都用unicode。我看过你的奔流,这个happyOCR似乎没有原始代码下载 



代码这两天就陆续会发,主要有些工具还没有改完,数据库方面调整太大。


 cheng_lai_shun 回复于:2007-12-29 14:03:48

这是个非常有前景的东东
LZ太牛了


 zhujiang73 回复于:2007-12-29 14:14:40

引用:原帖由 醉卧水云间 于 2007-12-28 17:19 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7782671&ptid=1035636]


你的问题主要是图象处理来解决,这方面我做的不多,只做过些简单的。也可以考虑用神经网络,不过要缩小图象。

这些年对OCR感兴趣的确实很少,我也只是兴趣。 



神经网络,我最近学了一点。:)  看来需要先把图像分割并二值化后,把各个子图送神经网络识别。不过现在的主要问题是,有时图像中目标物体的边缘不是很明显,甚至部分被其它物体遮挡,不容易从背景中分割出来。


 醉卧水云间 回复于:2007-12-29 17:03:48

引用:原帖由 zhujiang73 于 2007-12-29 14:14 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7786371&ptid=1035636]


神经网络,我最近学了一点。:)  看来需要先把图像分割并二值化后,把各个子图送神经网络识别。不过现在的主要问题是,有时图像中目标物体的边缘不是很明显,甚至部分被其它物体遮挡,不容易从背景中分割出来。 



这种问题一向很难,呵呵。


 zhujiang73 回复于:2007-12-30 19:26:43

引用:原帖由 醉卧水云间 于 2007-12-29 17:03 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7787346&ptid=1035636]


这种问题一向很难,呵呵。 



我不是做商业程序,不用着急。 这种问题是很难,属于科技前沿 :mrgreen:  , 不过也很有趣。

[attach]228445[/attach]

比如要识别这张图中的 A ,要么设法把 A 分割出来,要么设计一个神经网络,输入此图时输出层代表 A 的神经元仍然兴奋。







 醉卧水云间 回复于:2007-12-31 10:53:16

小图可以用模板匹配


 zhujiang73 回复于:2007-12-31 16:40:12

引用:原帖由 醉卧水云间 于 2007-12-31 10:53 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7791178&ptid=1035636]
小图可以用模板匹配 



      模板也不容易呀 :em16: :mrgreen: , 通常要求模板有一定弹性,可以匹配有一定变化的图像。例如手写体字符的识别就需要弹性模板,设计弹性模板和设计神经网络一样难。:)   远期目标是,编程模拟一些动物的视力,例如麻雀,它们能够分辨出树叶上趴着的虫子。 :)


 醉卧水云间 回复于:2007-12-31 18:11:56

引用:原帖由 zhujiang73 于 2007-12-31 16:40 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7791993&ptid=1035636]


      模板也不容易呀 :em16: :mrgreen: , 通常要求模板有一定弹性,可以匹配有一定变化的图像。例如手写体字符的识别就需要弹性模板,设计弹性模板和设计神经网络一样难。:)   远期目标是,编程模拟一些动 ... 



模拟麻雀的视觉?你先模拟蚊子的视觉吧:luya: :luya: :luya:


 zhujiang73 回复于:2007-12-31 19:16:53

引用:原帖由 醉卧水云间 于 2007-12-31 18:11 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7792109&ptid=1035636]


模拟麻雀的视觉?你先模拟蚊子的视觉吧:luya: :luya: :luya: 



 据报道,蚊子是用红外热成像和二氧化碳追踪联合制导,此类设备不容易买到。:emn35:


 wheel 回复于:2008-01-02 14:42:04

支持一下。。有情给顶。。


 醉卧水云间 回复于:2008-01-02 21:16:50

引用:原帖由 wheel 于 2008-1-2 14:42 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7798225&ptid=1035636]
支持一下。。有情给顶。。 



谢谢,不过我早就知道这里对识别感兴趣的不多,其实发到人工智能的论坛更合适,不过我懒于去注册了:)


 sikale 回复于:2008-01-17 11:12:01

对楼主的开源精神感到敬佩!


 zaszas 回复于:2008-02-15 17:36:46

学习中,楼主好人啊 ,,谢谢。。。。


 luoweiliuz 回复于:2008-03-09 23:47:03

只是下载下来的程序不能识别,想亲身测试一下。楼主开源好呀。:wink:


 luoweiliuz 回复于:2008-03-10 00:12:22

本人对OCR也很有兴趣,希望能得到楼主的指点。。


 reiase 回复于:2008-03-10 00:32:11

引用:原帖由 醉卧水云间 于 2008-1-2 21:16 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7799704&ptid=1035636]


谢谢,不过我早就知道这里对识别感兴趣的不多,其实发到人工智能的论坛更合适,不过我懒于去注册了:) 



那边好多做毕设的正等现成代码呢,您老送去这代码:em17: 就义了
我后边会做识别方向,要请LZ多指点了


 yj_yulin 回复于:2008-03-13 23:39:26

近来想看看这些智能的东西,不过程序编译不了,楼主的socklib没有带上,请补充一下吧


 reiase 回复于:2008-05-19 12:26:53

LZ好像最近没上线


 醉卧水云间 回复于:2008-05-19 12:56:05

zai:mrgreen:


 lubob 回复于:2008-05-19 15:10:24

感谢楼主!!


 coneagoe 回复于:2008-05-26 09:50:08

前后8、9年,楼主的毅力真是强啊


 nicsky 回复于:2008-05-26 11:43:23

:em09: :em09: :em09: :em09: :em09:


 NewCore 回复于:2008-05-26 22:13:47

站个位置,学习一下




原文链接:http://bbs.chinaunix.net/viewthread.php?tid=1035636
转载请注明作者名及原文出处