这部分主要是LT做的。这里对他的代码进行下分析,活学活用。
工程是FlowChart,主要是FlowChart.cpp的recognize函数,处理过程如下:
【1. 读取图像,将其转为二值图。】
使用了openCV里的东西,所以比较方便。它全称是Open Source Computer Vision Library。计算机视觉市场巨大而且持续增长,且这方面没有标准API,所以OpenCV应运而生。如有直接读取图片的函数IplImage *pSrc = cvLoadImage(imgName,0);,还有直接二值转化的函数cvCvtColor(pSrc,pDump,CV_GRAY2BGR);。
【2.识别椭圆形。】
识别图形方面,OpenCV也有专门的函数cvFindContours,用来找到图像中的轮廓,然后对这些轮廓进行判断,检测他们是否满足椭圆的几何特性。在这些轮廓中进行选择3个点来进行椭圆拟合,进行多次迭代,这个也有cvFitEllipse2。进行判断。
这里用到的识别,基于hough变换,参考另一篇转载的文章。
当然,强大的openCV也有相关的函数进行处理cvHoughCircles。
【3.识别矩形。】
这与上面的第二步类似。还有需要做到的,进行整合。因为在图像中的同一个矩形框,可能会被多次识别出来(因为边有厚度)。所以,要整合这些矩形框。
openCV里没有直接的检测矩形的函数,可以通过检测出直线,再处理判断平行垂直的四条线.cvLine2.
【4.进行规则一判断:图里面包含的元素个数是否大于最低值。】
如果上面检测的椭圆形+矩形数量,少于自定义参数MIN_ELEMENT_NUM(程序中为3),那这个图不是流程图。
【5.识别箭头和直线】
这部分真心没看懂。但是,也有线段的整合的问题。一幅图片可能没那么清晰,一条线段,可能中间断开,可能一部分粗,一部分细,所以,实际的一条线段可能会提取出好多线段。整合可以通过他们的斜率,他们的位置等等情况进行。
这里还有一点,就是进行箭头和直线识别前,首先要将已经检测出来的椭圆形和矩形擦除掉,矩形也有线段,里面的文字也可能会检测出线段。这个擦除,包含对矩形线段的擦除,所以,可以向外扩展一些像素,将边沿像素也擦除。
【6.进行规则二判断:线条个数是否大于最低值】
线段数太少,也不是流程图。
【7.建立各元素的逻辑关系】
进行逻辑关系判断前,首先需要对线段进行逻辑的处理。可能有以下的箭头。那么我们需要将它转换为四条逻辑的线段即可,从开始点都四个端点。
进行逻辑判断,主要是分情况进行讨论,如线段的端点,和这个元素的距离是多少,如果是少于一个自定义的参数grap,那么他们是相连接的。
【8.调用OCR程序】
这个从网上下载的参数。首先,需要将单独一个元素的图像提取出来,比如一个矩形,单独将框框内的内容提取出来,这样OCR才可以处理。可以通过//HGY cvSetImageROI 基于给定的矩形设置图像的ROI(感兴趣区域,region of interesting)这个函数来提取某一部分的图形。OCR (Optical Character Recognition,光学字符识别)。可以依赖于微软提供的MODI实现。MODI,Microsoft Office Document Imaging工具,用它可以查看、管理、读取和识别图像文档和传真文本。MODI也能让您执行光学字元辨识 (OCR)。藉著执行 OCR,您可以将文字从扫描影像或传真复制到另一个位置。
【9.进行规则三判断:shape里文字提取是否大于最大比率】
如果在shape里能提出出文字的比率低于自定义参数RATE_THRESHOLD,那这也不是流程图。
【10.存储在xml文件里】
将结果保存
【11.释放内存】
这部分很重要,因为有整个数据库需要进行处理。所以内存释放不好,就会有很多垃圾产生。这部分也是后期调试的重要部分。再完善!
这个程序,可以有效地将正确的流程图检测出来。但是,也很容易将其他图也判断为流程图。误检率很高。
并且,它较多地使用了自定义参数,如规定一幅图里最少有多少元素,多少线段,线段和元素的相隔间距最大是多少等等。由于实际的图片可能差异很大,所以自定义参数的方式不是很好。