Merge in RR/cv-analysis from add-pdf-coord-conversion to master
Squashed commit of the following:
commit f56b7b45feb78142b032ef0faae2ca8dd020e6c5
Author: Julius Unverfehrt <julius.unverfehrt@iqser.com>
Date: Thu Jul 7 11:26:46 2022 +0200
update pyinfra
commit 9086ef0a2059688fb8dd5559cda831bbbd36362b
Author: Julius Unverfehrt <julius.unverfehrt@iqser.com>
Date: Thu Jul 7 11:21:53 2022 +0200
update inpout metadata keys
commit 55f147a5848e22ea62242ea883a0ce53ef1c04a5
Author: Julius Unverfehrt <julius.unverfehrt@iqser.com>
Date: Thu Jul 7 09:16:16 2022 +0200
update to new input metadata signature
commit df4652fb027f734f2613e4adb7bc5b17edee62e9
Author: Julius Unverfehrt <julius.unverfehrt@iqser.com>
Date: Wed Jul 6 16:55:36 2022 +0200
refactor
commit e52c674085a9c7411c55a2e0993aa34622284317
Author: Julius Unverfehrt <julius.unverfehrt@iqser.com>
Date: Wed Jul 6 16:15:21 2022 +0200
update build script, refactor
commit 1f874aea591f25544aaa3f39a4e38fa50a24615e
Author: Julius Unverfehrt <julius.unverfehrt@iqser.com>
Date: Tue Jul 5 17:01:15 2022 +0200
add rotation formatter
commit b78a69741287a4cd38a90ace98f67e8f1b803737
Author: Julius Unverfehrt <julius.unverfehrt@iqser.com>
Date: Tue Jul 5 09:26:27 2022 +0200
refactor
commit b3155b8e072530f99114f3ee9135e73afc8f85cb
Author: Julius Unverfehrt <julius.unverfehrt@iqser.com>
Date: Fri Jul 1 15:06:45 2022 +0200
made assertion robust to floating point precision
commit 4169102a6b5053500a3db2d789d265c2c77d56a4
Author: Julius Unverfehrt <julius.unverfehrt@iqser.com>
Date: Fri Jul 1 15:06:01 2022 +0200
improve banner
commit dea74593d925c802489e5400297b48a9729038f0
Author: Julius Unverfehrt <julius.unverfehrt@iqser.com>
Date: Fri Jul 1 14:28:08 2022 +0200
introduce derotation logic for rectangles from rotated pdfs, introduce continious option for coordinates in Rectangle class
commit d07e1dc2731ea7ae9887cc02bb98155bf1565a0d
Author: Julius Unverfehrt <julius.unverfehrt@iqser.com>
Date: Fri Jul 1 10:39:38 2022 +0200
introduce table parsing formatter to convert pixel values to inches
commit 67ff6730dd7073a0fc9e9698904325dea9537c5b
Author: Julius Unverfehrt <julius.unverfehrt@iqser.com>
Date: Fri Jul 1 08:06:42 2022 +0200
fixed duplicate logging
commit 6c025409415329028f697bb99986cd0912c7ed54
Author: Julius Unverfehrt <julius.unverfehrt@iqser.com>
Date: Thu Jun 30 17:10:32 2022 +0200
add pyinfra mock script
112 lines
3.8 KiB
Python
112 lines
3.8 KiB
Python
from _operator import itemgetter
|
|
from functools import partial
|
|
|
|
import numpy as np
|
|
|
|
from cv_analysis.utils.structures import Rectangle
|
|
|
|
|
|
def make_formatter(dpi, page_size, rotation):
|
|
rotation = rotation // 90 if rotation not in [0, 1, 2, 3] else rotation
|
|
|
|
def format_(key2pixel):
|
|
convert = partial(convert_pixel_to_inch, dpi=dpi)
|
|
x, y, w, h = map(convert, itemgetter("x", "y", "width", "height")(key2pixel))
|
|
x1, y1 = x + w, y + h
|
|
matrix = np.vstack([[x, y], [x1, y1]]).T
|
|
new_matrix = rotate_and_shift(matrix, rotation, page_size)
|
|
x1, x2 = sorted(new_matrix[0, :])
|
|
y1, y2 = sorted(new_matrix[1, :])
|
|
return Rectangle.from_xyxy((x1, y1, x2, y2), discrete=False).json_xywh()
|
|
|
|
return format_
|
|
|
|
|
|
def convert_pixel_to_inch(pixel, dpi):
|
|
return pixel / dpi * 72
|
|
|
|
|
|
def rotate(input_matrix, radians):
|
|
rotation_matrix = np.vstack([[np.cos(radians), -np.sin(radians)], [np.sin(radians), np.cos(radians)]])
|
|
|
|
return np.dot(rotation_matrix, input_matrix)
|
|
|
|
|
|
def rotate_and_shift(matrix, rotation, size, debug=False):
|
|
"""Rotates a matrix against (!) a specified rotation. That is, the rotation is applied negatively. The matrix is
|
|
also shifted to ensure it contains points (columns) in quadrant I.
|
|
|
|
Procedure:
|
|
1) Rotate the matrix clockwise according to rotation value
|
|
2) Shift the matrix back into quadrant I
|
|
3) Set x_i and y_i to new lower left and upper right corners, since the corner vectors are no longer at these
|
|
corners due to the rotation
|
|
|
|
Args:
|
|
matrix: matrix to transform
|
|
rotation: any of 0, 1, 2, or 3, where 1 = 90 degree CLOCKWISE rotation etc.
|
|
size: the size of the page as a tuple (<width>, <height>)
|
|
debug: Visualizes the transformations for later re-understanding of the code
|
|
"""
|
|
|
|
def shift_to_quadrant_1(matrix):
|
|
|
|
# TODO: generalize
|
|
if rotation == 0:
|
|
back_shift = np.zeros_like(np.eye(2))
|
|
elif rotation == 1:
|
|
back_shift = np.array([[0, 0], [1, 1]]) * size[1]
|
|
elif rotation == 2:
|
|
back_shift = np.array([[1, 1], [1, 1]]) * size
|
|
elif rotation == 3:
|
|
back_shift = np.array([[1, 1], [0, 0]]) * size[0]
|
|
else:
|
|
raise ValueError(f"Unexpected rotation value '{rotation}'. Expected any of 0, 1, 2, or 3.")
|
|
|
|
matrix_shifted = matrix + back_shift
|
|
return matrix_shifted
|
|
|
|
# PDF rotations are clockwise, hence subtract the radian value of the rotation from 2 pi
|
|
radians = (2 * np.pi) - (np.pi * (rotation / 2))
|
|
matrix_rotated = rotate(matrix, radians)
|
|
matrix_rotated_and_shifted = shift_to_quadrant_1(matrix_rotated)
|
|
|
|
if debug:
|
|
__show_matrices(size, radians, matrix, matrix_rotated, matrix_rotated_and_shifted)
|
|
return matrix_rotated_and_shifted
|
|
|
|
|
|
def __show_matrices(size, radians, matrix, matrix_rotated, matrix_rotated_and_shifted):
|
|
|
|
import matplotlib.pyplot as plt
|
|
from copy import deepcopy
|
|
|
|
m1 = matrix
|
|
m2 = matrix_rotated
|
|
m3 = matrix_rotated_and_shifted
|
|
|
|
m1, m2, m3 = map(deepcopy, (m1, m2, m3))
|
|
|
|
frame = np.eye(2) * size
|
|
frame_rotated = rotate(frame, radians)
|
|
|
|
f1 = frame
|
|
f2 = frame_rotated
|
|
|
|
f1 *= 0.005 * 1
|
|
f2 *= 0.005 * 1
|
|
m1 *= 0.005 * 1
|
|
m2 *= 0.005 * 1
|
|
m3 *= 0.005 * 1
|
|
|
|
fig, axes = plt.subplots(1, 2, figsize=(8, 4))
|
|
axes = axes.ravel()
|
|
|
|
axes[0].quiver([0, 0], [0, 0], f1[0, :], f1[1, :], scale=5, scale_units="inches", color="red")
|
|
axes[1].quiver([0, 0], [0, 0], f2[0, :], f2[1, :], scale=5, scale_units="inches", color="red")
|
|
axes[0].quiver([0, 0], [0, 0], m1[0, :], m1[1, :], scale=5, scale_units="inches")
|
|
axes[1].quiver([0, 0], [0, 0], m2[0, :], m2[1, :], scale=5, scale_units="inches", color="green")
|
|
axes[1].quiver([0, 0], [0, 0], m3[0, :], m3[1, :], scale=5, scale_units="inches", color="blue")
|
|
|
|
plt.show()
|