基于C语言的字符切割方法

最近在用主控STM32H743与摄像头MT9V034做数字识别,今天刚解决数字识别中的字符切割。效果能用,但还需完善。
原理:主要用了投影法,先进行垂直投影,找出多个字符的左右边框,再对每个字符单独水平投影,捕获该字符的上下边框。原理很简单,下面是程序流程图:
基于C语言的字符切割方法_第1张图片
下面是程序源码:

typedef struct{
     
	uint16_t UpLine;
	uint16_t DownLine;
	uint16_t LeftLine;
	uint16_t RightLine;
}CharPosInfTypeDef; 

typedef struct{
     
	uint16_t VerHisGram[IMAGEW];  // 垂直方向投影
	uint16_t HorHisGram[IMAGEH];  // 水平方向投影
	uint16_t VerStartIndex;
	uint16_t VerEndIndex;
	uint8_t  VerFlag;  	//进入字符区标志位
	uint16_t HorStartIndex;
	uint16_t HorEndIndex;
	uint8_t  HorFlag; 
	uint16_t SumChar;
	CharPosInfTypeDef X_PosInf[50];
  CharPosInfTypeDef CharPosInf[100];   //字符信息
	uint8_t *Pro_Pixels;          // 框中字符区域的像素
}NumberSegTypeDef2;
/**
  * 函数功能: 分割字符 
  * 输入参数: 1.图像像素 2.图像高 3.图像宽
  * 返 回 值: 边框信息
  * 说    明:无
  *           
  */
CharPosInfTypeDef* SegmentionChar2(uint8_t *pixels,int height,int width)
{
     
	
	uint8_t HorIndex=0,VerIndex=0,i=0;
	/*获取垂直方向白色像素直方图*/
step1:	
	for(uint16_t y=0;y<height;y++){
     		
		for(uint16_t x=0;x<width;x++){
     			
			if(pixels[y*width+x]==0xff){
     				
				NumberSeg.VerHisGram[x]++;
				
			}
		}
	}
	
	//VerFlag=0:空白区 VerFlag=1:字符区
  /*从垂直投影直方图中左右切割字符,获取字符左右边框*/  		
	for(uint16_t x=0;x<width;x++){
       
    if(NumberSeg.VerHisGram[x]!=0&&NumberSeg.VerFlag==0){
           //进入字符区
			NumberSeg.VerFlag=1;
			NumberSeg.VerStartIndex=x;
				
		}    
    else if(NumberSeg.VerHisGram[x]==0&&NumberSeg.VerFlag==1){
      //退出字符区
		  NumberSeg.VerEndIndex=x;
			NumberSeg.VerFlag=0;
      NumberSeg.X_PosInf[VerIndex].LeftLine=NumberSeg.VerStartIndex;
      NumberSeg.X_PosInf[VerIndex++].RightLine=NumberSeg.VerEndIndex;				      				
		}			      			
	}
step2:
	/*垂直投影后再统计水平方向白色像素直方图*/
  for(uint16_t y=0;y<height;y++){
     
		for(uint16_t x=NumberSeg.X_PosInf[HorIndex].LeftLine;x<NumberSeg.X_PosInf[HorIndex].RightLine;x++){
     
			if(pixels[y*width+x]==0xff){
     				
				NumberSeg.HorHisGram[y]++;			
			}			
   					
		}
	}	
  /*从水平投影直方图中上下切割字符,获取字符上下边框*/  		
	for(uint16_t y=0;y<height;y++){
     
		if(NumberSeg.HorHisGram[y]!=0&&NumberSeg.HorFlag==0){
     
			NumberSeg.HorFlag=1;
			NumberSeg.HorStartIndex=y;
				
		}
    else if(NumberSeg.HorHisGram[y]==0&&NumberSeg.HorFlag==1){
     
		  NumberSeg.HorEndIndex=y;
			NumberSeg.HorFlag=0;	
      NumberSeg.CharPosInf[i].LeftLine=NumberSeg.X_PosInf[HorIndex].LeftLine;
      NumberSeg.CharPosInf[i].RightLine=NumberSeg.X_PosInf[HorIndex].RightLine;
			NumberSeg.CharPosInf[i].UpLine=NumberSeg.HorStartIndex;
			NumberSeg.CharPosInf[i++].DownLine=NumberSeg.HorEndIndex;
		}

	}
step3:
  if(HorIndex==VerIndex){
     
    NumberSeg.SumChar=i;		
		return NumberSeg.CharPosInf;
	}		
  else{
     
		HorIndex++;
		memset(NumberSeg.HorHisGram,0,sizeof(NumberSeg.HorHisGram));
		goto step2; 
	}
}	


返回的指针是指向存储字符位置信息的数组地址。

你可能感兴趣的:(图像处理)