• 前面提到了将验证码上的字符分割成一个单独的字符图片并且保存,但是扣下来的字符串可能会有倾斜的现象,因为现在很多网页验证码为了防止破解都对字符进行了一定的扭曲和旋转,即使是同一个网站的验证码,每个相同的...
    前面提到了将验证码上的字符分割成一个单独的字符图片并且保存,但是扣下来的字符串可能会有倾斜的现象,因为现在很多网页验证码为了防止破解都对字符进行了一定的扭曲和旋转,即使是同一个网站的验证码,每个相同的字符很有可能都是不一样的,所以为了提高识别的正确率,在这里最好能让每次进行训练的字符能够保持同一个角度。所以首先需要做的就是旋转倾斜。
    

    一、旋转倾斜

    旋转倾斜的目的就是要提高识别的正确率,如果字符‘A’的模板是标准的,让一个横着的‘A’去训练肯定得不到正确的结果。不过怎么旋转呢?想要将每个字符都旋转到印刷体的角度那是很难的,也是不必要的,在这里采用的思想就是每次都旋转成为“最瘦的”。每次分割出来一个字符不管是横着的还是竖着的,都可以回到“最瘦”的角度。具体做法就是利用OpenCV的旋转函数.

    [cpp] view plain copy
    1. cv::Mat M = cv::getRotationMatrix2D(center, angle, scale);  

    getRotationMatrix2D这个函数所做的就是计算旋转矩阵,熟悉计算机图形学的都知道,图形在做各种变换的时候都是在原有的矩阵上乘以变换矩阵。这里center是CvPoint2D32f类型的结构体,其有两个float类型的变量分别表示要旋转的图像的宽和高,angle就是要旋转的角度,scale是旋转后的缩放系数。得到变换矩阵之后就可以进行旋转操作了

    [cpp] view plain copy
    1. warpAffine(m_Mat,rotate_mat, M,cvSize(getWidth(),getHeight()),INTER_LINEAR,BORDER_CONSTANT,cvScalar(WHITE) );  

    warpAffine函数就是进行旋转操作。

    鉴于大部分验证码的旋转都不是特别夸张,所以处理时我让字符从旋转的范围定在顺时针-15度到15度,每次旋转一度,然后计算最左边第一个黑色像素到最右边第一个黑色像素的距离,取距离最小的角度最终让字符旋转那个角度。


    可以看到分割出来的字符和原始的还是有点不太一样,由于测试用的验证码倾斜的并不明显,所以这里调整的也不是很明显。

    二、归一化

    由于验证码大小不一,图片上又大量背景像素,因此在进行最后一步识别的时候,还应该将验证码的大小缩放到固定的大小。在这里我是先得到字符像素的最小外包矩形,这样可以先把没有用的白色背景像素干扰取消掉。接下来就是将所有的字符都统一缩放到16*16的大小,这样最终得到的经过预处理的标准字符就可以开始训练识别了。

    展开全文
  • 字符归一化

    2015-11-08 15:22:14
    扫描图像中的数字字符可能大小不一,而后续ANN的训练和识别都需要同一尺寸的字符对象,因此有必要对字符进行归一化处理,使其具有相同的尺寸...功能: 字符归一化 参数: img:有待归一化的图像 dst:归一化后目标图像

          扫描图像中的数字字符可能大小不一,而后续ANN的训练和识别都需要同一尺寸的字符对象,因此有必要对字符进行归一化处理,使其具有相同的尺寸。

    代码如下:

    /****************************************************************
    功能:    字符归一化
    参数:    img:有待归一化的图像
              dst:归一化后目标图像
    	  int nTargWidth:归一化的目标宽度
    	  int nTargHeight:归一化的目标高度
    	  RECT lpRect:等待缩放的矩形框
    注    :  只能处理二值图像
    返回值:  缩放后的矩形框
    ***************************************************************/
    RECT  Ctry::RgnZoom(IplImage* img, IplImage* dst, int nTargWidth, int nTargHeight, RECT lpRect)
    {
    	RECT retRT;   //缩放后的区域矩形
    	double dXScale;   //水平方向缩放因子
    	double dYScale;   //竖直方法缩放因子
    
        //确定缩放系数
    	dXScale = (double)nTargWidth / (lpRect.right - lpRect.left + 1);
    	dYScale = (double)nTargHeight / (lpRect.bottom - lpRect.top + 1);
    
    	int nSrc_i, nSrc_j;   //映射源坐标
    
    	retRT.top = lpRect.top;
    	retRT.bottom = retRT.top + nTargHeight;
    	retRT.left = lpRect.left;
    	retRT.right = retRT.left + nTargWidth;
    
       //对图像的区域矩形进行逐行扫描,通过像素映射完成缩放
    	for (int  i = retRT.top; i < retRT.bottom; i++)
    	{
    		for (int j = retRT.left; j < retRT.right; j++)
    		{
    			//计算映射的源坐标(最邻近插值)
    			nSrc_i = retRT.top + int((i - retRT.top) / dYScale);
    			nSrc_j = retRT.left + int((j - retRT.left) / dXScale);
    
    			//对应像素赋值
    			double pixel = cvGetReal2D(img, nSrc_i, nSrc_j);
    			cvSetReal2D(dst, i, j, pixel);
    		}
    	}
    	return retRT;
    }
    在上一篇博客文章《中字符分割二》中得到矩形框,然后调用此函数,完整代码如下:

    void Ctry::ObjectNorm()
    {
    	// TODO:  在此添加命令处理程序代码    
    	IplImage* img = cvLoadImage("C:\\Users\\Administrator\\Desktop\\dst.jpg", -1);
    	vector<RECT>  vecRECTBig;
    	vecRECTBig = ObjectSegment(img, 260);//该函数见上一篇博客《字符分割二》
    
    	IplImage *norm = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
    	for (int i = 0; i < norm->height; i++)
    	{
    		for (int j = 0; j < norm->width; j++)
    		{
    			cvSetReal2D(norm, i, j, 255);
    		}
    	}
    	for (int i = 0; i < vecRECTBig.size(); i++)
    	{
    		RECT rt = vecRECTBig[i];    //取得一个矩形轮廓
    		vecRECTBig[i] = RgnZoom(img, norm, 60, 100, rt);
    
    		int x = vecRECTBig[i].left - 1;
    		int y = vecRECTBig[i].top - 1;
    		int x1 = vecRECTBig[i].right + 1;
    		int y1 = vecRECTBig[i].bottom + 1;
    		CvPoint pt1(x, y);
    		CvPoint pt2(x1, y1);
    		cvRectangle(norm, pt1, pt2, CV_RGB(255, 0, 0), 1);
    	}
    	cvSaveImage("C:\\Users\\Administrator\\Desktop\\norm.jpg", norm);
    }


    效果图:

    原图:



    展开全文
  • matlab图像处理为什么要归一化和如何归一化, 一、为什么归一化 1.  基本上归一化思想是利用图像的不变矩寻找一组参数使其能够消除其他变换函数对图像变换的影响。也就是转换成唯一的标准形式以抵抗仿射变换  图像...

    matlab图像处理为什么要归一化和如何归一化,
    一、为什么归一化
    1.
     基本上归一化思想是利用图像的不变矩寻找一组参数使其能够消除其他变换函数对图像变换的影响。也就是转换成唯一的标准形式以抵抗仿射变换
      图像归一化使得图像可以抵抗几何变换的攻击,它能够找出图像中的那些不变量,从而得知这些图像原本就是一样的或者一个系列的。
      因为我们这次的图片有好多都是一个系列的,所以老师把这个也作为我研究的一个方向。
      我们主要要通过归一化减小医学图片由于光线不均匀造成的干扰。
    2.matlab里图像数据有时候必须是浮点型才能处理,而图像数据本身是0-255的UNIT型数据所以需要归一化,转换到0-1之间。
    3.归一化是一种简化计算的方式,即将有量纲的表达式,经过变换,化为无量纲的表达式,成为纯量。 目的是为了:
    (1).避免具有不同物理意义和量纲的输入变量不能平等使用
    (2).bp中常采用sigmoid函数作为转移函数,归一化能够防止净输入绝对值过大引起的神经元输出饱和现象
    (3).保证输出数据中数值小的不被吞食
    3.神经网络中归一化的原因
    归一化是为了加快训练网络的收敛性,可以不进行归一化处理
    归一化的具体作用是归纳统一样本的统计分布性。归一化在0-1之间是统计的概率分布,归一化在-1–+1之间是统计的坐标分布。归一化有同一、统一和合一的意思。无论是为了建模还是为了计算,首先基本度量单位要同一,神经网络是以样本在事件中的统计分别几率来进行训练(概率计算)和预测的,归一化是同一在0-1之间的统计概率分布; 当所有样本的输入信号都为正值时,与第一隐含层神经元相连的权值只能同时增加或减小,从而导致学习速度很慢。为了避免出现这种情况,加快网络学习速度,可以对输入信号进行归一化,使得所有样本的输入信号其均值接近于0或与其均方差相比很小。
    归一化是因为sigmoid函数的取值是0到1之间的,网络最后一个节点的输出也是如此,所以经常要对样本的输出归一化处理。所以这样做分类的问题时用[0.9 0.1 0.1]就要比用[1 0 0]要好。
    但是归一化处理并不总是合适的,根据输出值的分布情况,标准化等其它统计变换方法有时可能更好。

    二、如何归一化
    matlab中的归一化处理有三种方法

    1. premnmx、postmnmx、tramnmx
    2. restd、poststd、trastd
    3. 自己编程
      (1)线性函数转换,表达式如下:
      y=(x-MinValue)/(MaxValue-MinValue)
      说明:x、y分别为转换前、后的值,MaxValue、MinValue分别为样本的最大值和最小值。
      (2)对数函数转换,表达式如下:
      y=log10(x)
      说明:以10为底的对数函数转换。
      (3)反余切函数转换,表达式如下:
      y=atan(x)*2/PI
      (4)一个归一化代码.
      I=double(I);
      maxvalue=max(max(I)’);%max在把矩阵每列的最大值找到,并组成一个单行的数组,转置一下就会行转换为列,再max就求一个最大的值,如果不转置,只能求出每列的最大值。
      f = 1 - I/maxvalue; %为什么要用1去减?
      Image1=f;
    展开全文
  • 字符归一化是光学字符识别中的一个子步骤,给定一个字符区域,我们要做的就是将该区域内的字符归一化到一个标准模板大小,然后才能提取特征,并送给分类器做具体的识别。好的归一化算法可以尽量提高后续特征提取在同...
    本文介绍3种基本的字符形状归一化算法(Character Shape Normalization)。字符归一化是光学字符识别中的一个子步骤,给定一个字符区域,我们要做的就是将该区域内的字符归一化到一个标准模板大小,然后才能提取特征,并送给分类器做具体的识别。好的归一化算法可以尽量提高后续特征提取在同一类内的一致性。
    

    先来看一个例子,假如上帝拥有一个完美的字符归一化算法,那么他将可以做到如下所示的效果:

    图1,完美的归一化:左边为原始字符区域,右边为归一化后的结果。

    如果说我们能做到上述结果,那么也就无需再做特征提取,也无需再做训练,而只需简单的模板匹配即可得到100%准确的分类结果。可以看到,上述算法的能力在于:

    1. 归一化到标准模板大小

    2. 倾斜校正

    3. 笔画宽度归一化

    4. 字形归一化


    可惜的是,今天介绍的几种常见算法仅能保证第1点的实现,而2,3则只能实现部分。至于4,就让后续的特征提取去弥补吧。言归正传,3个算法分别是:线性归一化算法,基于图像矩的归一化以及非线性归一化算法。


    按惯例,3个算法的标准c实现可在:

    https://github.com/UnilVision/visionbase/tree/master/ocr/baseline/normalization找到。希望对大家有所帮助。


    线性归一化:线性归一化算法就是一个标准的线性采样过程,采用线性插值获得最终的图像结果。在我们的实现中,使用反向计算的方式:

    其中为长和宽的比值。

    对应代码中的函数为:

    1. void backward_linear(unsigned char* src, int src_wid, int src_hei, int src_widstep,  
    2.                      CHARECT_t* region,  
    3.                      unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep,  
    4.                      int ratio_preserve_func);  
    void backward_linear(unsigned char* src, int src_wid, int src_hei, int src_widstep,
    					 CHARECT_t* region,
    					 unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep,
    					 int ratio_preserve_func);
    

    图像矩归一化: 我们可以通过图像矩来预先校正字符的倾斜度,并通过矩来获得字体的实际大小[w1, h1]及中心位置[xc, yc]。归一化的原始区域被修改为

    [xc-w1/2, xc+w1/2, yc-h1/2, yc+h1/2]。其计算方法为:


    是一个经验值,一般取4。


    其中图像矩的计算方法:



    在找到新的区域[xc-w1/2, xc+w1/2, yc-h1/2, yc+h1/2]后,后续即调用线性归一化算法即可。对应代码中的实现为:

    1. void backward_moment(unsigned char* src, int src_wid, int src_hei, int src_widstep,  
    2.                      CHARECT_t* region,  
    3.                      unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep,  
    4.                      int ratio_preserve_func);  
    void backward_moment(unsigned char* src, int src_wid, int src_hei, int src_widstep,
    					 CHARECT_t* region,
    					 unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep,
    					 int ratio_preserve_func);


    图像矩倾斜校正:利用图像矩,我们可以找到字符的倾斜角

    采样计算方式为:


    注意这里我们仅调整x的位置以保证图像的中心仍然处于原始的xc,yc。其实现对于:

    1. // slant correction   
    2. // Note>> (dst_wid, dst_hei) must equal to (region.width, region.height)   
    3. void backward_moment_slantcorrection(unsigned char* src, int src_wid, int src_hei, int src_widstep,  
    4.                      CHARECT_t* region,  
    5.                      unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep);  
    // slant correction
    // Note>> (dst_wid, dst_hei) must equal to (region.width, region.height)
    void backward_moment_slantcorrection(unsigned char* src, int src_wid, int src_hei, int src_widstep,
    				     CHARECT_t* region,
    				     unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep);
    

    通常倾斜校正会放在归一化之前,已获得更好的效果。


    非线性归一化:这里实现的是Jun Tsukumo在1988年提出的一个经典算法(原论文名称为Classification of Handprinted Chinese Characters Using Non-linear Normalization and Correlation Methods)。作者的思路是希望每一行,每一列的背景区域都可以平均分布。

    为此,他首先为每个像素在x,y方向分别定义了个概率密度函数:以及。这两个函数的计算方法是:

    如果(x,y)是一个属于字符区域的像素,那么都取一个极小值(在我们的实现中,这个值是0.001f,调整这个参数可以引起归一化后笔画的粗细变化)。

    如果(x,y)是背景区域像素,那么:



    其中分别是当前像素所处x方向背景像素的run-length和y方向的run-length。有了这两个密度函数,定义:



    这里px和py就是归一化后的投影直方图了,为了在归一化后的图像中让px和py平均分布,引入两个函数hx,hy:



    通过前向映射采样即可实现归一化操作:



    注意这里与前两个算法的不同之处,前向映射是将当前图像的某个像素映射到归一化的图像中。而反向映射则是将归一化的图像中的某个像素位置映射到原图像中。

    非线性归一化的实现对应:

    1. void forward_nonlinear_1d(unsigned char* src, int src_wid, int src_hei, int src_widstep,  
    2.                           CHARECT_t* region,  
    3.                           unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep,  
    4.                           int ratio_preserve_func);  
    void forward_nonlinear_1d(unsigned char* src, int src_wid, int src_hei, int src_widstep,
    						  CHARECT_t* region,
    						  unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep,
    						  int ratio_preserve_func);
    

    参考结果

    最后看下各个算法的结果:


    图2,参考结果。从左到右依次:1. 原始扣取的图像通过OpenCV的resize函数缩放。2. 线性归一化。3.基于矩的归一化。4.先倾斜校正再基于矩的归一化。5.非线性归一化。


    [原创文章,转载请注明出处:http://blog.csdn.net/unilvision/article/details/8624606]

    展开全文
  • 字符归一化是光学字符识别中的一个子步骤,给定一个字符区域,我们要做的就是将该区域内的字符归一化到一个标准模板大小,然后才能提取特征,并送给分类器做具体的识别。好的归一化算法可以尽量提高后续特征提取在同...

    本文介绍3种基本的字符形状归一化算法(Character Shape Normalization)。字符归一化是光学字符识别中的一个子步骤,给定一个字符区域,我们要做的就是将该区域内的字符归一化到一个标准模板大小,然后才能提取特征,并送给分类器做具体的识别。好的归一化算法可以尽量提高后续特征提取在同一类内的一致性。

    先来看一个例子,假如上帝拥有一个完美的字符归一化算法,那么他将可以做到如下所示的效果:

    图1,完美的归一化:左边为原始字符区域,右边为归一化后的结果。

    如果说我们能做到上述结果,那么也就无需再做特征提取,也无需再做训练,而只需简单的模板匹配即可得到100%准确的分类结果。可以看到,上述算法的能力在于:

    1. 归一化到标准模板大小

    2. 倾斜校正

    3. 笔画宽度归一化

    4. 字形归一化


    可惜的是,今天介绍的几种常见算法仅能保证第1点的实现,而2,3则只能实现部分。至于4,就让后续的特征提取去弥补吧。言归正传,3个算法分别是:线性归一化算法,基于图像矩的归一化以及非线性归一化算法。


    按惯例,3个算法的标准c实现可在:

    https://github.com/UnilVision/visionbase/tree/master/ocr/baseline/normalization找到。希望对大家有所帮助。


    线性归一化:线性归一化算法就是一个标准的线性采样过程,采用线性插值获得最终的图像结果。在我们的实现中,使用反向计算的方式:

    其中为长和宽的比值。

    对应代码中的函数为:

    void backward_linear(unsigned char* src, int src_wid, int src_hei, int src_widstep,
    					 CHARECT_t* region,
    					 unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep,
    					 int ratio_preserve_func);
    

    图像矩归一化: 我们可以通过图像矩来预先校正字符的倾斜度,并通过矩来获得字体的实际大小[w1, h1]及中心位置[xc, yc]。归一化的原始区域被修改为

    [xc-w1/2, xc+w1/2, yc-h1/2, yc+h1/2]。其计算方法为:


    是一个经验值,一般取4。


    其中图像矩的计算方法:



    在找到新的区域[xc-w1/2, xc+w1/2, yc-h1/2, yc+h1/2]后,后续即调用线性归一化算法即可。对应代码中的实现为:

    void backward_moment(unsigned char* src, int src_wid, int src_hei, int src_widstep,
    					 CHARECT_t* region,
    					 unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep,
    					 int ratio_preserve_func);


    图像矩倾斜校正:利用图像矩,我们可以找到字符的倾斜角

    采样计算方式为:


    注意这里我们仅调整x的位置以保证图像的中心仍然处于原始的xc,yc。其实现对于:

    // slant correction
    // Note>> (dst_wid, dst_hei) must equal to (region.width, region.height)
    void backward_moment_slantcorrection(unsigned char* src, int src_wid, int src_hei, int src_widstep,
    				     CHARECT_t* region,
    				     unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep);
    

    通常倾斜校正会放在归一化之前,已获得更好的效果。


    非线性归一化:这里实现的是Jun Tsukumo在1988年提出的一个经典算法(原论文名称为Classification of Handprinted Chinese Characters Using Non-linear Normalization and Correlation Methods)。作者的思路是希望每一行,每一列的背景区域都可以平均分布。

    为此,他首先为每个像素在x,y方向分别定义了个概率密度函数:以及。这两个函数的计算方法是:

    如果(x,y)是一个属于字符区域的像素,那么都取一个极小值(在我们的实现中,这个值是0.001f,调整这个参数可以引起归一化后笔画的粗细变化)。

    如果(x,y)是背景区域像素,那么:



    其中分别是当前像素所处x方向背景像素的run-length和y方向的run-length。有了这两个密度函数,定义:



    这里px和py就是归一化后的投影直方图了,为了在归一化后的图像中让px和py平均分布,引入两个函数hx,hy:



    通过前向映射采样即可实现归一化操作:



    注意这里与前两个算法的不同之处,前向映射是将当前图像的某个像素映射到归一化的图像中。而反向映射则是将归一化的图像中的某个像素位置映射到原图像中。

    非线性归一化的实现对应:

    void forward_nonlinear_1d(unsigned char* src, int src_wid, int src_hei, int src_widstep,
    						  CHARECT_t* region,
    						  unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep,
    						  int ratio_preserve_func);
    

    参考结果

    最后看下各个算法的结果:


    图2,参考结果。从左到右依次:1. 原始扣取的图像通过OpenCV的resize函数缩放。2. 线性归一化。3.基于矩的归一化。4.先倾斜校正再基于矩的归一化。5.非线性归一化。


    [原创文章,转载请注明出处:http://blog.csdn.net/unilvision/article/details/8624606]




    展开全文
  • 本节介绍的数据归一化方法,包括图像坐标的平移和尺度缩放。 注意:归一化必须在实施DLT之前进行,而且是实质性的,一定不要视它为可有可无!!!之后再对结果进行适当的校正就能得到关于原坐标系的变换。(数据...
  • 这是本人写的有关bmp文件的关于车牌字符的代码,请多多指教!
  • 图像预处理第7步:标准归一化将分割出来的各个不同宽、高的数字字符宽、高统一 //图像预处理第7步:标准归一化 //将分割出来的各个不同宽、高的数字字符宽、高统一 void CChildView::OnImgprcStandarize() {...
  • 归一化定义与作用 归一化就是要把需要处理的数据经过处理后(通过某种算法)限制在你需要的一定范围内。首先归一化是为了后面数据处理的方便,其次是保证程序运行时收敛加快。归一化的具体作用是归纳统一样本的统计...
  • 图像处理开发资料、图像处理开发需求、图像处理接私活挣零花钱,可以搜索公众号"qxsf321",并关注! 图像处理开发资料、图像处理开发需求、图像处理接私活挣零花钱,可以搜索公众号"qxsf321",...
  • 归一化: 训练模型不会因为部分畸形数据而导致训练模型出现差错 批归一化: 每一层的激活值都进行归一化的过程 过拟合 解释:(在train的表现很好,在valid的表现不是很好)。 原因:参数过多,记住样本,不能泛化。...
  • 如题,无非就是把多组数据按照一定的格式转化,翻译成标准化应该更恰当,或者说归一化只是标准化的方法其中之一。其中最近,使用把图像像素值收缩[0,1]区间,matlab有现成函数,mapminmax。整个过程无非就是老区间...
  • 当不同的特征成列在一起的时候,由于特征本身表达方式的原因而导致在绝对数值上的小数据被大数据“吃掉”的情况,这个时候我们需要做的就是对抽取出来的features vector进行归一化处理,以保证每个特征被分类器平等...
  • 归一化方法总结

    2018-12-03 13:55:54
    1、线性函数归一化(Min-Max scaling),线性函数将原始数据线性化的方法转换到[0 1]的范围,归一化公式如下: 该方法实现对原始数据的等比例缩放,其中Xnorm为归一化后的数据,X为原始数据,Xmax、Xmin分别为原始...
  • 环境:vs2010+opencv 2.4.9功能:实现图片的归一化和翻转用途:在训练数据时,使图片统一化尺寸数据:yale大学的人脸数据库.链接(免积分):...
  • Opencv C++下的Mat归一化

    2017-08-25 15:39:15
    Opencv C++下的Mat归一化 void Mat_L2_mormal(cv::Mat &image) { //mat*mat, cv::Mat out; out=(image) .mul (image); float sum=0.0; for (int i=0;i;i++){ sum=sqrt(cv::sum(o
  • 在喂给机器学习模型的数据中,对数据要进行归一化处理。 为什么要进行归一化处理,下面从寻找最优解这个角度给出自己的看法。 例子 假定为预测房价的例子,自变量为面积,房间数两个,因变量为房价。 那么可以...
1 2 3 4 5 ... 20
收藏数 6,518
精华内容 2,607