Hi (continuation of a previous question here), I want to extract images from a drone video and I want to take images that have an implied difference between them, for this purpose I have a function to calculate IoU between 2 images. When the drone does not move in height between the 2 images, I get a result that seems logical, but when the drone rises/falls between the 2 images, I get an illogical result because the scale changes (for example, I get that the iou is above 90 even though they are really different because the height of the photo has changed). What do I need to change/add in order to deal with these cases or do I need to use a different method for this calculation?
Thanks for the help!
(the previous question - Measuring the similarity percentage between two images)
image example -
my code -
def calculate_iou(image1, image2, ratio_threshold=0.75, min_good_matches=10, min_inliers=10):
gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(gray1, None)
kp2, des2 = sift.detectAndCompute(gray2, None)
bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=False)
matches = bf.knnMatch(des1, des2, k=2)
good_matches = []
for m, n in matches:
if m.distance < ratio_threshold * n.distance:
good_matches.append(m)
if len(good_matches) < min_good_matches:
logger.info("Not enough good matches found. Returning IoU of 0.")
return 0.0
src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
M, mask = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC, 5.0)
inliers = mask.ravel().sum()
if inliers < min_inliers:
logger.info("Not enough inliers found. Returning IoU of 0.")
return 0.0
h, w, _ = image1.shape
warped_image2 = cv2.warpPerspective(image2, M, (w, h))
intersection = cv2.bitwise_and(image1, warped_image2)
union = cv2.bitwise_or(image1, warped_image2)
# need it to measure the percentage of difference between 2 images
iou = (np.sum(intersection > 0) / np.sum(union > 0)) * 100
return iou