11 # size of block that will be matched
12 # (correlate a block this size against a block with added slippage all around)
16 # pitch between the block centres
20 # allowable +/- slippage between pairs
29 in_jpg0 = 'tank_battle/down_2364.jpg'
30 in_jpg1 = 'tank_battle/down_2365.jpg'
31 out_jpg0 = 'out0_2364.jpg'
32 out_jpg1 = 'out0_2365.jpg'
34 print(f'read {in_jpg0:s}')
35 image0 = gamma.read_image(in_jpg0)
38 sys.stderr.write(f'write {out_jpg0:s}\n')
39 gamma.write_image(out_jpg0, image0)
41 print(f'read {in_jpg1:s}')
42 image1 = gamma.read_image(in_jpg1)
43 assert image1.shape == shape
46 xb = (xs // 2 - XM - 2 * XS) // XP
47 yb = (ys // 2 - YM - 2 * YS) // YP
48 print('xb', xb, 'yb', yb)
51 _, _, cs = image.shape
54 scipy.ndimage.gaussian_filter(image[:, :, i], CUTOFF1, mode = 'mirror') -
55 scipy.ndimage.gaussian_filter(image[:, :, i], CUTOFF0, mode = 'mirror')
61 def correlate(image0_bp, image1_bp, xc, yc):
64 x1 = xc - XM // 2 - XS
65 y1 = yc - YM // 2 - YS
78 # note: swapping block1, block0 flips the output (subtracts x and y
79 # from BLOCK_SIZE) and we need this to find matching part of image1
83 scipy.signal.correlate(
94 #temp = corr - numpy.mean(corr)
95 #temp /= 10. * numpy.sqrt(numpy.mean(numpy.square(temp)))
96 #gamma.write_image(f'corr_{i:d}_{j:d}.jpg', temp + .5)
98 y, x = numpy.unravel_index(numpy.argmax(corr), corr.shape)
103 x <= XS * 2 - CUTOFF1 and
105 y <= YS * 2 - CUTOFF1
111 image0_bp = bandpass(image0)
112 gamma.write_image('image0_bp.jpg', image0_bp + .5)
115 image1_bp = bandpass(image1)
116 gamma.write_image('image1_bp.jpg', image1_bp + .5)
118 print('find corner candidates')
121 corner_candidates = []
124 # correlate blocks in (i, j)-corner
128 yc = YS + YM // 2 + k * YP
132 xc = XS + XM // 2 + l * XP
135 offset = correlate(image0_bp, image1_bp, xc, yc)
136 if offset is not None:
137 offsets.append(offset)
141 #print('i', i, 'j', j, 'k', k, 'l', l, 'x', x, 'y', y)
142 p_all.append(numpy.array([xc, yc], numpy.double))
143 q_all.append(numpy.array([xc1, yc1], numpy.double))
144 blocks.append((xc, yc, xc1, yc1))
146 # find the trend in (i, j)-corner
148 xm = sorted([x for x, _ in offsets])[k]
149 ym = sorted([y for _, y in offsets])[k]
150 #print('i', i, 'j', j, 'xm', xm, 'ym', ym)
152 # choose CORNER_CANDIDATES blocks closest to trend in (i, j)-corner
153 u = numpy.array(offsets, numpy.double)
154 v = numpy.array([xm, ym], numpy.double)
155 dist = numpy.sum(numpy.square(u - v[numpy.newaxis, :]), 1)
156 corner_candidates.append(
158 [(dist[i],) + blocks[i] for i in range(len(blocks))]
159 )[:CORNER_CANDIDATES]
161 p_all = numpy.stack(p_all, 1)
162 q_all = numpy.stack(q_all, 1)
164 # try all combinations of the corner candidates
165 print('try corner candidates')
166 p = numpy.zeros((2, 4), numpy.double)
167 q = numpy.zeros((2, 4), numpy.double)
170 for _, xc00, yc00, xc10, yc10 in corner_candidates[0]:
175 for _, xc01, yc01, xc11, yc11 in corner_candidates[1]:
180 for _, xc02, yc02, xc12, yc12 in corner_candidates[2]:
185 for _, xc03, yc03, xc13, yc13 in corner_candidates[3]:
191 A = perspective.calc_transform(p, q)
194 q_all - perspective.apply_transform_multi(A, p_all)
197 if best_dist is None or dist < best_dist:
202 out_image1 = perspective.remap_image(best_A, image1)
204 sys.stderr.write(f'write {out_jpg1:s}\n')
205 gamma.write_image(out_jpg1, out_image1)