opencv 识别印刷体数字字母问题

Major_Tom_F 2017-11-21 02:02:03
学习opencv没有多久,开发VS2010+oencv2.4.11。之前有用SVM训练手写数字字母的分类器,现在想识别印刷体数字字母,可是找不到那么多样本图片就不怎么怎么去用SVM做了,或者说是自己还接触太少所以没有其他方向,希望有经验的能提一下建议,非常感谢!另外还有一个问题,在opencv中检测圆时的霍夫圆检测方法有很多参数,对图片的检测效果需要不断调整参数,换了一张差不多的又不行,效果还是不好,这个问题也没有解决办法呢?能不能做一个大致通用来给方法赋参数的呢?求教,再一次表示感谢!
...全文
1064 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiao586467 2018-11-24
  • 打赏
  • 举报
回复
楼主,请问印刷字体识别的样本问题你解决了吗?我也想识别印刷数字来着,但是样本很少呀,不知道怎么得到。。
shiter 2017-11-25
  • 打赏
  • 举报
回复
可以搜索一下现成的代码,参考参考
赵4老师 2017-11-22
  • 打赏
  • 举报
回复
仅供参考:
//////////////////////////////////////////////////////////////////////////
//判断轮廓是不是一个圆,通过轮廓的面积pi*r*r的差异,判断是不是圆。
//contour:输入轮廓
//minRadius: 半径长度至少大于minRadius
//////////////////////////////////////////////////////////////////////////
BOOL isCircleContour(vector<Point>& contour,double minRadius)
{
    BOOL isCircle = FALSE;

    //double perimeter = arcLength(contour,TRUE);
    double perimeter = arcLength(contour,FALSE);
	double perimeter2 =	arcLength(contour,TRUE);
	Rect rect =boundingRect(contour);
	double r = (rect.width+rect.height)/4.0;	//半径约等于轮廓外接矩的边长/2

	double area=contourArea(contour);

	double pi=3.1415926;

	//cout<<"x/y/width/height\t"<<rect.x<<"  "<<rect.y<<"  "<<rect.width<<"  "<<rect.height<<endl;
	//cout<<"perimeter:FALSE\t"<<perimeter<<endl;
	//cout<<"perimeter2:TRUE\t"<<perimeter2<<endl;
	//cout<<"area:\t"<<area<<endl;
	//cout<<"r: "<<r<<"  计算出周长: "<<2*pi*r<<"  计算出面积: "<<pi*r*r<<endl;

	double perimeterDiffRatio =	fabs(2*pi*r	- perimeter)*2.0/(2*pi*r + perimeter) *100;
	double areaDiffRatio = fabs(pi*r*r - area)*2.0/(pi*r*r + area) *100;
	double sideDiffRatio = abs(rect.width-rect.height)*2.0/(rect.width+rect.height)*100;

	//CString CstrInfo3;
	//CstrInfo3.Format(_T(" perimeterDiffRatio: %f\n areaDiffRatio: %f \n  sideDiffRatio:%f"),perimeterDiffRatio,areaDiffRatio,sideDiffRatio);
	//AfxMessageBox(CstrInfo3);

	if (r>minRadius)
	{
		cout<<"周长差异百分比:  "<<perimeterDiffRatio<<"%"<<endl;;
		cout<<"面积差异百分比:  "<<areaDiffRatio<<"%"<<endl;
		cout<<"边长差异百分比:  "<<sideDiffRatio<<"%"<<endl;;
		cout<<endl<<endl;
    }

    //原始的
    //const double areaDiffThresh = 18.0;       //目前统计的,最大的面积差2.58%
    //const double perimeterDiffThresh = 15;    //目前统计的,最大的周长差5.65%
    //const double sideDiffThresh = 15;     //目前统计的,最大的边长差7.3%
    //const double avgDiffThresh = 15.0;        //三个差异比值的加权平均要求小于5.0;

    const double areaDiffThresh = 5;        //目前统计的,最大的面积差2.58%
    const double perimeterDiffThresh =7.25; //目前统计的,最大的周长差5.65%
    const double sideDiffThresh = 10;       //目前统计的,最大的边长差7.3%
    const double avgDiffThresh = 5.0;       //三个差异比值的加权平均要求小于5.0;

    double avdDiffRatio = (areaDiffRatio+perimeterDiffRatio+sideDiffRatio)/3.0;

    //计算出的轮廓周长是半径的2*pi倍数
    if( (areaDiffRatio <areaDiffThresh)
        && (perimeterDiffRatio <perimeterDiffThresh)
        && (sideDiffRatio <sideDiffThresh)
        &&(avdDiffRatio<avgDiffThresh)
        && (r>minRadius) )
    {
        isCircle = TRUE;
    }

    return isCircle;

}
Major_Tom_F 2017-11-21
  • 打赏
  • 举报
