Marmot是文档图像数据集(http://www.icst.pku.edu.cn/cpdp/data/marmot_data.htm),其中标记了几项内容,例如文档正文,图像区域,表区域,表标题等。该数据集专门用于文档图像分析研究目的。他们提到了所有以16位六进制十进制和小端格式的坐标。是否有人使用此数据集,以及如何将16位XY坐标转换为人类可以理解的格式?
答案 0 :(得分:1)
如果有人像我一样尝试在Python 3中执行此操作,则只需更改其他答案的步骤2:
conv_pound = [struct.unpack('!d', bytes.fromhex(t))[0] for t in BBox]
答案 1 :(得分:1)
凝视xmls一个小时后,我在@MMReza的答案中找到了最后缺失的部分:
您不需要依靠度量单位(第3步)。根元素“页面”有一个名为“ CropBox”的属性。使用那个来缩放坐标。 我沿以下几行(这里也是y轴的倒数):
px0, py1, px1, py0 = list(map(hex_to_double, page.get("CropBox").split()))
pw = abs(px1 - px0)
ph = abs(py1 - py0)
for table in page.findall(".//Composite[@Label='TableBody']"):
x0p, y1m, x1p, y0m = list(map(hex_to_double, table.get("BBox").split()))
x0 = round(imgw*(x0p - px0)/pw)
x1 = round(imgw*(x1p - px0)/pw)
y0 = round(imgh*(py1 - y0m)/ph)
y1 = round(imgh*(py1 - y1m)/ph)
答案 2 :(得分:0)
最后,经过分析后,我得到了线索,如果有人需要调查此数据集,则可以在此处发布。但是,他们提到了将单位坐标转换为像素值的单位值,但由于在手册/指南中未提及单位,因此很难找到。他们提到另一个地方作为注释。
首先,您必须使用IEEE 754 little endian格式转换其16个字符的十六进制值。例如,标签的给定坐标为
BBox = ['4074145c00000005','4074dd95999999a9','4080921e74bc6a80','406fb9999999999a']
使用python转换
conv_pound = struct.unpack('!d',str(t).decode('hex'))[0])for BBox中的t]
您将获得以1/72英寸的“磅”为单位的值。我们通常以像素为单位使用坐标,我们知道1英寸为96像素。所以,
conv_pound = [321.2724609375003,333.8490234375009,530.2648710937501,253.8]
然后,将每个值除以72,再乘以96,最后得到对应的像素值,
in_pixel = [428.36328, 445.13203, 707.01983, 338.40000]
他们开始计算文档图像左下角的像素位置。如果从左上角考虑(通常以这种方式考虑),则必须从图像高度中减去第二和第四值。如果我们认为图像[height,width]为[1123,793],则可以将上述坐标表示为整数值,
label_boundary = [428、678、707、785]
答案 3 :(得分:0)
我想转换坐标,也想验证我的转换是否确实有效。因此,我制作了这个脚本来读取标签文件和相应的图像文件,然后提取表体的坐标(例如),并在图像上可视化它们。它可以用于以类似方式提取其他字段。评论说明了一切
import glob
import struct
import cv2
import binascii
import re
xml_files = glob.glob("path_to_labeled_files/*.xml")
for i in xml_files:
# Open the current file and read everything
cur_file = open(i,"r")
content = cur_file.read()
# Find index of all occurrences of only needed portions (eg TableBody this case)
residxs = [l.start() for l in re.finditer('Label="TableBody"', content)]
# Read the image
img = cv2.imread("path_to_images_folder/"+i.split('/')[-1][:-3]+"jpg")
# Traverse over all occurences
for r in residxs[:-1]:
# List to store output points
coords = []
# Start index of an occurence
sidx = r
# Substring from whole file content
substr = content[sidx:sidx+400]
# Now find start index and end index of coordinates in this substring
sidx = substr.find('BBox="')
eidx = substr.find('" CLIDs')
# String containing only points
points = substr[sidx+6:eidx]
# Make the conversion (also take care of little and big endian in unpack)
bins = ''
for j in points.split(' '):
if(j == ''):
continue
coords.append(struct.unpack('>d', binascii.unhexlify(j))[0])
if len(coords) != 4:
continue
# As suggested by MMReza
for k in range(4):
coords[k] = (coords[k]/72)*96
coords[1] = img.shape[0] - coords[1]
coords[3] = img.shape[0] - coords[3]
# Print the extracted coordinates
print(coords)
# Visualize it on the image
cv2.rectangle(img, (int(coords[0]),int(coords[1])) , (int(coords[2]),int(coords[3])), (255, 0, 0), 2)
cv2.imshow("frame",img)
cv2.waitKey(0)