Proof of concept automatic alignment routine using correlation
authorNick Downing <nick@ndcode.org>
Tue, 8 Feb 2022 23:46:51 +0000 (10:46 +1100)
committerNick Downing <nick@ndcode.org>
Tue, 8 Feb 2022 23:46:51 +0000 (10:46 +1100)
40 files changed:
correlate.py [new file with mode: 0755]
tank_battle/IMG_2364.jpg [new file with mode: 0644]
tank_battle/IMG_2365.jpg [new file with mode: 0644]
tank_battle/IMG_2366.jpg [new file with mode: 0644]
tank_battle/IMG_2367.jpg [new file with mode: 0644]
tank_battle/IMG_2368.jpg [new file with mode: 0644]
tank_battle/IMG_2369.jpg [new file with mode: 0644]
tank_battle/IMG_2370.jpg [new file with mode: 0644]
tank_battle/IMG_2371.jpg [new file with mode: 0644]
tank_battle/IMG_2372.jpg [new file with mode: 0644]
tank_battle/IMG_2373.jpg [new file with mode: 0644]
tank_battle/IMG_2374.jpg [new file with mode: 0644]
tank_battle/IMG_2375.jpg [new file with mode: 0644]
tank_battle/IMG_2376.jpg [new file with mode: 0644]
tank_battle/IMG_2377.jpg [new file with mode: 0644]
tank_battle/IMG_2378.jpg [new file with mode: 0644]
tank_battle/IMG_2379.jpg [new file with mode: 0644]
tank_battle/IMG_2380.jpg [new file with mode: 0644]
tank_battle/IMG_2381.jpg [new file with mode: 0644]
tank_battle/IMG_2382.jpg [new file with mode: 0644]
tank_battle/IMG_2383.jpg [new file with mode: 0644]
tank_battle/IMG_2384.jpg [new file with mode: 0644]
tank_battle/IMG_2385.jpg [new file with mode: 0644]
tank_battle/IMG_2386.jpg [new file with mode: 0644]
tank_battle/IMG_2387.jpg [new file with mode: 0644]
tank_battle/IMG_2388.jpg [new file with mode: 0644]
tank_battle/IMG_2389.jpg [new file with mode: 0644]
tank_battle/IMG_2390.jpg [new file with mode: 0644]
tank_battle/IMG_2391.jpg [new file with mode: 0644]
tank_battle/IMG_2392.jpg [new file with mode: 0644]
tank_battle/IMG_2393.jpg [new file with mode: 0644]
tank_battle/IMG_2394.jpg [new file with mode: 0644]
tank_battle/IMG_2395.jpg [new file with mode: 0644]
tank_battle/IMG_2396.jpg [new file with mode: 0644]
tank_battle/IMG_2397.jpg [new file with mode: 0644]
tank_battle/IMG_2398.jpg [new file with mode: 0644]
tank_battle/IMG_2399.jpg [new file with mode: 0644]
tank_battle/IMG_2400.jpg [new file with mode: 0644]
tank_battle/IMG_2401.jpg [new file with mode: 0644]
tank_battle/down.sh [new file with mode: 0755]

