|
| 1 | +from scipy.ndimage import filters |
| 2 | +import cv2 |
| 3 | +import numpy as np |
| 4 | +import matplotlib.pyplot as plt |
| 5 | +import random |
| 6 | + |
| 7 | +def computeHarrisResponse(im, sigma = 3): |
| 8 | +""" Compute the Harris corner detector response function |
| 9 | +for each pixel in a graylevel image. """ |
| 10 | + |
| 11 | +# compute derivatives |
| 12 | +imx = np.zeros(im.shape) |
| 13 | +filters.gaussian_filter(im, (sigma,sigma), (0,1), imx) # Ix = Gx * I |
| 14 | +imy = np.zeros(im.shape) |
| 15 | +filters.gaussian_filter(im, (sigma, sigma), (1,0), imy) # Iy = Gy * I |
| 16 | + |
| 17 | +# compute components of the Harris matrix |
| 18 | +Sxx = filters.gaussian_filter(imx*imx, sigma) |
| 19 | +Sxy = filters.gaussian_filter(imx*imy, sigma) |
| 20 | +Syy = filters.gaussian_filter(imy*imy, sigma) |
| 21 | + |
| 22 | +# compute determinant and trace |
| 23 | +Sdet = Sxx*Syy - Sxy*Sxy |
| 24 | +Str = Sxx + Syy |
| 25 | + |
| 26 | +# compute eigenvalue and eigenvector |
| 27 | +m, n = Sxx.shape |
| 28 | +lamda1 = np.zeros(im.shape) |
| 29 | +lamda2 = np.zeros(im.shape) |
| 30 | +for i in range(m): |
| 31 | +for j in range(n): |
| 32 | +H = np.array([[Sxx[i,j], Sxy[i,j]], [Sxy[i,j], Syy[i,j]]]) |
| 33 | +e_vals, e_vecs = np.linalg.eig(H) |
| 34 | +lamda1[i,j] = e_vals[0] |
| 35 | +lamda2[i,j] = e_vals[1] |
| 36 | + |
| 37 | + |
| 38 | +## compute the responce |
| 39 | +R1 = np.minimum(lamda1, lamda2) # The Shi-Tomasi corner response |
| 40 | +R2 = (lamda1*lamda2) - 0.04*(lamda1+lamda2)**2 # Harris corner response |
| 41 | +R3 = Sdet - 0.04*(Str**2) # Another common used Harris corner response |
| 42 | + |
| 43 | +return (R1, R2, R3) |
| 44 | + |
| 45 | + |
| 46 | +def getHarrisPoints(harrisim, min_dist = 5, threshold = 0.03): ## random.uniform(0.02, 0.04) |
| 47 | +""" Return corners from a Harris response image min_dist is the minimum number |
| 48 | +of pixels separating corners and image boundary. """ |
| 49 | + |
| 50 | +# find top corner candidates above a threshold |
| 51 | +corner_threshold = harrisim.max() * threshold |
| 52 | +harrisim_t = (harrisim > corner_threshold) |
| 53 | +#print harrisim_t.shape |
| 54 | + |
| 55 | +# get coordinates of candidates |
| 56 | +coords = np.array(harrisim_t.nonzero()).T |
| 57 | +#print coords.shape |
| 58 | + |
| 59 | +# ...and their values |
| 60 | +candidate_values = [harrisim[c[0],c[1]] for c in coords] |
| 61 | + |
| 62 | +# sort candidates |
| 63 | +index = np.argsort(candidate_values) |
| 64 | + |
| 65 | +# store allowed point locations in array |
| 66 | +allowed_locations = np.zeros(harrisim.shape) |
| 67 | +allowed_locations[min_dist:-min_dist,min_dist:-min_dist] = 1 |
| 68 | + |
| 69 | +# select the best points taking min_distance into account |
| 70 | +filtered_coords = [] |
| 71 | +for i in index: |
| 72 | +if allowed_locations[coords[i,0],coords[i,1]] == 1: |
| 73 | +filtered_coords.append(coords[i]) |
| 74 | +allowed_locations[(coords[i,0]-min_dist):(coords[i,0]+min_dist), |
| 75 | +(coords[i,1]-min_dist):(coords[i,1]+min_dist)] = 0 |
| 76 | +return filtered_coords |
| 77 | + |
| 78 | + |
| 79 | +def plotHarrisPoints(image, filtered_coords): |
| 80 | +""" Plots corners found in image. """ |
| 81 | +plt.figure() |
| 82 | +plt.gray() |
| 83 | +plt.imshow(image) |
| 84 | +plt.plot([p[1] for p in filtered_coords],[p[0] for p in filtered_coords],'*') |
| 85 | +plt.axis('off') |
| 86 | +plt.show() |
| 87 | + |
| 88 | + |
| 89 | +def main(): |
| 90 | +filename = 'Img3.jpg' |
| 91 | +img = cv2.imread(filename) |
| 92 | +grayimg = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) |
| 93 | +im = np.float32(grayimg) |
| 94 | + |
| 95 | +R = (R1, R2, R3) = computeHarrisResponse(im) |
| 96 | +for i in range(len(R)): |
| 97 | +filtered_coords = getHarrisPoints(R[i], 5) |
| 98 | +plotHarrisPoints(im, filtered_coords) |
| 99 | + |
| 100 | + |
| 101 | + |
| 102 | +if __name__== "__main__": |
| 103 | +main() |
| 104 | + |
0 commit comments