Advertisement
Guest User

Untitled

a guest
Apr 26th, 2017
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.46 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2.  
  3. import sys
  4. import numpy as np
  5. from scipy.ndimage import filters
  6. from PIL import Image
  7. import matplotlib.pylab as pyl
  8. from skimage.measure import ransac
  9. from skimage.transform import ProjectiveTransform
  10. from sphinx.addnodes import desc
  11.  
  12.  
  13. def harris_matrix_algorithm(img, sigma=2):
  14.     """ step 1.1 - algorithm to compute harris corner detector response matrix """
  15.  
  16.     ix = np.zeros(img.shape)
  17.     filters.gaussian_filter(img, 1, (0, 1), output=ix)  # (1,1) -> (sigma,sigma)
  18.     iy = np.zeros(img.shape)
  19.     filters.gaussian_filter(img, 1, (1, 0), output=iy)  # (1,1) -> (sigma,sigma)
  20.  
  21.     # compute components of the Harris matrix
  22.     A = filters.gaussian_filter(ix * ix, sigma)
  23.     B = filters.gaussian_filter(ix * iy, sigma)
  24.     C = filters.gaussian_filter(iy * iy, sigma)
  25.  
  26.     # calculate trace and determinant
  27.     det_M = (A * C) - (B ** 2)
  28.     tr_M = (A + C)
  29.  
  30.     print det_M / tr_M
  31.  
  32.     # return response matrix R
  33.     return det_M / tr_M
  34.  
  35.  
  36. def get_harris_interest_points(harris_im, min_distance=10, threshold=0.2):
  37.     """ step 1.2 - select Harris corner points above a threshold and perform nonmax
  38.        suppression in a region +/- min_distance.
  39.        min_distance is the minimum number of pixels separating corner and image boundary (spec = 11)"""
  40.  
  41.     # find top corner candidates above a threshold
  42.     corner_threshold = harris_im.max() * threshold
  43.     harris_im_th = (harris_im > corner_threshold)  # expect True/False
  44.  
  45.     # find the co-ordinates of these candidates
  46.     coords = np.array(harris_im_th.nonzero()).T
  47.     # and their values
  48.     candidate_values = np.array([harris_im[c[0], c[1]] for c in coords])
  49.     indices = np.argsort(candidate_values)
  50.  
  51.     # store allowed point locations in a boolean image
  52.     allowed_locations = np.zeros(harris_im.shape, dtype='bool')
  53.     allowed_locations[min_distance:-min_distance, min_distance:-min_distance] = True
  54.  
  55.     # select best points, using nonmax suppression based on allowed_locations array (taking min_distance into account)
  56.     filtered_coords = []
  57.     for i in indices[::-1]:  # back to front
  58.         r, c = coords[i]  # note reversed indices
  59.         if allowed_locations[r, c]:
  60.             filtered_coords.append((r, c))
  61.             allowed_locations[r - min_distance:r + min_distance + 1, c - min_distance:c + min_distance + 1] = False
  62.  
  63.     return filtered_coords
  64.  
  65.  
  66. def plot_harris_interest_points(img, hips):
  67.     """ plot interest points """
  68.     pyl.figure('Harris points/corners')
  69.     pyl.imshow(img, cmap='gray')
  70.     pyl.plot([p[1] for p in hips], [p[0] for p in hips], 'ro')
  71.     pyl.axis('off')
  72.     pyl.show()
  73.  
  74.  
  75. def descriptors(img, hips, wid=5):
  76.     """ step 2 - return pixel values around harris interest points using width 2*wid+1 (=11, as per spec)
  77.                 -> points extracted with min_distance > wid """
  78.  
  79.     descriptor = []
  80.     for coords in hips:
  81.         patch = img[coords[0] - wid:coords[0] + wid + 1, coords[1] - wid:coords[1] + wid + 1].flatten()
  82.         patch = (patch - np.mean(patch)) / np.linalg.norm(patch)
  83.         descriptor.append(patch)
  84.  
  85.     return descriptor
  86.  
  87.  
  88. def match(descriptor1, descriptor2, threshold=0.95):
  89.     m1 = np.asarray(descriptor1, dtype=np.float32)
  90.     m2 = np.asarray(descriptor2, dtype=np.float32).T
  91.  
  92.     # print max(descriptor1)
  93.     # print descriptor1
  94.     R_12 = np.dot(m1, m2)
  95.     print "Max is: " + str(m1.max())
  96.     print "Max is: " + str(m2.max())
  97.     print "Max is: " + str(R_12.max())
  98.     img = Image.fromarray(R_12 * 255)
  99.     pairs = []
  100.     for r in range(R_12.shape[0]):
  101.         row_max = R_12[r][0]
  102.         max_index = (r, 0)
  103.  
  104.         for c in range(R_12.shape[1]):
  105.             # pick only one
  106.             if R_12[r][c] > threshold and R_12[r][c] > row_max:
  107.                 max_index = (r, c)
  108.                 pairs.append((r, c))
  109.  
  110.         # R_12[max_index[0]][max_index[1]] = 255
  111.  
  112.     img2 = Image.fromarray(R_12 * 255)
  113.     pyl.subplot(121)
  114.     pyl.imshow(img)
  115.     pyl.subplot(122)
  116.     pyl.imshow(R_12)
  117.     pyl.show()
  118.     print R_12.shape
  119.     return R_12, pairs
  120.  
  121.  
  122. def plot_matches(image1, image2, hips_image1, hips_image2, matches):
  123.     """ step 3.3 -  output a concatenation of images (appended side by side) showing the 'true' matches between points. """
  124.  
  125.     rows1 = image1.shape[0]
  126.     rows2 = image2.shape[0]
  127.     matches = []
  128.     # print hips_image1[0]
  129.     # print R_12.shape[1]
  130.     # print R_12.shape[0]
  131.     # for i in range(R_12.shape[0]):
  132.     #     for j in range(R_12.shape[1]):
  133.     #         if R_12[i][j] != 0:
  134.     #             matches.append(i)
  135.     #             matches.append(j)
  136.  
  137.     print matches
  138.     # select image with least rows and pad accordingly (wrt to larger image)
  139.     if rows1 < rows2:
  140.         image1 = np.concatenate((image1, np.zeros((rows2 - rows1, image1.shape[1]))), axis=0)
  141.     elif rows2 < rows1:
  142.         image2 = np.concatenate((image2, np.zeros((rows1 - rows2, image2.shape[1]))), axis=0)
  143.  
  144.     # create new image with two input images appended side-by-side, then plot matches
  145.     image3 = np.concatenate((image1, image2), axis=1)
  146.     # image3 = np.vstack((image3, image3))
  147.     pyl.figure('Both images side by side with matches plotted')  # note incorrect matches! - use RANSAC
  148.     pyl.imshow(image3, cmap="gray")
  149.     column1 = image1.shape[1]
  150.     # for i in range(0, len(matches), 2):
  151.     for i, m in enumerate(matches):
  152.         # print "------------I-------------"
  153.         # print i
  154.         # 1 is X - plotting on x axis, corresponds to columns (remember offset second column value)
  155.         # 2 is Y - plotting on y axis, corresponds to rows (no offset)
  156.         # 3 is style
  157.         if m > 0:
  158.             pyl.plot([hips_image1[i][1], hips_image2[m][1] + column1], [hips_image1[i][0], hips_image2[m][0]], 'c')
  159.             # pyl.plot([hips_image1[matches[i]][1], hips_image2[matches[i + 1]][1] + column1], [hips_image1[matches[i]][0], hips_image2[matches[i + 1]][0]], 'c')
  160.     pyl.axis('off')
  161.     pyl.show()
  162.  
  163.  
  164. def RANSAC(R_12, descriptor1, descriptor2):
  165.     """ Step 4 """
  166.  
  167.     matches = []
  168.     # print hips_image1[0]
  169.     print R_12.shape[1]
  170.     print R_12.shape[0]
  171.     for i in range(R_12.shape[0]):
  172.         for j in range(R_12.shape[1]):
  173.             if R_12[i][j] != 0:
  174.                 matches.append(i)
  175.                 matches.append(j)
  176.  
  177.     offset = np.zeros((len(matches), 2))
  178.     for i in range(0, len(matches), 2):
  179.         ndx = matches[i]
  180.         ndx2 = matches[i + 1]
  181.         print ndx
  182.         print ndx2
  183.         offset[i, 0] = descriptor1[ndx][0] - descriptor2[ndx2][0]  # row
  184.         offset[i, 1] = descriptor1[ndx][1] - descriptor2[ndx2][1]  # column
  185.  
  186.     row_offset, col_offset = offset[0, 0], offset[0, 1]  # select offset at random
  187.     best_matchcount = 0
  188.  
  189.     for i in range(len(offset)):
  190.         matchcount = 1  # counter for agreements
  191.         offset_i0 = offset[i, 0]
  192.         offset_i1 = offset[i, 1]
  193.         if ((offset_i0 - row_offset) ** 2 + (offset_i1 - col_offset) ** 2) >= 1.6 ** 2:  # compare with WHAT
  194.             sum_row_offset, sum_col_offset = offset_i0, offset_i1
  195.             for j in range(len(matches)):
  196.                 if j != 1:
  197.                     offset_j0 = offset[j, 0]
  198.                     offset_j1 = offset[j, 1]
  199.                     if ((offset_i0 - offset_j0) ** 2 + (offset_i1 - offset_j1) ** 2) < 1.6 ** 2:  # compare with WHAT
  200.                         sum_row_offset += offset_j0
  201.                         sum_col_offset += offset_j1
  202.                         matchcount += 1
  203.                 if matchcount != best_matchcount:
  204.                     row_offset = sum_row_offset / matchcount
  205.                     col_offset = sum_col_offset / matchcount
  206.                     best_matchcount = matchcount
  207.  
  208.     return row_offset, col_offset, best_matchcount
  209.  
  210.  
  211. def appendimage(image1, image2, row_offset, col_offset):
  212.     """ Step 5 -- note image1, image2 are np arrays -> convert to image"""
  213.  
  214.     x2, y2 = image2.shape
  215.     x3 = int(x2 + row_offset)
  216.     y3 = int(y2 + col_offset)
  217.     canvas = np.zeros((x3, y3))
  218.     canvas = Image.fromarray(canvas)
  219.     image1 = Image.fromarray(image1)
  220.     image2 = Image.fromarray(image2)
  221.     canvas.paste(image1, (0, col_offset))  # (0,220)
  222.     canvas.paste(image2, (row_offset, 0))  # (290,0)
  223.     pyl.figure('Final composite image')
  224.     pyl.imshow(canvas)
  225.     pyl.axis('off')
  226.     pyl.show()
  227.  
  228.  
  229. # load images (accept cmdline arguments)    # pass the two images with .py at cmd
  230. print "Loading images..."
  231. image1 = np.array(Image.open(sys.argv[1]).convert('L'), dtype=np.float32)
  232. image2 = np.array(Image.open(sys.argv[2]).convert('L'), dtype=np.float32)
  233.  
  234. image1 /= 255
  235. image2 /= 255
  236. print "Done."
  237.  
  238. # Step 1 - Find HIPS by computing and thresholding harris response matrix
  239. print "Retrieving harris images"
  240. harris_image1 = harris_matrix_algorithm(image1, 2)  # sigma = 2
  241. harris_image2 = harris_matrix_algorithm(image2, 2)  # sigma = 2
  242. print "Finding interest points"
  243. hips_image1 = get_harris_interest_points(harris_image1, min_distance=10, threshold=0.1)
  244. hips_image2 = get_harris_interest_points(harris_image2, min_distance=10, threshold=0.1)
  245. print "Interest Points (img1): " + str(len(hips_image1))
  246. print "Interest Points (img2): " + str(len(hips_image2))
  247.  
  248. print "Plotting interest points"
  249. plot_harris_interest_points(image1, hips_image1)
  250. plot_harris_interest_points(image2, hips_image2)
  251.  
  252. # Step 2 - Form normalised patch descriptor vectors for all HIPScompute feature locations/descriptors
  253. print "Developing descriptors"
  254. descriptor1 = descriptors(image1, hips_image1)
  255. descriptor2 = descriptors(image2, hips_image2)
  256.  
  257. #
  258. # print "-----descriptors-------------"
  259. # print descriptor1
  260. # print descriptor2
  261.  
  262. # im1 = Image.fromarray(descriptor1)
  263. # im2 = Image.fromarray(descriptor2)
  264. # pyl.subplot(121)
  265. # pyl.imshow(im1)
  266. # pyl.subplot(122)
  267. # pyl.imshow(im2)
  268.  
  269. # Step 3 - Match descriptors -> plot all matching descriptors
  270. print "Matching descriptors"
  271. R_12 = match(descriptor1, descriptor2)
  272. print "Len desc1 %d" % len(descriptor1)
  273. print R_12
  274. # print R_12.shape
  275. # matches = match_stabilised(descriptor1, descriptor2)
  276. plot_matches(image1, image2, hips_image1, hips_image2, R_12)
  277.  
  278. # Step 4 - Exhaustive RANSAC
  279. row_offset, col_offset, best_matchcount = RANSAC(R_12, descriptor1, descriptor2)
  280. print '--Exhaustive RANSAC--'
  281. print 'Number of agreements (best match count): %d' % best_matchcount
  282. print 'Row offset: %d' % row_offset
  283. print 'Column offset: %d' % col_offset
  284.  
  285. # Step 5 - Create composite image using RANSAC translation
  286. appendimage(image1, image2, int(row_offset), int(col_offset))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement