首先看看我的项目结构:

从上面的结果图中,我们可以看出,主要用了两个库:itextsharp.dll 和 pdfbox-1.8.9.dll,dll文件夹存放引用的库,handles文件夹存放抽取的处理代码,lib文件夹中,相当于数据库中的DBHelp类的作用。model文件夹就不用介绍了,大家都知道。

我们从大的逻辑开始介绍,TitleHandle类中有一个方法:

从此方法可以看出,它接收两个参数:block和isTrainModel,返回 HandleResult类型。

我们先来看看Block的定义:

块由行构成,我们再看看Line的定义:

行由单词构成,再来看Word定义:

它其实是一个词的集合,WordMeta是一个单词的信息,它下面还有一层结构 WordInfo类,这个类是最基础的类,它代表了pdf文档中一个字符信息,底层基础决定上层建筑:

   public class WordInfo
{
/// <summary>
/// x坐标
/// </summary>
public float X { set; get; }
/// <summary>
/// y坐标
/// </summary>
public float Y { set; get; } public int XSize { set; get; } public int YSize { get; set; } public float XDirAdj { set; get; } public float YDirAdj { set; get; } /// <summary>
/// 字号
/// </summary>
public float FontSize { set; get; } public float Xscale { set; get; } public float Yscale { set; get; }
/// <summary>
/// 高度
/// </summary>
public float Height { set; get; } /// <summary>
/// 空格大小
/// </summary>
public float Space { set; get; }
/// <summary>
/// 宽度
/// </summary>
public float Width { set; get; }
/// <summary>
/// 子字体
/// </summary>
public string Subfont { set; get; }
/// <summary>
/// 基本字体
/// </summary>
public string Basefont { set; get; }
/// <summary>
/// 是否加粗
/// </summary>
public bool IsBold { set; get; }
/// <summary>
/// 是否倾斜
/// </summary>
public bool IsItalic { set; get; }
/// <summary>
/// 单词
/// </summary>
public string Word { set; get; } public override string ToString()
{
return "String[" + this.XDirAdj + ","
+ this.YDirAdj
+ " fs=" + this.FontSize
+ " xscale=" + this.Xscale
+ " isBold=" + this.IsBold
+ " space=" + this.Space
+ " isItalic=" + this.IsItalic
+ "xSize" + this.XSize
+ "ySize" + this.YSize
+ " width=" + this.Width + "]"
+ this.Word;
}
/// <summary>
/// 计算当前字符和lastChunk的距离
/// </summary>
/// <param name="lastChunk"></param>
/// <returns></returns>
public float DistanceFromEndOf(WordInfo lastChunk)
{
return this.X - lastChunk.X - lastChunk.Width;
} }

这个类包括了字符的位置,大小,粗细等等信息。这些信息是基础当中的基础,因此非常重要,给我们判断一个块是否是标题,提供了依据,相当于国之宪法。

从我解剖出来的结构看,解析出pdf标题,关键有两点:

第一,如何正确地划分块,把具有相同格式的多行文字划分到一个块中,这样就形成了一个块的字典集合,也就是Block类中的字典类型:Dictionary<int, List<WordMeta>>。

分块也有难点,有很多上标和下标的句子,也有很多非常相似的块,可能分错。比如标题的块和作者的块,文字格式如果非常接近的话,就很容易把作者和标题划分到同一个块中,这给后面的工作带来了麻烦,以至于提取了错误的标题。

第二,如何从众多的块中筛选出标题。

此处也采取了很多筛选策略。

1、根据块长度,淘汰字符长度太短的。

2、根据块位置,淘汰位置太偏的。

3、评分机制,根据块的特征信息,计算出一个0-1之间的数值来,然后选取第一名和第二名的块。

4、在第一名和第二名之间选择。根据它们的位置,字符长度,分值,块的高度,块所包含的单词数等来判断。

