Ask Your Question

Revision history [back]

How to improve the accuracy of logo matching?

I want to check which logo an image contains. There are 2 logos. In fact, the image contains the first logo but the score of the second logo using sift is higher.

I used BFMatcher to get good match and I also calculated the number of inliers. Both values indicate the second logo is more likely to present.

Are there anythings wrong with my code? How to improve the accuracy?

Thank you very much.

import cv2
import requests
import numpy as np

def get_array(url):
    logo1 = requests.get(url).content
    arr = np.asarray(bytearray(logo1), dtype=np.uint8)
    logo1_array = cv2.imdecode(arr, -1)
    return logo1_array

def get_good_match_num(image_array, logo_array):

    sift = cv2.xfeatures2d.SIFT_create()
    bf = cv2.BFMatcher()

    img_kp, img_des = sift.detectAndCompute(image_array, None)
    logo_kp, logo_des = sift.detectAndCompute(logo_array, None)  

    matches = bf.knnMatch(img_des, logo_des, k=2)

    good = []

    for p in matches:
        try:
            m, n = p
            if m.distance < 0.7*n.distance:
                good.append(m)
        except:
            continue

    if len(good) > 10:
        src_pts = []
        dst_pts = []
        for m in good:
            try:
                a, b = img_kp[m.queryIdx].pt, logo_kp[m.trainIdx].pt
                src_pts.append(a)
                dst_pts.append(b)
            except:
                continue

        src_pts = np.float32(np.array(src_pts)).reshape(-1,1,2)
        dst_pts = np.float32(np.array(dst_pts)).reshape(-1,1,2)

        M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
        num = sum(sum(mask))
    else:
        num = 0
    return len(good), num

logo1_array = get_array(r'https://drive.google.com/uc?id=1Pz1-pL0_auDzlZnbnYVnORYnRFb5n5GQ')
logo2_array = get_array(r'https://drive.google.com/uc?id=1xPnD5mzZ20tpot4Ecw75r3LgyloJwArs')
image_array = get_array(r'https://drive.google.com/uc?id=13S2Nl32MYmutG4xrDtJeu1ptCGJQPO-L')

good1, num1 = get_good_match_num(image_array, logo1_array) #good1 = 16, num1 = 0
good2, num2 = get_good_match_num(image_array, logo2_array) #good2 = 69, num1 = 51