diff --git a/correlate.py b/correlate.py
new file mode 100755 (executable)
index 0000000..e56c77f
--- /dev/null
@@ -0,0 +1,182 @@
+#!/usr/bin/env python3
+
+import gamma
+import numpy
+import perspective
+import scipy
+import scipy.ndimage
+import scipy.signal
+import sys
+
+# a BLOCKS x BLOCKS section is correlated with a (BLOCKS + 1) x (BLOCKS + 1)
+# the maximum allowable shift is BLOCK_SIZE with BLOCKS of surrounding context
+BLOCKS = 4
+BLOCK_SIZE = 64
+
+CUTOFF0 = 64
+CUTOFF1 = 4
+
+in_jpg0 = 'tank_battle/down_2364.jpg'
+in_jpg1 = 'tank_battle/down_2365.jpg'
+out_jpg0 = 'out0_2364.jpg'
+out_jpg1 = 'out0_2365.jpg'
+
+print(f'read {in_jpg0:s}')
+image0 = gamma.read_image(in_jpg0)
+shape = image0.shape
+
+sys.stderr.write(f'write {out_jpg0:s}\n')
+gamma.write_image(out_jpg0, image0)
+
+print(f'read {in_jpg1:s}')
+image1 = gamma.read_image(in_jpg1)
+assert image1.shape == shape
+
+ys, xs, cs = shape
+xb = xs // BLOCK_SIZE
+yb = ys // BLOCK_SIZE
+print('xb', xb, 'yb', yb)
+
+print('bp0')
+image0_lp0 = numpy.stack(
+  [
+    scipy.ndimage.gaussian_filter(image0[:, :, i], CUTOFF0, mode = 'mirror')
+    for i in range(cs)
+  ],
+  2
+)
+image0_lp1 = numpy.stack(
+  [
+    scipy.ndimage.gaussian_filter(image0[:, :, i], CUTOFF1, mode = 'mirror')
+    for i in range(cs)
+  ],
+  2
+)
+image0_bp = image0_lp1 - image0_lp0
+gamma.write_image('image0_bp.jpg', image0_bp + .5)
+
+print('bp1')
+image1_lp0 = numpy.stack(
+  [
+    scipy.ndimage.gaussian_filter(image1[:, :, i], CUTOFF0, mode = 'mirror')
+    for i in range(cs)
+  ],
+  2
+)
+image1_lp1 = numpy.stack(
+  [
+    scipy.ndimage.gaussian_filter(image1[:, :, i], CUTOFF1, mode = 'mirror')
+    for i in range(cs)
+  ],
+  2
+)
+image1_bp = image1_lp1 - image1_lp0
+gamma.write_image('image1_bp.jpg', image1_bp + .5)
+
+print('align')
+buckets = [[[], []], [[], []]]
+for i in range(yb - BLOCKS):
+  y1 = i * BLOCK_SIZE
+  y0 = y1 + BLOCK_SIZE // 2
+  for j in range(xb - BLOCKS):
+    x1 = j * BLOCK_SIZE
+    x0 = x1 + BLOCK_SIZE // 2
+
+    block0 = image0_bp[
+      y0:y0 + BLOCK_SIZE * BLOCKS,
+      x0:x0 + BLOCK_SIZE * BLOCKS,
+      :
+    ]
+    block1 = image1_bp[
+      y1:y1 + BLOCK_SIZE * (BLOCKS + 1),
+      x1:x1 + BLOCK_SIZE * (BLOCKS + 1),
+      :
+    ]
+
+    # note: swapping block1, block0 flips the output (subtracts x and y
+    # from BLOCK_SIZE) and we need this to find matching part of image1
+    corr = numpy.sum(
+      numpy.stack(
+        [
+          scipy.signal.correlate(
+            block1[:, :, i],
+            block0[:, :, i],
+            mode = 'valid'
+          )
+          for i in range(cs)
+        ],
+        0
+      ),
+      0
+    )
+    #temp = corr - numpy.mean(corr)
+    #temp /= 10. * numpy.sqrt(numpy.mean(numpy.square(temp)))
+    #gamma.write_image(f'corr_{i:d}_{j:d}.jpg', temp + .5)
+
+    y, x = numpy.unravel_index(numpy.argmax(corr), corr.shape)
+    if (
+      y >= CUTOFF1 and
+        y <= BLOCK_SIZE - CUTOFF1 and
+        x >= CUTOFF1 and
+        x <= BLOCK_SIZE - CUTOFF1
+    ):
+      buckets[i >= (yb - BLOCKS) // 2][j >= (xb - BLOCKS) // 2].append(
+        (x0, y0, x1, y1, x, y)
+      )
+
+p = []
+q = []
+for i in range(2):
+  for j in range(2):
+    k = len(buckets[i][j]) // 2
+    xm = sorted([x for _, _, _, _, x, _ in buckets[i][j]])[k]
+    ym = sorted([y for _, _, _, _, _, y in buckets[i][j]])[k]
+    #print('i', i, 'j', j, 'xm', xm, 'ym', ym)
+    u = numpy.array(
+      [[x, y] for _, _, _, _, x, y in buckets[i][j]],
+      numpy.double
+    )
+    v = numpy.array([xm, ym], numpy.double)
+    k = numpy.argmin(numpy.sum(numpy.square(u - v[numpy.newaxis, :]), 1))
+    x0, y0, x1, y1, x, y = buckets[i][j][k]
+    #print('i', i, 'j', j, 'x', x, 'y', y)
+    p.append(
+      numpy.array(
+        [
+          x0 + (BLOCKS * BLOCK_SIZE // 2),
+          y0 + (BLOCKS * BLOCK_SIZE // 2)
+        ],
+        numpy.double
+      )
+    )
+    q.append(
+      numpy.array(
+        [
+          x1 + x + (BLOCKS * BLOCK_SIZE // 2),
+          y1 + y + (BLOCKS * BLOCK_SIZE // 2)
+        ],
+        numpy.double
+      )
+    )
+p = numpy.stack(p, 1)
+q = numpy.stack(q, 1)
+A = perspective.calc_transform(p, q)
+
+print('remap')
+coords = numpy.zeros((2, ys, xs), numpy.double)
+coords[0, :, :] = numpy.arange(ys, dtype = numpy.double)[:, numpy.newaxis]
+coords[1, :, :] = numpy.arange(xs, dtype = numpy.double)[numpy.newaxis, :]
+mapped_coords = perspective.apply_transform_multi(
+  A,
+  coords[::-1, :, :].reshape((2, ys * xs))
+).reshape(2, ys, xs)[::-1, :, :]
+out_image1 = numpy.stack(
+  [
+    scipy.ndimage.map_coordinates(image1[:, :, j], mapped_coords)
+    for j in range(cs)
+  ],
+  2
+)
+
+sys.stderr.write(f'write {out_jpg1:s}\n')
+gamma.write_image(out_jpg1, out_image1)
diff --git a/tank_battle/IMG_2364.jpg b/tank_battle/IMG_2364.jpg
new file mode 100644 (file)
index 0000000..9caa90a
Binary files /dev/null and b/tank_battle/IMG_2364.jpg differ
diff --git a/tank_battle/IMG_2365.jpg b/tank_battle/IMG_2365.jpg
new file mode 100644 (file)
index 0000000..8b90540
Binary files /dev/null and b/tank_battle/IMG_2365.jpg differ
diff --git a/tank_battle/IMG_2366.jpg b/tank_battle/IMG_2366.jpg
new file mode 100644 (file)
index 0000000..703311a
Binary files /dev/null and b/tank_battle/IMG_2366.jpg differ
diff --git a/tank_battle/IMG_2367.jpg b/tank_battle/IMG_2367.jpg
new file mode 100644 (file)
index 0000000..124c9ef
Binary files /dev/null and b/tank_battle/IMG_2367.jpg differ
diff --git a/tank_battle/IMG_2368.jpg b/tank_battle/IMG_2368.jpg
new file mode 100644 (file)
index 0000000..b3a940e
Binary files /dev/null and b/tank_battle/IMG_2368.jpg differ
diff --git a/tank_battle/IMG_2369.jpg b/tank_battle/IMG_2369.jpg
new file mode 100644 (file)
index 0000000..175d80e
Binary files /dev/null and b/tank_battle/IMG_2369.jpg differ
diff --git a/tank_battle/IMG_2370.jpg b/tank_battle/IMG_2370.jpg
new file mode 100644 (file)
index 0000000..a05eae3
Binary files /dev/null and b/tank_battle/IMG_2370.jpg differ
diff --git a/tank_battle/IMG_2371.jpg b/tank_battle/IMG_2371.jpg
new file mode 100644 (file)
index 0000000..5374f97
Binary files /dev/null and b/tank_battle/IMG_2371.jpg differ
diff --git a/tank_battle/IMG_2372.jpg b/tank_battle/IMG_2372.jpg
new file mode 100644 (file)
index 0000000..12c3fc3
Binary files /dev/null and b/tank_battle/IMG_2372.jpg differ
diff --git a/tank_battle/IMG_2373.jpg b/tank_battle/IMG_2373.jpg
new file mode 100644 (file)
index 0000000..5d5251e
Binary files /dev/null and b/tank_battle/IMG_2373.jpg differ
diff --git a/tank_battle/IMG_2374.jpg b/tank_battle/IMG_2374.jpg
new file mode 100644 (file)
index 0000000..211341e
Binary files /dev/null and b/tank_battle/IMG_2374.jpg differ
diff --git a/tank_battle/IMG_2375.jpg b/tank_battle/IMG_2375.jpg
new file mode 100644 (file)
index 0000000..58d4704
Binary files /dev/null and b/tank_battle/IMG_2375.jpg differ
diff --git a/tank_battle/IMG_2376.jpg b/tank_battle/IMG_2376.jpg
new file mode 100644 (file)
index 0000000..368cba5
Binary files /dev/null and b/tank_battle/IMG_2376.jpg differ
diff --git a/tank_battle/IMG_2377.jpg b/tank_battle/IMG_2377.jpg
new file mode 100644 (file)
index 0000000..02e930e
Binary files /dev/null and b/tank_battle/IMG_2377.jpg differ
diff --git a/tank_battle/IMG_2378.jpg b/tank_battle/IMG_2378.jpg
new file mode 100644 (file)
index 0000000..1251ae5
Binary files /dev/null and b/tank_battle/IMG_2378.jpg differ
diff --git a/tank_battle/IMG_2379.jpg b/tank_battle/IMG_2379.jpg
new file mode 100644 (file)
index 0000000..b503ea6
Binary files /dev/null and b/tank_battle/IMG_2379.jpg differ
diff --git a/tank_battle/IMG_2380.jpg b/tank_battle/IMG_2380.jpg
new file mode 100644 (file)
index 0000000..342db93
Binary files /dev/null and b/tank_battle/IMG_2380.jpg differ
diff --git a/tank_battle/IMG_2381.jpg b/tank_battle/IMG_2381.jpg
new file mode 100644 (file)
index 0000000..72b0b88
Binary files /dev/null and b/tank_battle/IMG_2381.jpg differ
diff --git a/tank_battle/IMG_2382.jpg b/tank_battle/IMG_2382.jpg
new file mode 100644 (file)
index 0000000..1b363a2
Binary files /dev/null and b/tank_battle/IMG_2382.jpg differ
diff --git a/tank_battle/IMG_2383.jpg b/tank_battle/IMG_2383.jpg
new file mode 100644 (file)
index 0000000..2ee0e76
Binary files /dev/null and b/tank_battle/IMG_2383.jpg differ
diff --git a/tank_battle/IMG_2384.jpg b/tank_battle/IMG_2384.jpg
new file mode 100644 (file)
index 0000000..78322a6
Binary files /dev/null and b/tank_battle/IMG_2384.jpg differ
diff --git a/tank_battle/IMG_2385.jpg b/tank_battle/IMG_2385.jpg
new file mode 100644 (file)
index 0000000..8eef74c
Binary files /dev/null and b/tank_battle/IMG_2385.jpg differ
diff --git a/tank_battle/IMG_2386.jpg b/tank_battle/IMG_2386.jpg
new file mode 100644 (file)
index 0000000..13b9d47
Binary files /dev/null and b/tank_battle/IMG_2386.jpg differ
diff --git a/tank_battle/IMG_2387.jpg b/tank_battle/IMG_2387.jpg
new file mode 100644 (file)
index 0000000..7af3ac9
Binary files /dev/null and b/tank_battle/IMG_2387.jpg differ
diff --git a/tank_battle/IMG_2388.jpg b/tank_battle/IMG_2388.jpg
new file mode 100644 (file)
index 0000000..4fe6c78
Binary files /dev/null and b/tank_battle/IMG_2388.jpg differ
diff --git a/tank_battle/IMG_2389.jpg b/tank_battle/IMG_2389.jpg
new file mode 100644 (file)
index 0000000..fdee50c
Binary files /dev/null and b/tank_battle/IMG_2389.jpg differ
diff --git a/tank_battle/IMG_2390.jpg b/tank_battle/IMG_2390.jpg
new file mode 100644 (file)
index 0000000..b4bc0ff
Binary files /dev/null and b/tank_battle/IMG_2390.jpg differ
diff --git a/tank_battle/IMG_2391.jpg b/tank_battle/IMG_2391.jpg
new file mode 100644 (file)
index 0000000..7d3c706
Binary files /dev/null and b/tank_battle/IMG_2391.jpg differ
diff --git a/tank_battle/IMG_2392.jpg b/tank_battle/IMG_2392.jpg
new file mode 100644 (file)
index 0000000..8b15cf8
Binary files /dev/null and b/tank_battle/IMG_2392.jpg differ
diff --git a/tank_battle/IMG_2393.jpg b/tank_battle/IMG_2393.jpg
new file mode 100644 (file)
index 0000000..0cc90dd
Binary files /dev/null and b/tank_battle/IMG_2393.jpg differ
diff --git a/tank_battle/IMG_2394.jpg b/tank_battle/IMG_2394.jpg
new file mode 100644 (file)
index 0000000..4005218
Binary files /dev/null and b/tank_battle/IMG_2394.jpg differ
diff --git a/tank_battle/IMG_2395.jpg b/tank_battle/IMG_2395.jpg
new file mode 100644 (file)
index 0000000..e76c6fd
Binary files /dev/null and b/tank_battle/IMG_2395.jpg differ
diff --git a/tank_battle/IMG_2396.jpg b/tank_battle/IMG_2396.jpg
new file mode 100644 (file)
index 0000000..4ed77f9
Binary files /dev/null and b/tank_battle/IMG_2396.jpg differ
diff --git a/tank_battle/IMG_2397.jpg b/tank_battle/IMG_2397.jpg
new file mode 100644 (file)
index 0000000..d66be42
Binary files /dev/null and b/tank_battle/IMG_2397.jpg differ
diff --git a/tank_battle/IMG_2398.jpg b/tank_battle/IMG_2398.jpg
new file mode 100644 (file)
index 0000000..3da5a1a
Binary files /dev/null and b/tank_battle/IMG_2398.jpg differ
diff --git a/tank_battle/IMG_2399.jpg b/tank_battle/IMG_2399.jpg
new file mode 100644 (file)
index 0000000..9afed31
Binary files /dev/null and b/tank_battle/IMG_2399.jpg differ
diff --git a/tank_battle/IMG_2400.jpg b/tank_battle/IMG_2400.jpg
new file mode 100644 (file)
index 0000000..2757e31
Binary files /dev/null and b/tank_battle/IMG_2400.jpg differ
diff --git a/tank_battle/IMG_2401.jpg b/tank_battle/IMG_2401.jpg
new file mode 100644 (file)
index 0000000..344638f
Binary files /dev/null and b/tank_battle/IMG_2401.jpg differ
diff --git a/tank_battle/down.sh b/tank_battle/down.sh
new file mode 100755 (executable)
index 0000000..fbbb3a8
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+for i in IMG_*.jpg
+do
+  j=`echo $i |sed -e 's/IMG/down/'`
+  convert $i -resize 2145x1428 $j
+done