-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalibrate
executable file
·67 lines (61 loc) · 2.53 KB
/
calibrate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/usr/bin/python
from ast import literal_eval
import argparse
import cv2
import numpy as np
import pickle
def order_corners(corners):
print(corners)
rect = np.zeros((4, 2), dtype=np.float32)
s = corners.sum(axis = 1)
rect[0] = corners[np.argmin(s)]
rect[2] = corners[np.argmax(s)]
diff = np.diff(corners, axis = 1)
rect[1] = corners[np.argmin(diff)]
rect[3] = corners[np.argmax(diff)]
print(rect)
return rect
class ParseCoords(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
if nargs is not None:
raise ValueError("nargs not allowed")
super(ParseCoords, self).__init__(option_strings, dest, **kwargs)
def __call__(self, parser, namespace, values, option_string=None):
strings = values.split(' ')
if (len(strings) != 4):
raise ValueError("more than 4 tuples found, make sure there are no spaces inside")
coords = []
for c in map(literal_eval, strings):
coords.append(c)
setattr(namespace, self.dest, order_corners(np.array(coords)))
def save_calibration(c, path):
with open(path, 'wb') as file:
pickle.dump(c, file)
def print_calibration(c):
print('source resolution: ', c['source'])
print('target resolution: ', c['target'])
print('transformation:\n', c['matrix'])
def main():
parser = argparse.ArgumentParser(description='AmbiCam calibration utility')
parser.add_argument('image', help='input image file')
parser.add_argument('corners', action=ParseCoords,
help='coordinates of screen corners; top left, top right, bottom right and bottom left; each as (x,y) tuple')
parser.add_argument('-c', '--calibration', default='ambicam.calib',
help='path to store the calibration result')
options = parser.parse_args()
image = cv2.imread(options.image)
corners = options.corners
width = min(np.linalg.norm(corners[0] - corners[1]),
np.linalg.norm(corners[2] - corners[3]))
height = min(np.linalg.norm(corners[0] - corners[3]),
np.linalg.norm(corners[1] - corners[2]))
dst = np.array([[0, 0],
[width, 0],
[width, height],
[0, height]], dtype=np.float32)
M = cv2.getPerspectiveTransform(corners, dst)
c = dict(matrix=M, target=(width,height), source=(image.shape[1], image.shape[0]), corners=corners)
save_calibration(c, options.calibration)
print_calibration(c)
if __name__ == '__main__':
main()