# Compute Two Images Similarity Using Python OpenCV and SIFT – Python OpenCV Tutorial

By | August 1, 2022

When we are comparing two images, we have to compute the similarity score between them. In this tutorial, we will compute its similarity score using python opencv sift.

## How to use opencv SIFT?

In order to use sift in opencv, we have to use python opencv 3.4.2.16. Otherwise, you will get AttributeError: module ‘cv2’ has no attribute ‘xfeatures2d’ error.

Fix AttributeError: module ‘cv2’ has no attribute ‘xfeatures2d’ – Python OpenCV Tutorial

## How to compute the similarity score between two images?

Here we will give you a full example code to compute.

import cv2
import matplotlib.pyplot as plt

# Resize images to a similar dimension
# This helps improve accuracy and decreases unnecessarily high number of keypoints

def imageResizeTrain(image):
maxD = 1024
height,width = image.shape
aspectRatio = width/height
if aspectRatio < 1:
newSize = (int(maxD*aspectRatio),maxD)
else:
newSize = (maxD,int(maxD/aspectRatio))
image = cv2.resize(image,newSize)
return image

def imageResizeTest(image):
maxD = 1024
height,width,channel = image.shape
aspectRatio = width/height
if aspectRatio < 1:
newSize = (int(maxD*aspectRatio),maxD)
else:
newSize = (maxD,int(maxD/aspectRatio))
image = cv2.resize(image,newSize)
return image

def computeSIFT(image):
sift = cv2.xfeatures2d.SIFT_create()
return sift.detectAndCompute(image, None)

def calculateResultsFor(image_1,image_2):

keypoint1, descriptor1 = computeSIFT(image_1_data)
keypoint2, descriptor2 = computeSIFT(image_2_data)

matches = calculateMatches(descriptor1, descriptor2)
score = calculateScore(len(matches),len(keypoint1),len(keypoint2))
plot = getPlotFor(image_1,image_2,keypoint1,keypoint2,matches)
#print(len(matches),len(keypoint1),len(keypoint2),len(descriptor1),len(descriptor2))
#print(score) # 结果
plt.imshow(plot),plt.show()
return score

def getPlotFor(image1,image2,keypoint1,keypoint2,matches):
return getPlot(image1,image2,keypoint1,keypoint2,matches)

def calculateScore(matches,keypoint1,keypoint2):
return 100 * (matches/min(keypoint1,keypoint2))

def calculateMatches(des1, des2):
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)
topResults1 = []
for m, n in matches:
if m.distance < 0.7 * n.distance:
topResults1.append([m])

matches = bf.knnMatch(des2, des1, k=2)
topResults2 = []
for m, n in matches:
if m.distance < 0.7 * n.distance:
topResults2.append([m])

topResults = []
for match1 in topResults1:
match1QueryIndex = match1[0].queryIdx
match1TrainIndex = match1[0].trainIdx

for match2 in topResults2:
match2QueryIndex = match2[0].queryIdx
match2TrainIndex = match2[0].trainIdx

if (match1QueryIndex == match2TrainIndex) and (match1TrainIndex == match2QueryIndex):
topResults.append(match1)

def getPlot(image1,image2,keypoint1,keypoint2,matches):
image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)
image2 = cv2.cvtColor(image2, cv2.COLOR_BGR2RGB)
matchPlot = cv2.drawMatchesKnn(image1,keypoint1,image2,keypoint2,matches,None,[255,255,255],flags=2)
return matchPlot

#--

imageList = [
r"C:\Users\yuzhilun\Desktop\book_cover\1.png",
r"C:\Users\yuzhilun\Desktop\book_cover\2.png",
r"C:\Users\yuzhilun\Desktop\book_cover\3.png",
r"C:\Users\yuzhilun\Desktop\book_cover\4.png"]
lx = len(imageList) -1
for i in range(lx):
score = calculateResultsFor(imageList[i],imageList[i+1])
print(imageList[i],imageList[i+1],score)

In this example, we will use calculateResultsFor() function to compute the similarity score between two image. This function will receive two images and return their similarity score.

Run this code, we will see:

C:\Users\yuzhilun\Desktop\book_cover\1.png C:\Users\yuzhilun\Desktop\book_cover\2.png 0.125
C:\Users\yuzhilun\Desktop\book_cover\2.png C:\Users\yuzhilun\Desktop\book_cover\3.png 0.1875
C:\Users\yuzhilun\Desktop\book_cover\3.png C:\Users\yuzhilun\Desktop\book_cover\4.png 0.1405152224824356

From the result, we can find:if the score is low, these two images are different.