Image Registration

Loading the wattled image

01. import ia870
02. import cv2
03. import cv
04. import numpy as np
05. import ia636
06. from scipy.spatial import KDTree
07. 
08. print 'CV2 version:', cv2.__version__
09. 
10. f = adreadgray('tvframe.pgm')
11. adshow(f, 'Wattled image, the even lines of the image were captured \
12.            with a 1/60s delay in relation to the odd lines')
CV2 version: 2.4.6.1

Wattled image, the even lines of the image were captured with a 1/60s delay in relation to the odd lines

Separating the images to be registered

1. img1 = f[::2,:].astype('uint8')
2. adshow(img1, 'Image 01 - even lines')
3. 
4. img2 = f[1::2,:].astype('uint8')
5. adshow(img2,'Image 02 - odd lines')

Image 01 - even lines

Image 02 - odd lines

Computing SURF

01. surf = cv2.SURF(400)
02. kp,descriptors = surf.detectAndCompute(img1,None)
03. 
04. 
05. # Drawing image 1 with the SURF points
06. img1_color = cv2.cvtColor(img1,cv2.COLOR_GRAY2BGR)
07. for k in kp:
08.    cv2.circle(img1_color,(int(k.pt[0]),int(k.pt[1])),2,(0,255,0),-1)
09. 
10. img1_color = np.transpose(img1_color,(2,0,1))
11. adshow(img1_color, 'SURF points image 01')
12. 
13. keys,desc = surf.detectAndCompute(img2,None)
14. 
15. # Drawing image 2 with the SURF points
16. img2_color = cv2.cvtColor(img2,cv2.COLOR_GRAY2BGR)
17. for k in keys:
18.    cv2.circle(img2_color,(int(k.pt[0]),int(k.pt[1])),2,(0,255,0),-1)
19. 
20. 
21. img2_color = np.transpose(img2_color,(2,0,1))
22. adshow(img2_color,'SURF points image 02')

SURF points image 01

SURF points image 02

Matching SURF points

01. tree = KDTree(descriptors) #  kd-tree object
02. 
03. # Looking for the best matches (euclidean distance)
04. distances,indexes1 = tree.query(desc)
05. indexes2 = arange(len(indexes1)).astype(int)
06. 
07. 
08. # Choosing the best 3 matches
09. indexes3 = np.argsort(distances)[0:3]
10. distances = distances[indexes3]
11. indexes1 = indexes1[indexes3]
12. indexes2 = indexes2[indexes3]
13. 
14. l,c = img2.shape
15. 
16. img1_color2 = cv2.cvtColor(img1,cv2.COLOR_GRAY2BGR)
17. for k in indexes1:
18.    cv2.circle(img1_color2,(int(kp[k].pt[0]),int(kp[k].pt[1])),
19.                            2,(0,255,0),-1)
20.    cv2.circle(img1_color2,(int(kp[k].pt[0]),int(kp[k].pt[1])),
21.                            int(kp[k].size),(0,255,0),2)
22. 
23. 
24. img1_color2 = np.transpose(img1_color2,(2,0,1))
25. 
26. img2_color2 = cv2.cvtColor(img2,cv2.COLOR_GRAY2BGR)
27. for k in indexes2:
28.    cv2.circle(img2_color2,(int(keys[k].pt[0]),int(keys[k].pt[1])),
29.                            2,(0,255,0),-1)
30.    cv2.circle(img2_color2,(int(keys[k].pt[0]),int(keys[k].pt[1])),
31.                            int(keys[k].size),(0,255,0),2)
32. 
33. img2_color2 = np.transpose(img2_color2,(2,0,1))
34. 
35. img_composed = np.concatenate((img1_color2, img2_color2), axis = 2)
36. 
37. draw = adDraw(img_composed, rgb=1)
38. for i in xrange(3):
39.    k = indexes1[i]
40.    k2 = indexes2[i]
41.    draw.line((int(kp[k].pt[0]),int(kp[k].pt[1]),int(keys[k2].pt[0]+c),
42.               int(keys[k2].pt[1])), fill=(255,0,0))
43. 
44. img_composed = draw.get_image()
45. 
46. adshow(img_composed, 'Image showing the 3 best SURF point matches')

Image showing the 3 best SURF point matches

Registering the images

01. # Calculating the affine transform
02. img1_points = np.array([[kp[indexes1[0]].pt[0], kp[indexes1[0]].pt[1]],
03.                         [kp[indexes1[1]].pt[0], kp[indexes1[1]].pt[1]],
04.                         [kp[indexes1[2]].pt[0], kp[indexes1[2]].pt[1]]],
05.                         dtype = 'float32')
06. img2_points = np.array([[keys[indexes2[0]].pt[0], keys[indexes2[0]].pt[1]],
07.                         [keys[indexes2[1]].pt[0], keys[indexes2[1]].pt[1]],
08.                         [keys[indexes2[2]].pt[0], keys[indexes2[2]].pt[1]]],
09.                         dtype = 'float32')
10. 
11. T = cv2.getAffineTransform(img2_points,img1_points)
12. np.set_printoptions(suppress=True, precision=3)
13. print  'Affine transformation matrix T: \n', T
14. 
15. # Transforming  image 2 to the coordinates system of image 1
16. g = cv2.warpAffine(img2,T, dsize = (c,l))
17. adshow(g, 'Image 02 after the affine transformation')
18. 
19. 
20. 
21. # Composition of the registered images
22. g2 = zeros_like(f)
23. g2[1::2,:] = img1
24. g2[ ::2,:] = g
25. adshow(g2, 'Composition of the 2 registered images')
Affine transformation matrix T: 
[[  0.979   0.108 -34.897]
 [ -0.013   0.991  -6.446]]

Image 02 after the affine transformation

Composition of the 2 registered images