重庆市网站建设网店美工考试题目
重庆市网站建设,网店美工考试题目,湖北省建设厅的网站,钱包网站建设pdf文本分为两种#xff0c;一种是标准的pdf格式的文本#xff0c;这种无需利用ocr识别#xff0c;另外一种就是图片文本#xff0c;这种需要进行ocr的识别。
OCR 识别文本和文本区域
ppstructure是paddleocr里面的一个子库#xff0c;可以识别文档的页眉页脚、正文、标…pdf文本分为两种一种是标准的pdf格式的文本这种无需利用ocr识别另外一种就是图片文本这种需要进行ocr的识别。
OCR 识别文本和文本区域
ppstructure是paddleocr里面的一个子库可以识别文档的页眉页脚、正文、标题等等。输出是json格式的数据里面有文本type、文本内容、文本块区域bbox和每一行的文本区域text_region等信息。
版面恢复
agument-xy-cut
一个实现 code 其实这一步针对的是比较复杂的排版比如表格类型的。 一般的论文什么的排版都比较固定单栏横版和双栏横版基本上一句 sorted_boxes sorted(res, keylambda x: (x[bbox][1], x[bbox][0]))就可以解决了。一般的文本用不上 agument-xy-cut。我用 agument-xy-cut 来排版属于是杀鸡用了牛刀。
虽然ppstructure识别出来的文本块是无序的但是它给出了文本块区域bbox和每一行的文本区域text_region等信息我们可以利用文本块区域bbox的信息来对文本块排序。 agument-xy-cut就是一种很好的算法。可以识别单栏、双栏、表格甚至更复杂的排版。 如果是一般的单栏横版的文章我们可以跳过这一步因为直接利用每一行的文本区域text_region进行下一步即可。
整合自然段
主要是整合自然段因为ppstructure识别出来的文本有两个层次第一层次是文本块区域以bbox划分利用上面的 agument-xy-cut算法可以进行排序。还有文本块区域内部的每一行的文本这里我们要做的是将每一行的文本整合为自然段。 这里提供一种算法code 不是特别精确不过大概是能利用每一行的文本区域text_region对文本进行自然段的整合。
# 合并段落-横排-自然段from .merge_line import MergeLineclass MergePara(MergeLine):def __init__(self):super().__init__()self.tbpuName 多行-自然段self.mllhLine 1.8 # 最大段间距def isSameColumn(self, A, B): # 两个文块属于同一栏时返回 True# 获取A、B行高if lineHeight in A: # 已记录Ah A[lineHeight]else: # 未记录则写入记录Ah A[lineHeight] A[box][3][1] - A[box][0][1]A[lineCount] 1 # 段落的行数Bh B[box][3][1] - B[box][0][1]if abs(Bh - Ah) Ah * self.mllhH:return False # AB行高不符# 行高相符判断垂直投影是否重叠ax1, ax2 A[box][0][0], A[box][1][0]bx1, bx2 B[box][0][0], B[box][1][0]if ax2 bx1 or ax1 bx2:return Falsereturn True # AB垂直投影重叠def isSamePara(self, A, B): # 两个文块属于同一段落时返回 Trueah A[lineHeight]# 判断垂直距离ly ah * self.mllhYlLine ah * self.mllhLinea, b A[box], B[box]ay, by a[3][1], b[0][1]if by ay - ly or by ay lLine:return False # 垂直距离过大# 判断水平距离lx ah * self.mllhXax, bx a[0][0], b[0][0]if A[lineCount] 1: # 首行允许缩进2格return ax - ah * 2.5 - lx bx ax lxelse:return abs(ax - bx) lxdef merge2line(self, textBlocks, i1, i2): # 合并2行ranges [(0x4E00, 0x9FFF), # 汉字(0x3040, 0x30FF), # 日文(0xAC00, 0xD7AF), # 韩文(0xFF01, 0xFF5E), # 全角字符]# 判断两端文字的结尾和开头是否属于汉藏语族# 汉藏语族行间无需分割符。印欧语族则两行之间需加空格。separator ta, tb textBlocks[i1][text][-1], textBlocks[i2][text][0]fa, fb False, Falsefor l, r in ranges:if l ord(ta) r:fa Trueif l ord(tb) r:fb Trueif fa and fb:separator # print(f【{ta}】与【{tb}】是汉字集。)# else:# print(f【{ta}】与【{tb}】是西文集。)self.merge2tb(textBlocks, i1, i2, separator)textBlocks[i1][lineCount] 1 # 行数1def mergePara(self, textBlocks):# 单行合并hList self.mergeLine(textBlocks)# 按左上角y排序hList.sort(keylambda tb: tb[box][0][1])# 遍历每个行寻找并合并属于同一段落的两个行listlen len(hList)resList []for i1 in range(listlen):tb1 hList[i1]if not tb1:continuenum 1 # 合并个数# 遍历后续文块for i2 in range(i1 1, listlen):tb2 hList[i2]if not tb2:continue# 符合同一栏if self.isSameColumn(tb1, tb2):# 符合同一段合并两行if self.isSamePara(tb1, tb2):self.merge2line(hList, i1, i2)num 1# 同栏、不同段说明到了下一段则退出内循环else:breakif num 1:tb1[score] / num # 平均置信度resList.append(tb1) # 装填入结果return resListdef run(self, textBlocks, imgInfo):# 段落合并resList self.mergePara(textBlocks)# 返回新文块列表return resList# 合并单行-横排from .tbpu import Tbpufrom functools import cmp_to_keyclass MergeLine(Tbpu):def __init__(self):self.tbpuName 单行-横排# merge line limit multiple X/Y/H单行合并时的水平/垂直/行高阈值系数为行高的倍数self.mllhX 2self.mllhY 0.5self.mllhH 0.5def isSameLine(self, A, B): # 两个文块属于同一行时返回 TrueAx, Ay A[1][0], A[1][1] # 块A右上角xyAh A[3][1] - A[0][1] # 块A行高Bx, By B[0][0], B[0][1] # 块B左上角xyBh B[3][1] - B[0][1] # 块B行高lx Ah * self.mllhX # 水平、垂直、行高 合并阈值ly Ah * self.mllhYlh Ah * self.mllhHif abs(Bx - Ax) lx and abs(By - Ay) ly and abs(Bh - Ah) lh:return Truereturn Falsedef merge2tb(self, textBlocks, i1, i2, separator): # 合并2个tb将i2合并到i1中。tb1 textBlocks[i1]tb2 textBlocks[i2]b1 tb1[box]b2 tb2[box]# 合并两个文块boxyTop min(b1[0][1], b1[1][1], b2[0][1], b2[1][1])yBottom max(b1[2][1], b1[3][1], b2[2][1], b2[3][1])xLeft min(b1[0][0], b1[3][0], b2[0][0], b2[3][0])xRight max(b1[1][0], b1[2][0], b2[1][0], b2[2][0])b1[0][1] b1[1][1] yTop # y上b1[2][1] b1[3][1] yBottom # y下b1[0][0] b1[3][0] xLeft # x左b1[1][0] b1[2][0] xRight # x右# 合并内容tb1[score] tb2[score] # 合并置信度tb1[text] tb1[text] separator tb2[text] # 合并文本textBlocks[i2] None # 置为空标记删除def mergeLine(self, textBlocks): # 单行合并# 所有文块按左上角点的x坐标排序textBlocks.sort(keylambda tb: tb[box][0][0])# 遍历每个文块寻找后续文块中与它接壤、且行高一致的项合并两个文块resList []listlen len(textBlocks)for i1 in range(listlen):tb1 textBlocks[i1]if not tb1:continueb1 tb1[box]num 1 # 合并个数# 遍历后续文块for i2 in range(i1 1, listlen):tb2 textBlocks[i2]if not tb2:continueb2 tb2[box]# 符合同一行则合并if self.isSameLine(b1, b2):# 合并两个文块boxself.merge2tb(textBlocks, i1, i2, )num 1if num 1:tb1[score] / num # 平均置信度resList.append(tb1) # 装填入结果return resListdef sortLines(self, resList): # 对文块排序从上到下从左到右def sortKey(A, B):# 先比较两个文块的水平投影是否重叠ay1, ay2 A[box][0][1], A[box][3][1]by1, by2 B[box][0][1], B[box][3][1]# 不重叠则按左上角y排序if ay2 by1 or ay1 by2:return 0 if ay1 by1 else (-1 if ay1 by1 else 1)# 重叠则按左上角x排序ax, bx A[box][0][0], B[box][0][0]return 0 if ax bx else (-1 if ax bx else 1)resList.sort(keycmp_to_key(sortKey))def run(self, textBlocks, imgInfo):# 单行合并resList self.mergeLine(textBlocks)# 结果排序self.sortLines(resList)# 返回新文块列表return resList这里的 key 需要自己手动更改‘box’、‘score’分别对应的是paddleocr识别出来的’text_region’、‘confidence’。 其实paddleocr里面应该也有对应的算法here这里面也是根据文本块区域bbox进行的排序先y后x也挺合适的。不过没有整合自然段的功能。就是粗暴的把文本块区域都弄在一起了。
总结
步骤就是这样先ocr识别文本和区域后面根据区域进行版面恢复。版面恢复部分根据自己的需要可以省略。
PS突然有个问题我发现wpspython-word处理的应该也还行段落什么的也都分的很好表格也识别对了。之前是觉得wps对生僻字识别的不好所以没用而且wps要钱hh。不过工程上的方法就是很多只有达到效果就行科研就不行都是精益求精的。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/88622.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!