In [219]:
from subprocess import call
data=open("puzzle.jpg").read()

In [220]:
# ./jpegdump puzzle.jpg |grep SOI|cut -d ' ' -f 6|cut -f 1 > jpeg_pos
lines = open("jpeg_pos").read().splitlines()
pos = map(int, lines)
print pos
for i in range(len(pos)-1):    
    with open("tt/u%03d.jpg"%i, "w") as f:
        f.write(data[pos[i]:pos[i+1]])
    # http://svn.emphy.de/nanojpeg/trunk/nanojpeg/nanojpeg.c
    call(["./jpg", "tt/u%03d.jpg"%i, "xx/u%03d.ppm"%i])
num_imgs = i+1
print num_imgs


[0, 30, 5427, 10876, 16126, 20918, 22965, 28794, 33761, 35746, 37488, 43488, 45338, 49819, 53875, 59647, 61325, 62921, 67075, 72203, 74364, 81068, 83079, 87531, 93891, 98070, 99962, 101921, 104393, 109045, 111512, 113831, 118996, 123023, 128741, 133694, 138617, 140405, 146022, 149088, 154420, 160799, 165707, 171362, 177181, 179046, 183680, 185555, 187223, 193070, 195464, 198443, 203996, 206003, 208130, 214139, 219540, 225816, 227781, 232178, 233903, 238980, 240890, 243279, 245210, 246970, 252150, 253893, 255714, 257378, 262413, 264153, 266200, 268254, 270340, 272290, 274169, 276138, 281297, 286099, 291862, 293885, 299377, 301561, 303325, 305320, 306982, 309132, 313884, 319747, 325721, 330189, 335313, 337060, 341149, 346404, 350697, 356848, 359221, 365025, 367090, 371257]
101

In [221]:
%matplotlib inline
import numpy as np
import cv2
import matplotlib.pyplot as plt
import os
import cv
import sys
from IPython.html.widgets import interact, interactive, fixed
from IPython.display import clear_output, display, HTML
from IPython.html import widgets

In [222]:
imgs = [cv2.imread("xx/u%03d.ppm"%i) for i in range(num_imgs)]

In [223]:
from IPython.display import display, Image
from io import BytesIO
import PIL
def display_img_array(ima, cvt=None, **kwargs):
      if cvt is None and len(ima.shape)==3:
        cvt = cv2.COLOR_RGB2BGR
      if cvt:
          ima = cv2.cvtColor(ima, cvt)
      im = PIL.Image.fromarray(ima)
      bio = BytesIO()
      im.save(bio, format='png')
      display(Image(bio.getvalue(), format='png', **kwargs))

In [224]:
for i in range(num_imgs):
    try:
        display_img_array(imgs[i])
    except:
        print "error", i, imgs[i]
# since imgs[0] is not valid
imgs.pop(0)


error 0 None

In [225]:
display_img_array(np.concatenate([imgs[1], imgs[0], imgs[30]], axis=1))
display_img_array(imgs[0])
display_img_array(imgs[30])



In [226]:
H,W,B =  imgs[0].shape
print H,W,B
 
def norm(v):
    v=v.flatten()-128.0
    return v/np.linalg.norm(v)
matches  = []
for img0 in imgs:
    right0 = norm( img0[:, -1:, :])
    left0 = norm( img0[:,:1, :])
    top0 =  norm( img0[:1, :, :])
    bottom0 = norm( img0[-1:, :, :])
    result = []
    for i, img in enumerate(imgs):
        right = norm( img[:, -1:, :])
        left = norm( img[:,:1, :])
        top =  norm( img[:1, :, :])
        bottom = norm( img[-1:, :, :])
        result.append( (i, np.dot(right0,left), np.dot(left0, right), np.dot(top0,bottom), np.dot(bottom0,top)) )
    rtn = []
    for d in range(1,5):
        best2 = sorted(result, reverse=True, key=lambda x:x[d])[:2]
        best = best2[0]
        second = best2[1]
        if best[d]>max(0.6, second[d]): # second is not used
            rtn.append(best[0])
        else:
            rtn.append(None)
    matches.append(rtn)
print "done"


96 128 3
done

In [227]:
def nbhd_pos(x,y):
    return [(x+1,y), (x-1,y), (x,y-1), (x,y+1)]
pos=[None]*len(imgs)
pos[0]=(0,0)
rev_pos= {(0,0): 0}
for loop_cnt in range(10):
    for i, img in enumerate(imgs):
        if pos[i]:
            # print "doing", i, pos[i]
            for j, p in enumerate(nbhd_pos(*pos[i])):
                k = matches[i][j]
                if k is None:
                    continue
                if pos[k] or p in rev_pos:
                    if pos[k]!=p or rev_pos.get(p, k)!= k:
                        #print "conflict?", p,k, pos[k], rev_pos.get(p, None)
                        pass
                    continue
                if matches[k][j^1]!=i:
                    continue
                pos[k] = p
                rev_pos[p] = k
                # print "add", p, k
    print loop_cnt, len(rev_pos)


0 30
1 58
2 79
3 99
4 100
5 100
6 100
7 100
8 100
9 100

In [228]:
min(pos), max(pos), W, H


Out[228]:
((-4, -6), (5, 3), 128, 96)

In [229]:
solution = np.concatenate([np.concatenate([imgs[rev_pos[x,y]] for x in range(-4,6)], axis=1) for y in range(-6, 4)], axis=0)
display_img_array(solution)



In [231]:
# google and find original image
import requests
# r = requests.get("http://1.bp.blogspot.com/-PGfrBVdv_Kk/U-w89DZq_UI/AAAAAAAAGZ4/i3o1fUudb5g/s1600/Taipei_101_from_afar.jpg")
r = requests.get("http://allenlyeh.files.wordpress.com/2013/12/taipei-101.jpg")
with open("orignal.jpg", "w") as f:
    f.write(r.content)
original = cv2.imread("orignal.jpg")

In [232]:
display_img_array(original)



In [233]:
sx = cv2.adaptiveBilateralFilter(solution, (5,5), 5.0)
ox = cv2.adaptiveBilateralFilter(original, (5,5), 5.0)
gray1 = cv2.cvtColor(sx, cv2.COLOR_BGR2GRAY)
gray0 = cv2.cvtColor(ox, cv2.COLOR_BGR2GRAY)
display_img_array(cv2.absdiff(ox, sx)*30)
display_img_array(cv2.absdiff(gray0, gray1)*30)



In [ ]: