Project 2: Local Feature Matching

Feature Matching Points

The objective of this project is to find the matches two images using local feature matching techniques. The matching process here is divided into three steps: First step is to find the corner points using Harris corner detector as they have distinctive surroundings that can be easily identified, apply. The second step is to calculate the SIFT descriptors for the interesting points. The final step is to calculate the feature differences and select point pairs according to the threshold ratio.

  1. Interest Point Detection
  2. Getting features of interest points
  3. Feature Matching

Interest Point Detection

In this function, we first implement the Harris corner detection algorithm. First the image is filtered. Then at each pixel, y and y gradients are computed Ix and Iy. These are used to compute Ix2 Iy2 and Ixy. A thresholding operation is peformed and points having a sufficiently high cornerness score are selected.

Example of code


%example code
[Gx, Gy] = gradient(fspecial('Gaussian',5,1));
Ix = imfilter(image, Gx);
Iy = imfilter(image, Gy);

Gaussian_Filter = fspecial('Gaussian', feature_width, 2);
Ixx = imfilter((Ix .* Ix), Gaussian_Filter);
Ixy = imfilter(Ix .* Iy, Gaussian_Filter);
Iyy = imfilter(Iy .* Iy, Gaussian_Filter);

alpha = 0.06;
R = (Ixx.*Iyy - Ixy.^2) - alpha*((Ixx + Iyy).^2);
R = R / max(max(R));

R=R.*(R>0.025);
B=colfilt(R,[5,5],'sliding',@max);
R = R .* (R == B); 
[Y,X]=find(R);

Interest Points


Features of Interest Points

After the interest points are calculated in the previous method, each points feature descriptor is computed. 4 by 4 grid in 8 directions is constructed and each bin contains magnitude of the intensity in that angle/direction. Thus we get 128 dimensions or a vector of 1 by 128.


%example code

for i = 1: size(x,1)
    
    magnitude_mat = magnitude(y(i)-7:y(i)+8, x(i)-7:x(i)+8);
    direction_mat = direction(y(i)-7:y(i)+8, x(i)-7:x(i)+8);
    cur_feature = [];
    for xi = 1: 4 : feature_width
        
        for yi = 1: 4: feature_width
            
            points_vals = zeros(1,8);
            for xii = xi: xi+3
                
                for yii = yi: yi+3
                    
                    den = (pi/4);
                    num = (direction_mat(xii, yii) + pi);
                    pix = ceil(num / den);
                    points_vals(pix) = points_vals(pix) + magnitude_mat(xii, yii);
                    
                end
                
            end
            points_vals = points_vals / sum(points_vals);
            cur_feature = [cur_feature points_vals];
            
        end
        
    end
    features(i,:) = cur_feature;
end

Matching the features

The final step in the process is matching between feature points detected in the two images. This is done in my program by computing the Euclidean distance between every pair of feature points in the two images. The smallest distances means closest similarity amongst the different feature points in Image1 and Image2. For a given feature point in Image 1, the nearest neighbour and second nearest neighbour are identified by sorting the results of distances and getting the smallest two values. The ratio of these two distances is taken and values greater than particular treshold value are taken as pairs that are matching.


%example code


for i = 1 : size(features1, 1)
    dists = features2;
    
    %calculating distances between all features
    for j = 1 : size(dists, 1)
        dists(j, :) = (dists(j, :) - features1(i, :)).^2;
    end
    
    %sorting to help find nearest neighbor
    [sorted_distances_list, index] = sort(sum(dists, 2));
    
    %ratio of smallest and second smallest to get reliability
    rel = sorted_distances_list(2) / sorted_distances_list(1);
    confidence = (rel)^-1;
    
    if confidence < threshold
        matches(counter, 1) = i;
        matches(counter, 2) = index(1);
        confidences(counter) = confidence;
        counter = counter + 1;
    end 
end

Arrows showing the pairs matched


Results obtained for Notre Dame

The pairs that are matching according to my algorithm are compared with the ground truth. This is done to determine the accuracy of the pairs matched by the algorithm.


The accuracy obtained for Notre Dame is 84% and accuracy obtained for Mount Rushmore is 93% after varying the treshold value to 0.75 for which the best results are obtained. For different pairs of images different values of threshold give high accuracy. This may vary due to the scaling of the images. Images that differ in the rotation/orientation show lesser accuracy on experimentation