import json
import random
import numpy as np
import cv2
import pandas as pd
import imgkit
import time
from PIL import Image
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
from create_labelme_data import create_lines_labelme, create_official_seal
DESKTOP_PATH = r"C:\Users\Administrator\Desktop"
def read_csv(path):
df = pd.read_csv(path, encoding='gbk')
df = df[:2000]
_list = []
for index, row in df.iterrows():
if type(row['json_table']) == float:
print(row['json_table'])
continue
_list.append(json.loads(row['json_table']))
# print(_list)
return _list
def create_html_table(_list, html_dir, count=0):
html_path_list = []
i = count
for table in _list:
table_text = '
' + "\n"
for row in table:
table_text += "" + "\n"
for col in row:
table_text += "" + col[0] + " | " + "\n"
table_text += "
" + "\n"
table_text += "
" + "\n"
css_text = ''
# 虚线框
# css_text = ''
# 粗虚线 上下或左右无边线
# css_text = ''
# css_text = ''
html_text = "" + "\n" \
+ "" + "\n" \
+ css_text + "\n" \
+ '' + "\n" \
+ '' + "\n" \
+ table_text + "\n" \
+ '
' + "\n" \
+ ""
html_path = html_dir + str(i) + ".html"
with open(html_path, 'w') as f:
f.write(html_text)
html_path_list.append(html_path)
i += 1
return html_path_list
def get_table_size(html_path):
print(html_path)
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
driver = webdriver.Chrome(chrome_options=chrome_options)
# driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(0)
driver.get(html_path)
# JS
js = """
_t = document.getElementById('table0')
function myFunc(){
var cells_size = new Array();
for (i = 0; i<_t.rows.length; i++){
var rows_size = new Array();
for (j = 0; j < _t.rows[i].cells.length; j++){
col = _t.rows[i].cells[j];
col_width = window.getComputedStyle(col).width;
col_height = window.getComputedStyle(col).height;
rows_size[j] = [col_width, col_height];
}
cells_size[i] = rows_size
}
return cells_size;
}
return myFunc();
"""
rows_list = driver.execute_script(js)
# print(rows_list)
# print(type(rows_list))
js = """
_t = document.getElementById('table0')
function myFunc(){
table_width = window.getComputedStyle(_t).width;
table_height = window.getComputedStyle(_t).height;
var table_size = [table_width, table_height];
return table_size
}
return myFunc()
"""
table_size = driver.execute_script(js)
table_size = [int(float(table_size[0][:-2])), int(float(table_size[1][:-2]))]
print("table_size", table_size)
# get_table_lines(rows_list, table_size)
# table = driver.find_element_by_id('table0')
# print("rows_list", rows_list)
return rows_list, table_size
def html2image1(html_path, table_size):
# 工具路径
path_wkimg = r'D:\Software\html_to_pdf\wkhtmltopdf\bin\wkhtmltoimage.exe'
cfg = imgkit.config(wkhtmltoimage=path_wkimg)
options = {
'width': table_size[0],
'height': table_size[1],
'encoding': 'UTF-8',
}
# 1、将html文件转为图片
image_path = html_path.split(".")[0]+".jpg"
print("html2image", image_path)
imgkit.from_file(html_path, image_path, config=cfg, options=options)
# 2、从url获取html,再转为图片
# imgkit.from_url('https://httpbin.org/ip', 'ip.jpg', config=cfg)
# 3、将字符串转为图片
# imgkit.from_string('Hello!','hello.jpg', config=cfg)
return image_path
def html2image(html_path, table_size):
# 将html文件转为图片
image_path = html_path.split(".")[0]+".jpg"
print("html2image", image_path)
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
broswer = webdriver.Chrome(chrome_options=chrome_options)
broswer.get(html_path)
# 截全图
width = broswer.execute_script("return document.documentElement.scrollWidth")
height = broswer.execute_script("return document.documentElement.scrollHeight")
broswer.set_window_size(width, height)
broswer.save_screenshot(image_path)
table = broswer.find_element_by_id('table0')
left = table.location['x']
top = table.location['y']
elementWidth = table.location['x'] + table.size['width']
elementHeight = table.location['y'] + table.size['height']
picture = Image.open(image_path)
picture = picture.crop((left, top, elementWidth, elementHeight))
picture = picture.convert("RGB")
picture.save(image_path)
return image_path
def get_table_lines(rows_list):
row_line_list = []
col_line_list = []
x = 0
y = 0
# 横线line
width = 0
height = 0
i = 0
for row in rows_list:
if i == 0:
for col in row:
width += float(col[0][:-2]) + 1
row_line_list.append([[x, y], [x+width, y]])
height += float(row[0][1][:-2]) + 1
else:
row_line_list.append([[x, y+height], [x+width, y+height]])
height += float(row[0][1][:-2]) + 1
i += 1
row_line_list.append([[x, y+height], [x+width, y+height]])
# 竖线line
width = 0
height = 0
i = 0
for col_num in range(len(rows_list)):
height += float(rows_list[col_num][0][1][:-2]) + 1
# print("height", height)
for row in rows_list:
if i == 0:
col_line_list.append([[x, y], [x, y+height]])
for col in row:
width += float(col[0][:-2]) + 1
col_line_list.append([[x+width, y], [x+width, y+height]])
break
# print("row_line_list", row_line_list)
# print("col_line_list", col_line_list)
# draw_lines(row_line_list+col_line_list, table_size, )
return row_line_list+col_line_list
def draw_lines(line_list, table_size, image_path, expand=False):
img = np.zeros((table_size[1], table_size[0]), np.uint8)
img.fill(255)
if expand:
image_origin = cv2.imread(image_path)
# print(image_origin.shape, img.shape)
# expand_height = int((image_origin.shape[1] - img.shape[1]) / 2)
# expand_width = int((image_origin.shape[0] - img.shape[0]) / 2)
# img = cv2.copyMakeBorder(img, expand_height, expand_height, expand_width,
# expand_width, cv2.BORDER_CONSTANT, value=(255, 255, 255))
img = np.zeros((image_origin.shape[0], image_origin.shape[1]), np.uint8)
print(image_origin.shape, img.shape)
img.fill(255)
for line in line_list:
cv2.line(img, (int(line[0][0]), int(line[0][1])),
(int(line[1][0]), int(line[1][1])), (0, 0, 255), 1)
cv2.imwrite(image_path.split(".")[0] + ".png", img)
# cv2.imshow("label", img)
# cv2.waitKey(0)
# image = cv2.imread(image_path)
# cv2.imshow("image", image)
# cv2.waitKey(0)
return line_list
def image_expand(image_path, line_list):
# image_np = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
# 随机选择边缘扩充px
# expand_height = random.randint(0, 500)
# expand_width = int(expand_height / 1.3333)
image_origin = cv2.imread(image_path)
expand_height = int((1123 - image_origin.shape[0]) / 2)
expand_width = int((794 - image_origin.shape[1]) / 2)
if expand_width < 0:
expand_width = 0
if expand_height < 0:
expand_height = 0
# print(expand_height, expand_width)
# 图像边缘扩充
image_np = cv2.imread(image_path)
image_np = cv2.copyMakeBorder(image_np, expand_height, expand_height, expand_width,
expand_width, cv2.BORDER_CONSTANT, value=(255, 255, 255))
cv2.imwrite(image_path, image_np)
# 线条坐标全部加上增加的宽高
new_line_list = []
for line in line_list:
new_line_list.append([[line[0][0]+expand_width, line[0][1]+expand_height],
[line[1][0]+expand_width, line[1][1]+expand_height]])
return image_path, new_line_list
if __name__ == '__main__':
csv_path = "D:\\BIDI_DOC\\比地_文档\\websource_67000_table.csv"
table_list = read_csv(csv_path)
i = 500
stop_i = 700
table_list = table_list[i:]
save_dir = "D:\\Project\\table-detect-master\\data_process\\create_data\\"
html_path_list = create_html_table(table_list, save_dir, i)
for html in html_path_list:
print("Loop", i)
rows_list, table_size = get_table_size(html)
image_path = html2image(html, table_size)
line_list = get_table_lines(rows_list)
# 图片扩展
# image_path, line_list = image_expand(image_path, line_list)
# 添加公章
image_np = cv2.imread(image_path)
image_np = create_official_seal(image_np)
cv2.imwrite(image_path, image_np)
with open(image_path, 'rb') as f:
image_bytes = f.read()
image_np = cv2.imread(image_path)
labelme = create_lines_labelme(line_list, image_bytes, image_np.shape[1], image_np.shape[0])
with open('../train/dataset-line/6/train_' + str(i) + '.json', 'w') as f:
json.dump(labelme, f)
draw_lines(line_list, table_size, image_path, False)
i += 1
if i > stop_i:
break
# break
# img_path = DESKTOP_PATH + '/1.jpg'
# get_table_lines(img_path)