c#抽取pdf文档标题(1)的更多相关文章

  1. c#抽取pdf文档标题——前言

    由于工作的需要,研究c#抽取pdf文档标题有3个月了.这项工作是一项"伟大而艰巨"的任务.应该是我目前研究工作中最长的一次.我觉得在长时间忙碌后,应该找些时间,把自己的心路历程归纳 ...

  2. c#抽取pdf文档标题(3)

    上一篇介绍了整体流程以及利用库读取pdf内容形成字符集合.这篇着重介绍下,过滤规则,毕竟我们是使用规则过滤,最后得到标题的. 首先看归一化处理,什么是归一化呢?就是使结果始终处于0-1之间(包括0,1 ...

  3. c#抽取pdf文档标题(2)

    public class IETitle { public static List<WordInfo> WordsInfo = new List<WordInfo>(); pr ...

  4. c#抽取pdf文档标题(4)——机器学习以及决策树

    我的一位同事告诉我,pdf抽取标题,用机器学习可以完美解决问题,抽取的准确率比较高.于是,我看了一些资料,就动起手来,实践了下. 我主要是根据以往历史块的特征生成一个决策树,然后利用这棵决策树,去判断 ...

  5. Python处理Excel和PDF文档

    一.使用Python操作Excel Python来操作Excel文档以及如何利用Python语言的函数和表达式操纵Excel文档中的数据. 虽然微软公司本身提供了一些函数,我们可以使用这些函数操作Ex ...

  6. C#给PDF文档添加文本和图片页眉

    页眉常用于显示文档的附加信息,我们可以在页眉中插入文本或者图形,例如,页码.日期.公司徽标.文档标题.文件名或作者名等等.那么我们如何以编程的方式添加页眉呢?今天,这篇文章向大家分享如何使用了免费组件 ...

  7. 将w3cplus网站中的文章页面提取并导出为pdf文档

    最近在看一些关于CSS3方面的知识,主要是平时看到网页中有很多用CSS3实现的很炫的效果,所以就打算系统的学习一下.在网上找到很多的文章,但都没有一个好的整理性,比较凌乱.昨天看到w3cplus网站中 ...

  8. PDF2SWF转换只有一页的PDF文档,在FlexPaper不显示解决方法

    问题:PDF2SWF转换只有一页的PDF文档,在FlexPaper不显示! FlexPaper 与 PDF2SWF 结合是解决在线阅读PDF格式文件的问题的,多页的PDF文件转换可以正常显示,只有一页 ...

  9. 【PDF】java使用Itext生成pdf文档--详解

    [API接口]  一.Itext简介 API地址:javadoc/index.html:如 D:/MyJAR/原JAR包/PDF/itext-5.5.3/itextpdf-5.5.3-javadoc/ ...

随机推荐

  1. 试着把.net的GC讲清楚(2)

    试着把.net的GC讲清楚(1) 上篇文章说了一些基本概念的东西,然后还有很多东西概念没有头绪,这篇文章我试着解释 GC的回收算法详细步骤? 上篇]文章讲了.net GC的算法是Mark and Co ...

  2. Wordpress上传资源报HTTP错误

    简述 在公司内部搭建内部视频学习网站,经过对比选择了wordpress进行站点搭建.但是在上传视频遭遇到了各种问题,特将此处理过程进行记录. 原因排查 1.上传一个十几兆mp4的文件上传进度到达百分之 ...

  3. Spark SQL1.2测试

    Spark SQL 1.2 运行原理 case class方式 json文件方式 背景:了解到HDP也能够支持Spark SQL,但官方文档是版本1.2,希望支持传统数据库.hadoop平台.文本格式 ...

  4. Hive:子查询

    Hive只支持在FROM子句中使用子查询,子查询必须有名字,并且列必须唯一:SELECT ... FROM(subquery) name ...

  5. HTML入门标签汇总

    HTML入门标签汇总 1.<div></div>用于定义文档的区块,用来划分出独立不同的部分. 2.<h1></h1>数字1-6定义从大到小的标题. 3 ...

  6. 云计算基础 (redhat7介绍及相关配置)

    redhat7简介 新版本的rhel7不再对32位架构的支持 引导程序: GRUB2,比之前的GRUB更强大,GRUB2支持bios,efi和openfiremware GRUB2支持mbr分区表和g ...

  7. linux远程控制

    linux远程控制 SSH协议:为客户机提供安全的shell环境,默认端口22OpenSSH服务服务名称:sshd主程序:/usr/sbin/sshd ,/usr/bin/ssh配置文件:/etc/s ...

  8. cips2016+学习笔记︱简述常见的语言表示模型(词嵌入、句表示、篇章表示)

    在cips2016出来之前,笔者也总结过种类繁多,类似词向量的内容,自然语言处理︱简述四大类文本分析中的"词向量"(文本词特征提取)事实证明,笔者当时所写的基本跟CIPS2016一 ...

  9. ARM开发软件ADS教程

    ARM开发软件ADS教程 ADS(ARM Developer Suite)是ARM公司推出ARM集成开发环境,操作简单方便,获得广大开发人员的青睐.下面使用ADS v1.2做一个实例教程,帮助大家学会 ...

  10. Struts2实现文件上传报错(二)

    1.具体报错如下 usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] [ -nonaming ] { -he ...