我有文本文档的图像。它包括文本和块方案。主要问题是检测模块方案。我认为有两种方法可以解决此任务:1)检测构成方案的几何图元; 2)检测整个方案。
请问我该如何解决这个问题。
更新1 我尝试检测文档块计划中的放置位置。示例如下图所示。我没有尝试在程序框图中检测文本。
UPDATE 2 主要问题是我应该找到不同品种的模块方案。甚至是一部分计划。
答案 0 :(得分:3)
如果要搜索的图表类型更多,我希望这样做,但是根据您给出的例子,这是我天真地解决它的尝试。
1)将图像调整为可管理的大小,以提高速度并减少操作。
2)使用形态开放将所有黑暗物体聚在一起。
3)对深色物体进行二值化。
4)使用openCV连接的组件标记对象。这将为我们提供每个区域的边界框。
5)将重叠的边界框聚在一起。
6)分析每个边界框,找到带有图的边界框。在这里,您可以应用更复杂的算法,例如框检测,甚至是箭头检测,但是在您的示例中,我认为简单的框比率就足够了。
这是实现的代码
import cv2
import numpy as np
# Function to fill all the bounding box
def fill_rects(image, stats):
for i,stat in enumerate(stats):
if i > 0:
p1 = (stat[0],stat[1])
p2 = (stat[0] + stat[2],stat[1] + stat[3])
cv2.rectangle(image,p1,p2,255,-1)
# image name
img_name = 'test_image.png'
# Load image file
diagram = cv2.imread(img_name,0)
diagram = cv2.blur(diagram,(5,5))
fScale = 0.25
# Make it smaller to speed up everything and easier to cluster
small_img = cv2.resize(diagram,(0,0),fx = fScale, fy = fScale)
img_h, img_w = np.shape(small_img)
# Morphological close process to cluster nearby objects
fat_img = cv2.morphologyEx(small_img,cv2.MORPH_OPEN,None,iterations = 1)
# Threshold strong signals
_, bin_img = cv2.threshold(fat_img,210,255,cv2.THRESH_BINARY_INV)
# Analyse connected components
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(bin_img)
# Cluster all the intersected bounding box together
rsmall, csmall = np.shape(small_img)
new_img1 = np.zeros((rsmall, csmall), dtype=np.uint8)
fill_rects(new_img1,stats)
# Analyse New connected components to get filled regions
num_labels_new, labels_new, stats_new, centroids_new = cv2.connectedComponentsWithStats(new_img1)
# Check for regions that satifies conditions coresponds to diagram
min_dia_width = img_w * 0.1
dia_regions = []
for i ,stat in enumerate(stats):
if i > 0:
# get basic dimensions
x,y,w,h = stat[0:4]
# calculate ratio
ratio = w / float(h)
# if condition met, save in list
if ratio < 1 and w > min_dia_width:
dia_regions.append((x/fScale,y/fScale,w/fScale,h/fScale))
# For display purpose
diagram_disp = cv2.imread(img_name)
for region in dia_regions:
x,y,w,h = region
x = int(x)
y = int(y)
w = int(w)
h = int(h)
cv2.rectangle(diagram_disp,(x,y),(x+w,y+h),(0,255,0),2)
labels_disp = np.uint8(200*labels/np.max(labels)) + 50
labels_disp2 = np.uint8(200*labels_new/np.max(labels_new)) + 50
cv2.imshow('small_img',small_img)
cv2.imshow('fat_img',fat_img)
cv2.imshow('bin_img',bin_img)
cv2.imshow("labels",labels_disp)
cv2.imshow("labels_disp2",labels_disp2)
cv2.imshow("diagram_disp",diagram_disp)
cv2.waitKey(0)
这是另一种输入的结果。
答案 1 :(得分:3)
您可以执行1)对象检测2)语义分割。我建议分割,因为边界提取对于您的应用程序至关重要。
我假设您将文档页面作为图像。
以下是涉及细分的项目中涉及的步骤。
Labelme-(我的推荐)
Vgg Annotation tool-(使用html编写的高度可移植的工具,但功能不如labelme)
您可以将U-Net模型用于任务。 Unet Paper。它很容易实现,但是在大多数现实世界中的任务(例如您的任务)上表现出色。
我们在工作中做了类似的事情。这是blog post。我们已经详细解释了从数据收集阶段到结果的管道中涉及的步骤。
此处介绍的方法可能看起来很乏味且耗时,但是在测试时,它对于文档中的可变性很健壮。如有任何疑问,请在下面评论。