回复
引用 3 楼 worldy 的回复:
在图片检测之前,做一些预处理很关键,必须先做预处理,比如黑白化、滤波等
嗯,可是我做了预处理,圆检测时我还是用霍夫圆检测,方法的参数还是不方便改变啊?请赐教,非常感谢。
worldy 2017-11-21
  • 打赏
  • 举报
回复
在图片检测之前,做一些预处理很关键,必须先做预处理,比如黑白化、滤波等
Major_Tom_F 2017-11-21
  • 打赏
  • 举报
回复
感谢赵4老师!那请问关于图片中圆的检测问题您可以提示一下吗?我一张拍摄的图片中有很多圆,我用霍夫圆检测方法,一直要调整参数才能得到比较好的结果,但是换个图片就不行,参数不好控制,怎么样可以有一套比较适用的方法啊?opencv中检测圆就只能用这个方法吗?还请赵老师赐教!非常感谢!
赵4老师 2017-11-21
  • 打赏
  • 举报
回复
识别印刷体数字字母不是OCR的事儿吗?
VB实现OCR文字识别
原理: 利用微软OCR控件, 只需要不到10行代码就能够实现自已的OCR文字识别软件.
1. 添加控件,需要安装office2003, 没有安装office2003的可以从别人机子上拷贝相关文件,注册regsvr32.exe mdivwctl.dll,
控件一般在这个目录下:C:\Program Files\Common Files\Microsoft Shared\MODI\11.0, 只需要相关的几个文件就可以了, 此文件夹全部文件大概在21M左右.
工程->部件->添加这个控件:Microsoft Office Document Imaging 11.0 Type Library

2.在按钮的Click事件里:
    Dim strLayoutInfo As String, strLPN As String

     '初始化并加载文档
    Set miDoc = CreateObject("MODI.Document")            '创建对象
    miDoc.Create "D:\未命名.tif"                         '加载图片文件(必须是黑白二值图)

    Screen.MousePointer = vbHourglass                    '设置光标忙
    '识别
    miDoc.Images(0).OCR miLANG_CHINESE_SIMPLIFIED, True, True '有用的就此一句,识别为中文简体

    Set modiLayout = miDoc.Images(0).Layout              '读出数据
    strLayoutInfo = _
        "Language: " & modiLayout.Language & vbCrLf & _
        "Number of characters: " & modiLayout.NumChars & vbCrLf & _
        "Number of fonts: " & modiLayout.NumFonts & vbCrLf & _
        "Number of words: " & modiLayout.NumWords & vbCrLf & _
        "Beginning of text: " & Left(modiLayout.Text, 50) & vbCrLf & _
        "First word of text: " & modiLayout.Words(0).Text
    MsgBox strLayoutInfo, vbInformation + vbOKOnly, "Layout Information"
    Set modiLayout = Nothing
    Set miDoc = Nothing
    Screen.MousePointer = vbDefault

3. OK了, 是不是很简单

    本课程分享对由中国开发者提供的OpenCV条形码识别模块的原理和代码精讲。该模块借鉴“目标识别”领域先进理念,采用“定位-识别”二段模式,有效提高了自然环境下条码识别的准确率并保持了C++代码的高速度,相比较常用的zxing和zbar在准确率和识别速度上均有较大优势。更难得可贵的是在代码的实现过程中能够注意细节,在诸如“循环测试确定参数数值”“积分图的使用”“倾斜矩形纠偏”等处,均提供了思路清晰、弹性高的优质代码。作为一套通过了OpenCV官方的代码检验、解决一个常用领域内具体问题的模块,对于图像处理学习来说是难得可贵的。    逐条进行代码解读繁琐且低效,个人认为,在图像处理领域,能够运行和修改观察的代码对于学习研究至关重要。在理论剖析部分,也是由应用引导原理。同时做好知识的迁移和代码的复用工作。在这个过程中,创建针对性的实验非常重要。 课程内容分为4个部分:一是基本配置,包括· 条形码识别模块的安装使用 (cmake配置和OpenCV编译);· 构建用于测试和代码阅读的环境;· 模块对官方数据集的测试;二是条码定位,将详细讲解思路、原理和实现知识迁移部分将简单说一下在毛发识别上的迁移:三是条码识别,该部分内容会首先梳理框架,而后具体进行分析讲解    此外,我们将结合例子,将OpenCV的基础功能,包括积分图像、形态学变化、联通区域、透视变化等进行复习,加深理解。 

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