• OCR 表格识别中的树编辑距离


    kPaddleOCR/README_ch.md at release/2.5 · PaddlePaddle/PaddleOCR · GitHub

    编辑距离paper:

     GitHub - ibm-aur-nlp/PubTabNet

      1911.10683.pdf (arxiv.org)

     作者提供了脚本,但是jupter

    我复制了一遍,如下:
     

    1. pred = '
      Name of algoriNotablefeatures
      MACS [23]Uses both a control library and local statistics to minimize bias
      SICER [15]Designed for detecting diffusely enriched regions; for example, histone modification
      PeakSEQ [24]Corrects for reference genome mappability and local statistics
      SISSRs [25]High resolution, precise identification of binding-site location
      F-seq [26]Uses kernel density estimation
      '
    2. true = '
      Name of algorithmNotable features
      MACS [23]Uses both a control library and local statistics to minimize bias
      SICER [14]Designed for detecting diffusely enriched regions; for example, histone modification
      PeakSeq [24]Corrects for reference genome mappability and local statistics
      SISSRs [25]High resolution, precise identification of binding-site location
      F-seq [26]Uses kernel density estimation
      '
    3. from metric import TEDS
    4. # Initialize TEDS object
    5. teds = TEDS()
    6. # Evaluate
    7. score = teds.evaluate(pred, true)
    8. print('TEDS score:', score)

    这两个string,作者只提供了标签,没有提供图片。我们可以直接把标签里面复制到一个html文件中,然后用浏览器打开。

     如果你的格式有点乱,可以格式化一下。

    我们只关注body 里面的内容。<> 和是一对,就像括号一样。thead 是表头,就是下面加黑的那个。tbody是表格身体。tr是一行,td是一个单元格。

     下面来说跨行的情况

     whole country 垮了四列

    1. <tr>
    2. <td colspan="4">
    3. whole country
    4. td>
    5. tr>

     下面是跨行

    DHS WI 新开一行  CDR-RS 不新开一行。CDR 和 RS 新开一行。也就是说,是否要新开一行只与上一个单元格的行起点有关系。

    1. <tr>
    2. <td rowspan="3">
    3. DHS WI
    4. td>
    5. <td>
    6. CDR–RS
    7. td>
    8. <td>
    9. 0.76
    10. td>
    11. <td>
    12. 0.394
    13. td>
    14. tr>
    15. <tr>
    16. <td>
    17. CDR
    18. td>
    19. <td>
    20. 0.64
    21. td>
    22. <td>
    23. 0.483
    24. td>
    25. tr>
    26. <tr>
    27. <td>
    28. RS
    29. td>
    30. <td>
    31. 0.74
    32. td>
    33. <td>
    34. 0.413
    35. td>
    36. tr>

     上面的图片我是用的作者example文件夹中的,这里不仅有图片还有标签。还有脚本,脚本可以把jason转为HTML格式的字符串。

    脚本我运行不了,要改一改

    1. if __name__ == '__main__':
    2. import json
    3. import sys
    4. f = "PubTabNet_Examples.jsonl"
    5. file = open(f, 'r', encoding='utf-8')
    6. for line in file.readlines():
    7. annotations = json.loads(line)
    8. if annotations["imgid"] == 32:
    9. html_string = format_html(annotations)
    10. print(html_string)

     计算树编辑距离的核心代码就是这里:

      PubTabNet/metric.py at master · ibm-aur-nlp/PubTabNet · GitHub

    distance = APTED(tree_pred, tree_true, CustomConfig()).compute_edit_distance()

    这里核心代码我也不懂,大概意思是作者自定义了一个tree的类,通过递归的方式逐层加载HTML的string,创建出整棵树。然后使用上面那个API计算树的距离。

     
    

    下面是作者封装的一个树。   tree_true = self.load_html_tree(true)

    1. {
    2. "tag": table{
    3. "tag": thead{
    4. "tag": tr{
    5. "tag": td,
    6. "colspan": 1,
    7. "rowspan": 1,
    8. "text": ['<b>', 'N', 'a', 'm', 'e', ' ', 'o', 'f', ' ', 'a', 'l', 'g', 'o', 'r', 'i', 't', 'h', 'm', 'b>'
    9. ]
    10. }{
    11. "tag": td,
    12. "colspan": 1,
    13. "rowspan": 1,
    14. "text": ['<b>', 'N', 'o', 't', 'a', 'b', 'l', 'e', ' ', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', 'b>'
    15. ]
    16. }
    17. }
    18. }{
    19. "tag": tbody{
    20. "tag": tr{
    21. "tag": td,
    22. "colspan": 1,
    23. "rowspan": 1,
    24. "text": ['M', 'A', 'C', 'S', ' ', '[', '2', '3', '
    25. ]'
    26. ]
    27. }{
    28. "tag": td,
    29. "colspan": 1,
    30. "rowspan": 1,
    31. "text": ['U', 's', 'e', 's', ' ', 'b', 'o', 't', 'h', ' ', 'a', ' ', 'c', 'o', 'n', 't', 'r', 'o', 'l', ' ', 'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ', 'a', 'n', 'd', ' ', 'l', 'o', 'c', 'a', 'l', ' ', 's', 't', 'a', 't', 'i', 's', 't', 'i', 'c', 's', ' ', 't', 'o', ' ', 'm', 'i', 'n', 'i', 'm', 'i', 'z', 'e', ' ', 'b', 'i', 'a', 's'
    32. ]
    33. }
    34. }{
    35. "tag": tr{
    36. "tag": td,
    37. "colspan": 1,
    38. "rowspan": 1,
    39. "text": ['S', 'I', 'C', 'E', 'R', ' ', '[', '1', '4', '
    40. ]'
    41. ]
    42. }{
    43. "tag": td,
    44. "colspan": 1,
    45. "rowspan": 1,
    46. "text": ['D', 'e', 's', 'i', 'g', 'n', 'e', 'd', ' ', 'f', 'o', 'r', ' ', 'd', 'e', 't', 'e', 'c', 't', 'i', 'n', 'g', ' ', 'd', 'i', 'f', 'f', 'u', 's', 'e', 'l', 'y', ' ', 'e', 'n', 'r', 'i', 'c', 'h', 'e', 'd', ' ', 'r', 'e', 'g', 'i', 'o', 'n', 's', ';', ' ', 'f', 'o', 'r', ' ', 'e', 'x', 'a', 'm', 'p', 'l', 'e', ',', ' ', 'h', 'i', 's', 't', 'o', 'n', 'e', ' ', 'm', 'o', 'd', 'i', 'f', 'i', 'c', 'a', 't', 'i', 'o', 'n'
    47. ]
    48. }
    49. }{
    50. "tag": tr{
    51. "tag": td,
    52. "colspan": 1,
    53. "rowspan": 1,
    54. "text": ['P', 'e', 'a', 'k', 'S', 'e', 'q', ' ', '[', '2', '4', '
    55. ]'
    56. ]
    57. }{
    58. "tag": td,
    59. "colspan": 1,
    60. "rowspan": 1,
    61. "text": ['C', 'o', 'r', 'r', 'e', 'c', 't', 's', ' ', 'f', 'o', 'r', ' ', 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e', ' ', 'g', 'e', 'n', 'o', 'm', 'e', ' ', 'm', 'a', 'p', 'p', 'a', 'b', 'i', 'l', 'i', 't', 'y', ' ', 'a', 'n', 'd', ' ', 'l', 'o', 'c', 'a', 'l', ' ', 's', 't', 'a', 't', 'i', 's', 't', 'i', 'c', 's'
    62. ]
    63. }
    64. }{
    65. "tag": tr{
    66. "tag": td,
    67. "colspan": 1,
    68. "rowspan": 1,
    69. "text": ['S', 'I', 'S', 'S', 'R', 's', ' ', '[', '2', '5', '
    70. ]'
    71. ]
    72. }{
    73. "tag": td,
    74. "colspan": 1,
    75. "rowspan": 1,
    76. "text": ['H', 'i', 'g', 'h', ' ', 'r', 'e', 's', 'o', 'l', 'u', 't', 'i', 'o', 'n', ',', ' ', 'p', 'r', 'e', 'c', 'i', 's', 'e', ' ', 'i', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', ' ', 'o', 'f', ' ', 'b', 'i', 'n', 'd', 'i', 'n', 'g', '-', 's', 'i', 't', 'e', ' ', 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n'
    77. ]
    78. }
    79. }{
    80. "tag": tr{
    81. "tag": td,
    82. "colspan": 1,
    83. "rowspan": 1,
    84. "text": ['F', '-', 's', 'e', 'q', ' ', '[', '2', '6', '
    85. ]'
    86. ]
    87. }{
    88. "tag": td,
    89. "colspan": 1,
    90. "rowspan": 1,
    91. "text": ['U', 's', 'e', 's', ' ', 'k', 'e', 'r', 'n', 'e', 'l', ' ', 'd', 'e', 'n', 's', 'i', 't', 'y', ' ', 'e', 's', 't', 'i', 'm', 'a', 't', 'i', 'o', 'n'
    92. ]
    93. }
    94. }
    95. }
    96. }

  • 相关阅读:
    举例说明PyTorch函数torch.cat与torch.stack的区别
    嵌入式Linux系统编程 — 3.7 文件目录与处理
    【Docker】- 【入门】- 001 - 创建docker 账户 以及 上传image和部署image
    北京十大靠谱律师事务所最新排名(2022前十推荐)
    待试验:AR与DMX同步,实现AR效果与现实灯光互相影响,增强体验的真实感
    工作和异地,都是生活的考验
    面向大规模队列,百万并发的多优先级消费系统设计
    看完这篇 教你玩转渗透测试靶机vulnhub——FunBox4(CTF)
    学习javaEE初阶的第一堂课
    7.1 为什么要用函数
  • 原文地址:https://blog.csdn.net/qq_40709711/article/details/126472962