【问题标题】:How to detect diagram region and extract(crop) it from a research paper's Image如何检测图表区域并从研究论文的图像中提取(裁剪)它
【发布时间】:2020-04-06 03:40:44
【问题描述】:

我想从该研究论文图像中提取所有图形/图表。我该怎么做?

我只想要人物部分,有什么办法可以剪掉那部分吗?

【问题讨论】:

  • 这太笼统了。您在尝试执行此操作时遇到具体问题吗?
  • 非常感谢@AlexanderCécile 的评论!我能够使用 teseract 检测文本我计划从图像中裁剪该部分,但问题是(图中的文本)的某些部分也被检测到。我们能否以某种方式检测除文本或图像中的数字以外的部分
  • 或者你能指导我如何解决这个问题吗?我希望图像中的数字与文本分开
  • 您想从任何 PDF 中提取所有图像吗?
  • 是的@AlexanderCécile 我想提取所有的图形/图表(它不是 PDF,而是研究论文 PDF 的多个图像)

标签: python opencv machine-learning image-processing computer-vision


【解决方案1】:

这里只提取图形/图表是一种使用 OpenCV 的方法:

  1. 获取二值图像。加载图像,转换为灰度和Otsu的阈值得到二值图像。

  2. 连接文本轮廓。我们利用文本按段落结构化的观察结果,因此我们可以用水平轮廓扩张,将单个单词连接成一个轮廓。

  3. 删除非图表轮廓。我们使用纵横比和轮廓面积找到轮廓和过滤器。我们通过填充轮廓有效地去除了非图表轮廓。

  4. 形成单个边界框。遍历剩余轮廓并确定边界框坐标

  5. 提取 ROI。 使用 Numpy 切片裁剪/提取图表。


这是每个步骤的可视化:

阈值图像

使用水平内核扩张

过滤去除非图表轮廓

检测到的图表边界框

提取的投资回报率


注意:这种方法是假设图像中只有一个图表。如果有多个,那么您可以删除第 4 步以获得多个 ROI,并将每个单独的 ROI 保存为单独的图像。我相信这将是一个简单的改变:)

代码

import cv2
import numpy as np

# Load image, grayscale, Otsu's threshold
image = cv2.imread('1.png')
original = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Dilate with horizontal kernel
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (20,10))
dilate = cv2.dilate(thresh, kernel, iterations=2)

# Find contours and remove non-diagram contours
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    area = cv2.contourArea(c)
    if w/h > 2 and area > 10000:
        cv2.drawContours(dilate, [c], -1, (0,0,0), -1)

# Iterate through diagram contours and form single bounding box
boxes = []
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    x, y, w, h = cv2.boundingRect(c)
    boxes.append([x,y, x+w,y+h])

boxes = np.asarray(boxes)
x = np.min(boxes[:,0])
y = np.min(boxes[:,1])
w = np.max(boxes[:,2]) - x
h = np.max(boxes[:,3]) - y

# Extract ROI
cv2.rectangle(image, (x,y), (x + w,y + h), (36,255,12), 3)
ROI = original[y:y+h, x:x+w]

cv2.imshow('image', image)
cv2.imshow('thresh', thresh)
cv2.imshow('dilate', dilate)
cv2.imshow('ROI', ROI)
cv2.waitKey()

【讨论】:

  • 太棒了,我真的欠你很多谢谢! @nathancy :)
  • 你能帮我解决这个问题吗stackoverflow.com/questions/59311235/…
  • 问题目前已关闭,我无法回答。我不认为 pytesseract 能够识别符号。它只能做文本。不幸的是,我没有这个问题的解决方案
猜你喜欢
  • 2021-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-27
相关资源
最近更新 更多