代码之家  ›  专栏  ›  技术社区  ›  Gaurav Gandhi

查找类似文档

  •  4
  • Gaurav Gandhi  · 技术社区  · 6 年前

    我正在一个项目中工作,在这个项目中,我有带有标签类别的单页医疗报告的流程和存储文档。用户将输入一个文档,我必须对它所属的类别进行分类。

    我已将所有文档转换为灰度图像格式,并存储用于比较。

    我有一个图像数据集,包含以下数据,

    • image_path :此列有指向图像的路径
    • histogram_value :此列有图像的直方图,使用 cv2.calcHist 功能
    • np_avg :此列具有图像所有像素的平均值。计算方法 np.average
      • category :此列是图像的类别。

    我打算用这两种方法,

    • 计算 直方图值 在输入图像中,找到最近的10个匹配图像
      • 计算 NPAVG 在输入图像中,找到最近的10个匹配图像
      • 取两个结果集的交集
      • 如果找到多个图像,请进行模板匹配以找到最佳匹配。

    我对图像处理领域知之甚少。以上机制对我来说是否可靠?

    我查了一下,在相同的问题上发现了一些问题,但它们有一个非常不同的问题和期望的结果。 This question 看起来与我的情况类似,但它非常通用,我不确定它是否适用于我的场景。

    Link to sample reports

    4 回复  |  直到 6 年前
        1
  •  3
  •   HakunaMaData    6 年前

    我推荐一些东西:

    基于文本的比较:

    OCR使用谷歌的Tesseract(目前最好的开源OCR软件包之一)来提取文档和文本功能。它还有一个叫做python的包装器 PyTesseract . 您可能需要利用图像的分辨率,使OCR工作到您满意的程度——这需要一些尝试和错误。

    一旦你提取了单词,一个普遍接受的方法是计算tf-idf(术语频率-文档反向频率),然后任何基于距离的方法(余弦相似性是常见的方法之一)来比较哪些文档彼此“相似”(更接近)。

    基于图像的比较

    如果您已经将图像作为一个向量,那么应用基于距离的度量来计算相似性。一般来说,l1或l2标准是可行的。这个 paper 这表明曼哈顿(l1标准)可能对自然图像更有效。你可以从这个开始,尝试其他基于距离的测量方法

    集合基于文本和图像的比较

    运行这两种方法,然后在这两种方法之间取一些平均值,以得到彼此相似的文档。

    例如

    基于文本的方法可能将docb和docc分别按距离10和20个单位排列为距离doca最近的2个文档。

    根据距离5和距离20,基于图像的方法可能将docc和docb列为最接近的两个。

    然后你可以平均两个距离。docb为(10+20)/2=15,docc为(20+5)/2=12.5,与doca分开。所以你会用一种整体的方法来对待docc,让它更接近a而不是b。

        2
  •  2
  •   Mitiku    6 年前

    由于两个原因,从图像测量文档的相似度比从文本测量文档复杂。

    1. 图像在亮度、文本上下文、图表或符号方面可能具有相似性。
    2. 与文本信息相比,从文档所包含的图像中找到文档的表示形式通常比较困难。

    解决方案

    我的解决方案是使用机器学习查找文档的表示,并使用此表示对文档进行分类。 在这里,我将向Keras提供我建议的解决方案的实施。

    网络类型

    我建议使用卷积层进行特征提取,然后使用循环层进行序列分类。我之所以选择Keras是因为我很熟悉,它有一个简单的API来定义一个包含卷积层和循环层的网络。但代码可以很容易地更改为其他库,如pytorch、tensorflow等。

    图像预处理

    有很多方法可以预先处理神经网络文档的图像。我在做假设。

    • 图像包含水平文本而不是垂直文本。
    • 文档图像大小是固定的。如果图像大小不固定,可以使用 opencv's resize 方法。

    垂直拆分图像,以便将行作为序列馈送(如果拆分行可以在空行上对齐,则效率更高)。我将使用numpy显示单个文档。在下面的实现中,我假设单个文档的图像形状是(100,100,3)。 首先,让我们定义图像形状文档图像的形状为

    import numpy as np
    image_shape = (100, 100, 3)
    split_size = 25 # this should be factor of the image_shape[0]
    doc_images = [] #
    doc_image = np.zeros(image_shape)
    
    splitted_images = np.split(doc_images,[split_size], axis=0)
    doc_images.append(doc_image)
    doc_images = np.array(doc_images)
    

    网络实现

    克拉斯有 ConvLSTM2D 层处理顺序图像。网络的输入是由分割文档图像生成的一系列图像的列表。

    from keras.models import Sequential
    from keras.layers import ConvLSTM2D, Dense, Flatten
    num_of_classes = 10
    model = Sequential()
    
    model.add(ConvLSTM2D(32,(3, 3),input_shape=(None, split_size, image_shape[1],image_shape[2]),
            padding='same',
            return_sequences=True))
    model.add(ConvLSTM2D(32,(3, 3),padding='same',return_sequences=True))
    model.add(ConvLSTM2D(32,(3, 3),padding='same',return_sequences=False))
    model.add(Flatten())
    model.add(Dense(1024, activation="relu"))
    model.add(Dense(num_classes, activation="softmax"))
    

    理想情况下,该模型可以工作,因为该模型可以从文档的图像中学习文档的层次表示(字符、单词、句子、上下文、符号)。

        3
  •  1
  •   dario    6 年前

    样本文档差异很大,无法在图像级别进行比较(柱状图,np_avg)。

    报告的内容是多个数字(最小、最大、推荐)或类别结果(负/正)。

    对于每种类型的报告 你得做预处理。

    如果文档源是数字的(未扫描),则需要提取和比较字段、行。每行单独。

    • 提取字段或行的图像部分并与nn进行比较
    • 提取到文本并比较值(OCR)

    如果文档被扫描,在提取之前,您必须处理图像、质量和工件的旋转。

    每种类型的报告都有其自身的问题。选择一种具有多个样本的报告类型作为开始。

    因为你处理的是数字,只有提取到文本和数字,你会有很好的结果。如果报告说值为0.2,允许的范围在0.1到0.3之间,那么nn不是实现这一点的工具。你必须比较数字。

    nns并不是实现这一点的最佳工具,至少不用于比较值。可能是提取过程的一部分。

    解决方法步骤

    • 自动化报表分类
    • 对于每种类型的报告,用数据标记字段
    • 对于每种类型的报表,自动提取值
    • 对于每种类型的报告,根据业务规则解释值
        4
  •  0
  •   Chris Hubley    6 年前

    这似乎是一个使用机器学习对文档进行分类的好地方。

    你考虑过使用TensorFlow吗? (tensorflow.org)

    你可以用一堆文件来训练你的神经网络,然后把它放在其他文件上。