CSCI 3240U --- Computer Vision I¶
Lab 7 --- Interest Points and Local Descriptors¶
Faisal Z. Qureshi
Faculty of Science, Ontario Tech University
Oshawa ON Canada
http://vclab.science.ontariotechu.ca
Fall 2026
Lab - Image matching via local feature detection¶
The goal of this lab is to experiment with image matching via local feature detection.
In this notebook, I have provided code for 1) corner detection and 2) SIFT feature computation. You will be using SIFT features to compute a match score between two images. Details are provided below.
While it is not necessary, it is worthwhile for you to test out your code on images from this dataset. https://image-matching-workshop.github.io/challenge/
Please Submit via Blackboard.
import cv2
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
Test Image¶
img_file = 'cn-tower-1.jpg'
#img_file = 'cb.png'
img = cv2.imread(img_file)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(10,10))
plt.imshow(img)
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-1-1596d39e4f4c> in <module> 2 #img_file = 'cb.png' 3 ----> 4 img = cv2.imread(img_file) 5 img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 6 plt.figure(figsize=(10,10)) NameError: name 'cv2' is not defined
Finding interest points using Harris Corner Detector¶
img = cv2.imread(img_file)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
src = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
src = np.float32(src)
blocksize = 2 # size of the neighbourhood considered for corner detection
ksize = 3 # size of the Sobel kernel (a.k.a. the aperture parameter of the Sobel derivative)
k = 0.04 # Harris detector parameter used in the corner response equation $R = det(M) - k (trace(M))^2$
dst = cv2.cornerHarris(src, blocksize, ksize, k)
dst = cv2.dilate(dst, None)
img[dst>0.01*dst.max()]=[255,0,0]
plt.figure(figsize=(20,15))
plt.title('Harris Corner Response')
plt.subplot(2,1,1)
plt.imshow(dst, cmap='gray')
plt.subplot(2,1,2)
plt.title('Harris Corner Detector')
plt.imshow(img)
<matplotlib.image.AxesImage at 0x13954c590>
Finding interest points using Shi-Tomasi Corner Detector¶
img = cv2.imread(img_file)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
src = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
corners = cv2.goodFeaturesToTrack(src, 25, 0.01, 10)
corners = np.int0(corners)
for i in corners:
x,y = i.ravel()
cv2.circle(img,(x,y),3,255,-1)
plt.figure(figsize=(10,10))
plt.title('Shi-Tomasi Corner Detector')
plt.imshow(img)
<matplotlib.image.AxesImage at 0x1395ba950>
SIFT¶
The following code identifies the locations (stored as cv2.Keypoint) that are suitable for SIFT computation. An orientation and scale is associated with each location.
img = cv2.imread(img_file)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
src = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
sift = cv2.xfeatures2d.SIFT_create()
kp = sift.detect(src, None)
# We draw the keypoint alongwith their scale and orientation
# for better visualization
img = cv2.drawKeypoints(src, kp, img, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
plt.figure(figsize=(10,10))
plt.title('SIFT key points')
plt.imshow(img)
<matplotlib.image.AxesImage at 0x1394b6290>
TODO¶
Your goal is to use local feature descriptors computed from two images to compute a match score for these images. Here's the a recipie for computing a match score. You are encouraged to not use the built-in image matcher. Instead experiment with different matching techniques to see if you can match images successfully.
- Compute $n$ SIFT descriptors from image 1
- Compute $m$ SIFT descriptors from image 2
- Each descriptor is a 128-dimenstional vector. So find a scheme to compute distance between two vectors---say, Euclidean distance. Also identify a suitable threshold that you can use to decide if two vectors are "matched. Now using the distance computating above, find the number of matched vectors between the vectors computed from image 1 and those computed from image 2.
- Find the percentage of matched vectors w.r.t. to the the number of vectors computed from the image 1 or image 2. Use image 1 number, if $n$ is smaller than $m$, image 2 numbers otherwise.
Complete the following function which returns a number between 0.0 and 1.0
def img_match(filename1, filename2):
# TO DO
return 0.0
We will use this function as follows
filename1 = 'cn-tower-1.jpg'
filename2 = 'cn-tower-2.jpg'
print ('Match score is', img_match(filename1, filename2))
Match score is 0.0