pythonopencvimage-recognition

How do I find an image similar to the input image from a directory?


I have a python program which will detect images from webcam. Now, I want to compare the image recognized by the webcam with the images in my directory and check if the exact similar image is already existing or not.

I have tried using this recognition algorithm but it does not work. The program always outputs single image no matter how different the input image is.

The input image(the image scanned by the webcam) is little blurry like this while the image in the data set looks like this

I need an algorithm which can recognize these images with more accuracy.


Solution

  • Here i write a small script for you, hope that it could solve your problem

    import cv2
    import os
    import numpy as np
    
    from typing import Union
    
    def read_img_from_dir(image_dir: str, query_shape: Union[list, tuple]) -> tuple[list, np.ndarray]:
        name_image = []
        img_array = np.empty((0, np.prod(query_shape)), dtype=np.float32)
        for image_name in os.listdir(image_dir):
            name_image.append(image_name)
            image = cv2.imread(os.path.join(image_dir, image_name))
            if not isinstance(image, np.ndarray):
                # if path is not image
                continue
            image = cv2.resize(image, query_shape[:2][::-1])
            image = image.reshape(1, -1) / 255.
            img_array = np.concatenate((img_array, image))
        return name_image, img_array    
    
    def find_by_knn(query_img: np.ndarray, list_name: list[str], database: np.ndarray) -> str:
        query_img = query_img.reshape(1, -1) / 255.
        dists = np.sqrt(np.sum((database-query_img) ** 2,axis = 1))
        idx = dists.argmin()
        return list_name[idx]
    
    if __name__=='__main__':
        image_query = 'Path to the image that you want to find'
        image_dir = 'Image folder that may contain your query image'
        img = cv2.imread(image_query)
        
        # optional: since the query image size maybe large, resize 
        # all image to a small disired shape may avoid OOM problem
        # and boost computing speed
        
        # global_shape = (320, 320)
        # img = cv2.resize(img, global_shape)
        
        shape = img.shape
        name_image, img_array = read_img_from_dir(image_dir, shape)
        result = find_by_knn(img, name_image, img_array)
        print(result)
    

    If you wanna know more about KNN, take a look at this link: http://cs231n.github.io/classification/#nn