Spaces:
Runtime error
Runtime error
import os | |
import numpy as np | |
import cv2 | |
from shapely.geometry import box, Polygon | |
from shapely import affinity | |
import math | |
def _rect2quad(boxes): | |
x_min, y_min, x_max, y_max = boxes[:, 0].reshape((-1, 1)), boxes[:, 1].reshape((-1, 1)), boxes[:, 2].reshape((-1, 1)), boxes[:, 3].reshape((-1, 1)) | |
return np.hstack((x_min, y_min, x_max, y_min, x_max, y_max, x_min, y_max)) | |
def _quad2rect(boxes): | |
## only support rectangle | |
return np.hstack((boxes[:, 0].reshape((-1, 1)), boxes[:, 1].reshape((-1, 1)), boxes[:, 4].reshape((-1, 1)), boxes[:, 5].reshape((-1, 1)))) | |
def _quad2minrect(boxes): | |
## trans a quad(N*4) to a rectangle(N*4) which has miniual area to cover it | |
return np.hstack((boxes[:, ::2].min(axis=1).reshape((-1, 1)), boxes[:, 1::2].min(axis=1).reshape((-1, 1)), boxes[:, ::2].max(axis=1).reshape((-1, 1)), boxes[:, 1::2].max(axis=1).reshape((-1, 1)))) | |
def _quad2boxlist(boxes): | |
res = [] | |
for i in range(boxes.shape[0]): | |
res.append([[boxes[i][0], boxes[i][1]], [boxes[i][2], boxes[i][3]], [boxes[i][4], boxes[i][5]], [boxes[i][6], boxes[i][7]]]) | |
return res | |
def _boxlist2quads(boxlist): | |
res = np.zeros((len(boxlist), 8)) | |
for i, box in enumerate(boxlist): | |
# print(box) | |
res[i] = np.array([box[0][0], box[0][1], box[1][0], box[1][1], box[2][0], box[2][1], box[3][0], box[3][1]]) | |
return res | |
def _rotate_image(im, polygons, angle): | |
new_polygons = polygons | |
## rotate image first | |
height, width, _ = im.shape | |
## get the minimal rect to cover the rotated image | |
img_box = np.array([[0, 0, width, 0, width, height, 0, height]]) | |
rotated_img_box = _quad2minrect(_rotate_polygons(img_box, -1*angle, (width/2, height/2))) | |
r_height = int(max(rotated_img_box[0][3], rotated_img_box[0][1]) - min(rotated_img_box[0][3], rotated_img_box[0][1])) | |
r_width = int(max(rotated_img_box[0][2], rotated_img_box[0][0]) - min(rotated_img_box[0][2], rotated_img_box[0][0])) | |
r_height_padding = max(r_height, height) | |
r_width_padding = max(r_width, width) | |
## padding im | |
im_padding = np.zeros((r_height_padding, r_width_padding, 3)) | |
start_h, start_w = int((r_height_padding - height)/2.0), int((r_width_padding - width)/2.0) | |
# start_h = max(start_h, 0) | |
# start_w = max(start_w, 0) | |
end_h, end_w = start_h + height, start_w + width | |
# print(start_h, end_h, start_w, end_w, im.shape) | |
im_padding[start_h:end_h, start_w:end_w, :] = im | |
M = cv2.getRotationMatrix2D((r_width/2, r_height/2), angle, 1) | |
im = cv2.warpAffine(im_padding, M, (r_width, r_height)) | |
## polygons | |
new_polygons = _rotate_segms(polygons, -1*angle, (r_width/2, r_height/2), start_h, start_w) | |
return im, new_polygons | |
def _rotate_polygons(polygons, angle, r_c): | |
## polygons: N*8 | |
## r_x: rotate center x | |
## r_y: rotate center y | |
## angle: -15~15 | |
poly_list = _quad2boxlist(polygons) | |
rotate_boxes_list = [] | |
for poly in poly_list: | |
box = Polygon(poly) | |
rbox = affinity.rotate(box, angle, r_c) | |
if len(list(rbox.exterior.coords))<5: | |
print(poly) | |
print(rbox) | |
# assert(len(list(rbox.exterior.coords))>=5) | |
rotate_boxes_list.append(rbox.boundary.coords[:-1]) | |
res = _boxlist2quads(rotate_boxes_list) | |
return res | |
def _rotate_segms(polygons, angle, r_c, start_h, start_w): | |
## polygons: N*8 | |
## r_x: rotate center x | |
## r_y: rotate center y | |
## angle: -15~15 | |
poly_list=[] | |
for polygon in polygons: | |
tmp=[] | |
for i in range(int(len(polygon) / 2)): | |
tmp.append([polygon[2*i] + start_w, polygon[2*i+1] + start_h]) | |
poly_list.append(tmp) | |
rotate_boxes_list = [] | |
for poly in poly_list: | |
box = Polygon(poly) | |
rbox = affinity.rotate(box, angle, r_c) | |
if len(list(rbox.exterior.coords))<5: | |
print(poly) | |
print(rbox) | |
rotate_boxes_list.append(rbox.boundary.coords[:-1]) | |
res = [] | |
for i, box in enumerate(rotate_boxes_list): | |
tmp = [] | |
for point in box: | |
tmp.append(point[0]) | |
tmp.append(point[1]) | |
res.append([tmp]) | |
return res | |
def _read_gt(gt_path): | |
polygons = [] | |
words = [] | |
with open(gt_path, 'r') as fid: | |
lines = fid.readlines() | |
for line in lines: | |
line = line.strip() | |
polygon = line.split(',')[:8] | |
word = line.split(',')[8] | |
polygon = [float(x) for x in polygon] | |
polygons.append(polygon) | |
words.append(word) | |
return polygons, words | |
def format_new_gt(polygons, words, new_gt_path): | |
with open(new_gt_path, 'wt') as fid: | |
for polygon, word in zip(polygons, words): | |
# print(polygon) | |
polygon = [str(int(x)) for x in polygon[0]] | |
# polygon = [str(int(x)) for x in polygon] | |
line = ','.join(polygon) + ',' + word | |
# print(line) | |
fid.write(line+'\n') | |
def visu_gt(img, polygons, visu_path): | |
for polygon in polygons: | |
pts = np.array(polygon, np.int32) | |
pts = pts.reshape((-1,1,2)) | |
cv2.polylines(img,[pts],True,(0,255,255)) | |
cv2.imwrite(visu_path, img) | |
img_dir = '../datasets/icdar2013/test_images' | |
gt_dir = '../datasets/icdar2013/test_gts' | |
angle = 45 | |
new_img_dir = '../datasets/icdar2013/rotated_test_images'+'_'+str(angle) | |
new_gt_dir = '../datasets/icdar2013/rotated_test_gts'+'_'+str(angle) | |
if not os.path.isdir(new_img_dir): | |
os.mkdir(new_img_dir) | |
if not os.path.isdir(new_gt_dir): | |
os.mkdir(new_gt_dir) | |
visu_dir = '../output/visu/' | |
for i in range(233): | |
img_name = 'img_' + str(i+1) + '.jpg' | |
img_path = os.path.join(img_dir, img_name) | |
img = cv2.imread(img_path) | |
gt_path = os.path.join(gt_dir, img_name + '.txt') | |
new_img_path = os.path.join(new_img_dir, img_name) | |
visu_path = os.path.join(visu_dir, img_name) | |
new_gt_path = os.path.join(new_gt_dir, 'gt_' + img_name.split('.')[0] + '.txt') | |
polygons, words = _read_gt(gt_path) | |
# print(img_name) | |
if angle == 90: | |
(h, w) = img.shape[:2] | |
img = cv2.transpose(img) | |
img = cv2.flip(img,flipCode=0) | |
# M = cv2.getRotationMatrix2D(center, 90, 1) | |
# img = cv2.warpAffine(img, M, (h, w)) | |
new_polygons = [[polygon[1], w-polygon[0], polygon[3], w-polygon[2], polygon[5], w-polygon[4], polygon[7], w-polygon[6]] for polygon in polygons] | |
else: | |
img, new_polygons = _rotate_image(img, polygons, angle) | |
format_new_gt(new_polygons, words, new_gt_path) | |
# visu_gt(img, new_polygons, visu_path) | |
cv2.imwrite(new_img_path, img) | |