Fast method for key-point based image matching [Python]

753 Views Asked by At

The scenario is, Let's suppose I took random images from my Gallery and put in some folder, and also print these image in hard form. Now I turned on my laptop camera and place an image in front of camera, My code need the tell the name of matching image from the folder. Actually the code I have add in the question works fine but when I increases the number of image in folder then Identification start taking more time. I want to know, is there any method that I can try to improve my speed? Here is the working Demo of my scenario.

import cv2
import os
from pathlib import Path
import time


# Define path
pathImages = 'ImagesQuery'

# Set the Number of detected Features
orb = cv2.ORB.create(nfeatures=1000)

# Set the threshold of minimum Features detected to give a positive, around 20 to 30
thres = 27

# List Images and Print out their Names and how many there are in the Folder
images = []
classNamesImages = []
myListImages = os.listdir(pathImages)

print(myListImages)
print('Total Classes Detected', len(myListImages))
# this will read in the images
for cl in myListImages:
    imgCur = cv2.imread(f'{pathImages}/{cl}', 0)
    images.append(imgCur)
    # delete the file extension
    classNamesImages.append(os.path.splitext(cl)[0])
print(classNamesImages)


# this will find the matching points in the images
def findDes(images):
    desList = []
    for img in images:
        kp, des = orb.detectAndCompute(img, None)
        desList.append(des)
    return desList

# this will compare the matches and find the corresponding image
def findID(img, desList):
    image_matching_time = time.time()

    kp2, des2 = orb.detectAndCompute(img, None)
    bf = cv2.BFMatcher()
    matchList = []
    finalVal = -1
    try:
        for des in desList:
            matches = bf.knnMatch(des, des2, k=2)
            good = []
            for m, n in matches:
                # the distance of the matches in comparison to each other
                if m.distance < 0.75 * n.distance:
                    good.append([m])
            matchList.append(len(good))
    except:
        pass
    # uncomment to see how many positive matches, according to this the thres is set
    # print(matchList)

    if len(matchList) != 0:
        if max(matchList) > thres:
            finalVal = matchList.index(max(matchList))
    print("matching time --- %s seconds ---" % (time.time() - image_matching_time))
    return finalVal


desList = findDes(images)
print(len(desList))

# open Webcam
cap = cv2.VideoCapture(1)

while True:

    success, img2 = cap.read()
    imgOriginal = img2.copy()
    # convert Camera to Grayscale
    img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)


# if Matching with Image in List, send the respective Name
    id = findID(img2, desList)

    if id != -1:
        # put text for the found Image
        cv2.putText(imgOriginal, classNamesImages[id], (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)

    # show the final Image
    cv2.imshow('img2', imgOriginal)
    cv2.waitKey(1)

I have tried with deep learning base solution but it did't work. Second I have tried FLANN feature matcher its showing the same time delay 0.4 sec as in upper shown code. I am looking for any fast solution. Here is a sample of original image from folder and query image from the camera.

[Edit]: Number of query images is around 1000 and I want to compare 20 fps with all query images.

enter image description here

0

There are 0 best solutions below