OpenCV Best way to match the spot patterns
I'm trying to write an app for wild leopard classification and conservation in South Asia. For this, I have the main challenge to identify the leopards by their spot pattern in the forehead.
The current approach I used was,
- Store the known leopard forehead images as a base list
- Get the user-provided leopard image and crop the forehead of the leopard
- identify the keypoints using the SIFT algorithm
- Use FLANN matcher to get KNN matches
- Select good matches based on the ratio threshold
Sample code below:
img1 = cv.bilateralFilter(baseImg, 9, 75, 75)
img2 = cv.bilateralFilter(userImage, 9, 75, 75)
detector = cv.xfeatures2d_SIFT.create()
keypoints1, descriptors1 = detector.detectAndCompute(img1, None)
keypoints2, descriptors2 = detector.detectAndCompute(img2, None)
# FLANN parameters
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50) # or pass empty dictionary
matcher = cv.FlannBasedMatcher(index_params, search_params)
knn_matches = matcher.knnMatch(descriptors1, descriptors2, 2)
allmatchpointcount = len(knn_matches)
ratio_thresh = 0.7
good_matches = []
for m, n in knn_matches:
if m.distance < ratio_thresh * n.distance:
good_matches.append(m)
goodmatchpointcount = len(good_matches)
print("Good match count : ", goodmatchpointcount)
matchsuccesspercentage = goodmatchpointcount/allmatchpointcount*100
print("Match percentage : ", matchsuccesspercentage)
Problems I have with this approach:
- The method has a medium-low success rate and tends to break when there is a new user image.
- The user images are sometimes taken from different angles where some key patterns are not visible or warped.
- The user image quality affects the match result significantly.
I appreciate any suggestions to get this improved in any manner.
Example user image: (Base image)
Above is matching to below: (Incorrect pattern matched)