【数图大作业】基于模板匹配的文字识别(二)(文字行列分割)

简介: 【数图大作业】基于模板匹配的文字识别(二)(文字行列分割)

行分割


任务:


确定每行文字的开始行和结束行的位置。


步骤:


先将源图像进行二值化反色得到黑底白字的反色图,从反色图像第一行开始,判断反色图像中每行是否出现了白点,即原图中该行是否存在黑点,如果存在则表明该行存在汉字。


再次扫描,从第一行开始到倒数第二行,判断此行与下一行反色后白点总数是否满足一定条件。如果此行没有白点而下一行白点总数不为0,则下一行是汉字的上边界;如果此行白点总数不为0而下一行没有白点,则此行是汉字的下边界。


流程图:



代码:


int CVICALLBACK rowSplit (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
  Point point;
  PixelValue grayLevel;
  // 每行文字上界和下界的数目
  int topm=0, botm=0; 
  // 获取输入图像的宽高
  imaqGetImageSize (srcImage, &width, &height); 
  // 每行(反色后)白点的数目
  int *pt = calloc(height, sizeof(int)); 
  switch (event)
  {
  case EVENT_COMMIT:
  // 出现(反色后)白色像素则确定边界 
  for(int h = 0; h < height; h++)
  {   for(int w = 0; w < width; w++)
      {   point.x = w;
    point.y = h;
    imaqGetPixel(binImage, point, &grayLevel);
    if(grayLevel.grayscale == 255.0)
      *(pt + h) = *(pt + h) + 1;
         }
  }
  // 记录每行文字上界和下界
  for(int h = 0; h < height - 1; h++)
  {   
    if(*(pt + h) == 0 & *(pt + h + 1) > 0) 
    {
    topRow[topm++] = h; 
    num_row = num_row + 1; 
    }
    if(*(pt + h) > 0 & *(pt + h + 1) == 0) 
    bottomRow[botm++] = h; 
  }
  // 记录行分割后每行文字的高度
  for(int topm = 0; topm < num_row; topm++)
    _height[topm] = bottomRow[topm] - topRow[topm]; 
  break;
  }
  return 0;
}


列分割


任务:


确定每个文字的开始列和结束列的位置。


步骤:


在行分割的基础上,先进行行扫描,然后进行列扫描,判断一行汉字里的每一列是否出现了白点,即原图中该列是否存在黑点,如果存在则表明该列存在汉字。


再次扫描,从每一行的第一列开始扫描到倒数第二列,判断此列与下一列反色后白点总数是否满足一定条件。如果此列没有白点而下一列白点总数不为0,则下一列是字的左边界;如果此列白点总数不为0而下一列没有白点,则此列是字的右边界。


代码:


for(h = 0; h < num_row; h++)
{
  i = 0, j = 0;
  // 出现(反色后)白色像素则确定边界 
  for(int x = 0; x < width; x++)
  {   
  for(int y = topRow[h]; y <= bottonRow[h]; y++)
  {   
    point.x = x;
    point.y = y;
    imaqGetPixel(binImage, point, &grayLevel);
    if(grayLevel.grayscale == 255.0) 
     *(pt + h * width + x) = *(pt + h * width + x) + 1; 
    }
  }
  // 记录每行文字左界和右界
  for(int x = 0; x < width - 1; x++)
  {   
    if(*(pt + h * width + x) == 0 & *(pt + h * width + x + 1) > 0)   
      leftMargin[h][i++] = x;
    if(*(pt + h * width + x) > 0 & *(pt + h * width + x + 1) == 0)    
    {
    rightMargin[h][j++] = x; 
    num_col[h] = num_col[h] + 1;
    }
  }
  }


列分割的原理和行分割基本一致,但是有可能出现误分割的情况(字中间存在空隙,即某行文字中某列反色后白色像素点数目为0)。


左右结构字体防误切割


任务:


识别出类似于“八”和“川”这种可能会被误分割成两部分或三部分的字。


步骤:


1.对于“八”型的字:

如果列分割的时候被分成第h行的第i个和第i+1个字,则根据第i个和第i+1个字的左右边界坐标值是否满足一定条件,来判断是否需要合并。







通过分析字形,确定判断条件:

(1) 第i+1个字的左边界与第i个字的右边界相距小于文字高度的三分之一;

(2) 第i+1个字的右边界与第i个字的左边界相距小于文字高度;

(3) 第i+2个字的右边界与第i个字的左边界相距大于文字高度。

以上三个条件都满足,则为“八”型的字。


对于“八”型的字,将初次列分割得到第i个和第i+1个字的左右边界合并,并将该行字的个数减去1。


2.对于“川”型的字:

如果列分割的时候被分成第h行的第i个、第i+1个字和第i+2个字,则根据第i个、第i+1个字和第i+2个字的左右边界坐标值是否满足一定条件,来判断是否需要合并。




通过分析字形,确定判断条件:

(1) 第i+2个字的左边界与第i+1个字的右边界相距小于文字高度的三分之一;

(2) 第i+1个字的左边界与第i个字的右边界相距小于文字高度的三分之一;

(3) 第i+2个字的右边界与第i个字的左边界相距小于文字高度;

(4) 第i+3个字的右边界与第i个字的左边界相距大于文字高度。

以上条件(1)和(2)满足任意一条,同时满足条件(3)和(4),则为“川”型的字。


对于“川”型的字,将初次列分割得到第i个、第i+1个和第i+2个字的左右边界合并,并将该行字的个数减去2。


流程图:




代码:


for(i = 0; i < num_col[h]; i++)
{   
  // 判断是否为“八”字这类容易被误分割成两部分的字,并对此进行合并
  if((leftMargin[h][i+1] - rightMargin[h][i] <= _height[h]/3) && (rightMargin[h][i+1] - leftMargin[h][i] <= _height[h]) 
  && (rightMargin[h][i+2] - leftMargin[h][i] >= _height[h]))              
  {   
  for(g = i; g < num_col[h]; g++)
    rightMargin[h][g] = rightMargin[h][g+1]; 
  for(j = i + 1; j < num_col[h]; j++)
    leftMargin[h][j] = leftMargin[h][j+1]; 
    num_col[h] = num_col[h] - 1; 
  }
  // 判断是否为“川”字这类容易被误分割成三部分的字,并对此进行合并  
  if(((leftMargin[h][i+2] - rightMargin[h][i+1] <= _height[h]/3) || (leftMargin[h][i+1] - rightMargin[h][i] <= _height[h]/3))
  && (rightMargin[h][i+2] - leftMargin[h][i] <= _height[h]) && (rightMargin[h][i+3] - leftMargin[h][i] >= _height[h]))
  {   
  for(g = i;g < num_col[h]; g++)
    rightMargin[h][g] = rightMargin[h][g+2]; 
  for(j = i + 1; j < num_col[h]; j++)
    leftMargin[h][j] = leftMargin[h][j+2]; 
    num_col[h] = num_col[h] - 2; 
  }
}


分割效果



相关文章
|
7月前
|
机器学习/深度学习 文字识别 Shell
高效率办公PDF批量处理:批量OCR识别PDF区域文字内容,用PDF内容批量改名或导出表格的货物运单应用案例
针对铁路货运物流单存档需求,本项目基于WPF与飞桨OCR技术,实现批量图片多区域文字识别与自动重命名。用户可自定义识别区域,系统提取关键信息(如车号、批次号)并生成规范文件名,提升档案管理效率与检索准确性,支持PDF及图像文件处理。
1046 48
|
7月前
|
人工智能 文字识别 API
医疗票据OCR技术演进:从模板匹配到智能理解的突破
医疗票据OCR正从传统模板匹配迈向智能理解新阶段。快瞳科技融合OCR与医疗知识图谱,实现高精度、自适应识别,显著提升效率与准确性,推动医疗数字化智能化升级。
531 3
|
编解码 文字识别 自然语言处理
如何使用OCR技术批量识别图片中的文字并重命名文件,OCR 技术批量识别图片中的文字可能出现的错误
### 简介 【批量识别图片内容重命名】工具可批量识别图片中的文字并重命名文件,方便高效处理大量图片。然而,OCR 技术面临字符识别错误(如形近字混淆、生僻字识别不佳)、格式错误(段落错乱、换行问题)和语义理解错误等挑战。为提高准确性,建议提升图片质量、选择合适的 OCR 软件及参数,并结合自动校对与人工审核,确保最终文本的正确性和完整性。
2306 12
如何使用OCR技术批量识别图片中的文字并重命名文件,OCR 技术批量识别图片中的文字可能出现的错误
|
文字识别 UED Python
对双栏 | 单双栏混合 | 图表文字混合的复杂布局的图片OCR识别(对布局复杂的整个pdf进行OCR识别)
这个故事告诉我们要多尝试不同的库和引擎,尤其是需求比较偏门或者少见的时候。同一个方向不同的库所擅长的领域是不一样的。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
机器学习/深度学习 文字识别 前端开发
基于 Spring Boot 3.3 + OCR 实现图片转文字功能
【8月更文挑战第30天】在当今数字化信息时代,图像中的文字信息越来越重要。无论是文档扫描、名片识别,还是车辆牌照识别,OCR(Optical Character Recognition,光学字符识别)技术都发挥着关键作用。本文将围绕如何使用Spring Boot 3.3结合OCR技术,实现图片转文字的功能,分享工作学习中的技术干货。
2020 2
|
机器学习/深度学习 人工智能 文字识别
轻松识别文字,这款Python OCR库支持超过80种语言
轻松识别文字,这款Python OCR库支持超过80种语言
1312 2
|
文字识别
印刷文字识别使用问题之影响印刷体文字识别率包括哪些
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
人工智能 文字识别 开发工具
印刷文字识别使用问题之是否支持识别并返回文字在图片中的位置信息
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
文字识别
【提取翻译竖排文字日文图片的软件】竖排的日语图片文字识别翻译,竖排的日语图片文字如何识别,竖排日语图片识别后转横排,竖排的日语识别比较友好的方法
这款软件专攻竖排日语图片文字识别,支持自动横排转换,能准确提取左右排版文字,并翻译成中文。用户可从百度网盘或腾讯云盘下载。功能包括图片打开、拖拽识别、截屏拾取、顺序识别、文字导出、快捷搜索及窗体操作。识别时注意保持文字等高以减少误差。附带视频教程(BV1vW4y1p7st)帮助快速上手。
3659 1
|
机器学习/深度学习 人工智能 文字识别
文本,文字扫描01,OCR文本识别技术展示,一个安卓App,一个简单的设计,文字识别可以应用于人工智能,机器学习,车牌识别,身份证识别,银行卡识别,PaddleOCR+SpringBoot+Andr
文本,文字扫描01,OCR文本识别技术展示,一个安卓App,一个简单的设计,文字识别可以应用于人工智能,机器学习,车牌识别,身份证识别,银行卡识别,PaddleOCR+SpringBoot+Andr

热门文章

最新文章