Feature Detection

Given a target image with a feature and an input image, try to identify all locations of the target in the input.

In [194]:
import numpy as np

import cv2
from PIL import Image

from scipy.signal import fftconvolve

import os

import matplotlib.pyplot as plt
from matplotlib import cm
%matplotlib inline

OpenCV Implementation

In [2]:
def detect_features_opencv(target_image_path, template_path, number = 'one', threshold=0.75):
    
    
    method = eval('cv2.TM_SQDIFF')
    
    if number == 'one':
        target = cv2.imread(target_image_path, 0)
        template = cv2.imread(template_path, 0)
        h, w = template.shape
        res = cv2.matchTemplate(target, template, method)
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)


        top_left = min_loc
        bottom_right = (top_left[0] + w, top_left[1] + h)
        cv2.rectangle(target, top_left, bottom_right, 255, 2)

        plt.figure(figsize=(16, 16))
        plt.subplot(121); plt.imshow(res, cmap='gray')
        plt.title('Match'); plt.axis('off')
        plt.subplot(122); plt.imshow(target, cmap='gray')
        plt.title('Detection'); plt.axis('off')
        plt.show();
        
    elif number == 'many':
        target_rgb = cv2.imread(target_image_path)
        target_gray = cv2.cvtColor(target_rgb, cv2.COLOR_BGR2GRAY)
        template = cv2.imread(template_path, 0)
        
        method = eval('cv2.TM_CCOEFF_NORMED')
        h , w = template.shape
        
        res = cv2.matchTemplate(target_gray, template, method)
        loc = np.where(res >= threshold)
        
        for point in zip(*loc[::-1]):
            cv2.rectangle(target_rgb, point, (point[0] + w, point[1] + h), (0, 0, 255), 2)
            
        cv2.imwrite('result.png', target_rgb)
        result = plt.imread('result.png')
        plt.figure(figsize=(12, 12))
        plt.imshow(result); plt.axis('off');
        plt.title('Detection Results', size = 24);
        plt.show();
    
        os.remove('result.png')
    else:
        print('Enter Valid Number (one or many)')
In [3]:
detect_features_opencv('images/target.jpg', 'images/template.jpg')
In [4]:
detect_features_opencv('images/target.jpg', 'images/template.jpg', number = 'many', threshold=0.9)
In [5]:
detect_features_opencv('images/target_street.jpg', 'images/template_human.jpg')
In [6]:
detect_features_opencv('images/target_street.jpg', 'images/template_human.jpg',
                number = 'many', threshold=0.75)