-
Notifications
You must be signed in to change notification settings - Fork 0
/
pyrcorrect.py
141 lines (107 loc) · 4.49 KB
/
pyrcorrect.py
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
from projection import Correction
from pyramid_constraint import Pyramid, Constraint
import numpy
import cv2
class PyrCorrect(Correction):
def __init__(self, **kw):
Correction.__init__(self, **kw)
#self.full_target = 50*numpy.ones((self.H, self.W, 3), dtype=numpy.uint8)
self.set_pyr_level(7)
self.coeff = 0.5
cv2.namedWindow("error")
cv2.namedWindow("correction")
cv2.createTrackbar("coeff", "correction", 5, 100, lambda x: self.set_coeff(x/10.0))
cv2.createTrackbar("pyr level", "correction", 7, 10, self.set_pyr_level)
def set_coeff(self, newval):
self.uncorrect()
self.coeff = newval
self.correct()
def onkey(self, key):
Correction.onkey(self, key)
if key == 'p':
self.constraint.next()
self.p_correction = None
if key == 'a':
for i in range(5):
self.constraint.next()
self.p_correction = None
def set_pyr_level(self, level):
self.pyr = Pyramid(level=level, size=(self.W, self.H))
#self.target = self.pyr.down(self.full_target)
self.measured = None
self.d_measured = None
self.error = None
self.d_error = None
self.p_correction = None
self.d_correction = None
self.errorlog = []
self.constraint = Constraint(size=self.pyr.down_size())
def filter(self, im):
#im = im.mean(axis=2).astype(numpy.uint8) # grayscale
new_measured = self.pyr.down(im)
if self.measured is not None:
self.d_measured = new_measured - self.measured
self.measured = new_measured
return im
def get_error(self):
new_error = self.measured - self.target
if self.error is not None:
self.d_error = new_error - self.error
total_d_error = numpy.sum(self.d_error)
print 'change in error', total_d_error
return new_error
def get_target(self):
return self.measured.mean().clip(50,200) * numpy.ones(self.measured.shape, dtype=numpy.uint8)
def update_level(self):
# total_error = numpy.sum(numpy.abs(self.error))
# maxerr = numpy.abs(self.error).max()
# self.errorlog.append(total_error)
# print 'total error', total_error, 'max_error', maxerr
# if len(self.errorlog) > 5:
# print 'errorlog', self.errorlog
# if self.errorlog[-1] >= 1.05*self.errorlog[-2]:
# print 'increase in error -- going back'
# return self.pyr.level + 1
# elif self.errorlog[-1] >= 0.95*self.errorlog[-2]:
# print 'pretty good! moving on'
# return self.pyr.level - 1
pass
def get_correction(self):
self.p_d_correction = self.d_correction
self.d_correction = numpy.zeros(self.error.shape)
constraint = self.constraint.next()
self.d_correction[constraint] = - self.error[constraint]
# # normalize
# self.d_correction *= 128 / max(1, abs(self.d_correction).max())
self.d_correction = (self.d_correction.astype(int) * self.coeff).clip(-128,127)
# center on 128 & convert to uint
self.d_correction += 128
self.d_correction = self.d_correction.astype(numpy.uint8)
d_correction_full = self.pyr.up(self.d_correction)
return (self.correction.astype(int) + d_correction_full.reshape((self.correction.shape[0], self.correction.shape[1], -1)) - 128).clip(0, 255).astype(numpy.uint8)
def correct(self):
self.raw_transformed = self.filter(self.transformed)
self.target = self.get_target()
self.error = self.get_error()
cv2.imshow("error",
cv2.resize(self.error, (400,300)))
newlevel = self.update_level()
if newlevel is not None:
self.set_pyr_level(newlevel)
return self.correct()
self.p_correction = self.correction
self.correction = self.get_correction()
cv2.imshow("correction",
cv2.resize(self.d_correction,
(400,300)))
self.render_projector()
def uncorrect(self):
self.constraint.prev()
if self.p_correction is not None:
self.correction = self.p_correction
self.render_projector()
if __name__=='__main__':
p = PyrCorrect(W=1920, H=1200, record = True)
# p = PyrCorrect(W=600, H=400, record = True)
p.iterate()
p.run()