11 # a BLOCKS x BLOCKS section is correlated with a (BLOCKS + 1) x (BLOCKS + 1)
12 # the maximum allowable shift is BLOCK_SIZE with BLOCKS of surrounding context
19 in_jpg0 = 'tank_battle/down_2364.jpg'
20 in_jpg1 = 'tank_battle/down_2365.jpg'
21 out_jpg0 = 'out0_2364.jpg'
22 out_jpg1 = 'out0_2365.jpg'
24 print(f'read {in_jpg0:s}')
25 image0 = gamma.read_image(in_jpg0)
28 sys.stderr.write(f'write {out_jpg0:s}\n')
29 gamma.write_image(out_jpg0, image0)
31 print(f'read {in_jpg1:s}')
32 image1 = gamma.read_image(in_jpg1)
33 assert image1.shape == shape
38 print('xb', xb, 'yb', yb)
41 _, _, cs = image.shape
44 scipy.ndimage.gaussian_filter(image[:, :, i], CUTOFF1, mode = 'mirror') -
45 scipy.ndimage.gaussian_filter(image[:, :, i], CUTOFF0, mode = 'mirror')
51 def correlate(image0_bp, image1_bp, xc, yc):
52 x0 = xc - BLOCKS * BLOCK_SIZE // 2
53 y0 = yc - BLOCKS * BLOCK_SIZE // 2
54 x1 = xc - (BLOCKS + 1) * BLOCK_SIZE // 2
55 y1 = yc - (BLOCKS + 1) * BLOCK_SIZE // 2
58 y0:y0 + BLOCK_SIZE * BLOCKS,
59 x0:x0 + BLOCK_SIZE * BLOCKS,
63 y1:y1 + (BLOCKS + 1) * BLOCK_SIZE,
64 x1:x1 + (BLOCKS + 1) * BLOCK_SIZE,
68 # note: swapping block1, block0 flips the output (subtracts x and y
69 # from BLOCK_SIZE) and we need this to find matching part of image1
73 scipy.signal.correlate(
84 #temp = corr - numpy.mean(corr)
85 #temp /= 10. * numpy.sqrt(numpy.mean(numpy.square(temp)))
86 #gamma.write_image(f'corr_{i:d}_{j:d}.jpg', temp + .5)
88 y, x = numpy.unravel_index(numpy.argmax(corr), corr.shape)
90 (x - BLOCK_SIZE // 2, y - BLOCK_SIZE // 2)
93 x <= BLOCK_SIZE - CUTOFF1 and
95 y <= BLOCK_SIZE - CUTOFF1
101 image0_bp = bandpass(image0)
102 gamma.write_image('image0_bp.jpg', image0_bp + .5)
105 image1_bp = bandpass(image1)
106 gamma.write_image('image1_bp.jpg', image1_bp + .5)
109 buckets = [[[], []], [[], []]]
110 for i in range(yb - BLOCKS):
111 yc = i * BLOCK_SIZE + (BLOCKS + 1) * BLOCK_SIZE // 2
112 for j in range(xb - BLOCKS):
113 xc = j * BLOCK_SIZE + (BLOCKS + 1) * BLOCK_SIZE // 2
114 offset = correlate(image0_bp, image1_bp, xc, yc)
115 if offset is not None:
117 print('i', i, 'j', j, 'x', x, 'y', y)
118 buckets[i >= (yb - BLOCKS) // 2][j >= (xb - BLOCKS) // 2].append(
119 (xc, yc, xc + x, yc + y)
126 k = len(buckets[i][j]) // 2
127 offset = [(xc1 - xc0, yc1 - yc0) for xc0, yc0, xc1, yc1 in buckets[i][j]]
128 xm = sorted([x for x, _ in offset])[k]
129 ym = sorted([y for _, y in offset])[k]
130 #print('i', i, 'j', j, 'xm', xm, 'ym', ym)
131 u = numpy.array(offset, numpy.double)
132 v = numpy.array([xm, ym], numpy.double)
133 k = numpy.argmin(numpy.sum(numpy.square(u - v[numpy.newaxis, :]), 1))
134 xc0, yc0, xc1, yc1 = buckets[i][j][k]
135 #print('i', i, 'j', j, 'x', x, 'y', y)
136 p.append(numpy.array([xc0, yc0], numpy.double))
137 q.append(numpy.array([xc1, yc1], numpy.double))
138 p = numpy.stack(p, 1)
139 q = numpy.stack(q, 1)
140 A = perspective.calc_transform(p, q)
143 out_image1 = perspective.remap_image(A, image1)
145 sys.stderr.write(f'write {out_jpg1:s}\n')
146 gamma.write_image(out_jpg1, out_image1)