mfergus9
mfergus9

Reputation: 23

OpenCV template ghosting when template matching

I am trying to locate QR position squares withing a QR code. QR position squares are the three boxes in the corners of a QR code:

A QR Code positioning block.

I am template matching these to an image provided to me. I have discovered that there are significant 'ghosts' which appear in my output upon template matching:

enter image description here

Note the white region on the left is a giant smear of template, more distinct templates appear in black along the bottom but the whole image is essentially a smear of templates. Here is my code:

import cv2
import numpy as np

qrs=['A','B','C','D','E']
for qr in qrs:
    
    template=cv2.imread(r'C:\Users\Matt\Desktop\Virginia Tech\CV\QR_Template_final.png',0)    
    img = cv2.imread(r'C:\Users\Matt\Desktop\Virginia Tech\CV\QR_'+qr+'.png', 0)
    img_origin = cv2.imread(r'C:\Users\Matt\Desktop\Virginia Tech\CV\QR_'+qr+'.png')
    
    # Binarize
    img[img>125]=255
    img[img<126]=0
    img=img.astype(np.float32)
    template=template.astype(np.float32)

        
    # Template Matching
    res=cv2.matchTemplate(img, template, cv2.TM_CCORR_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    res=255*(res-min_val)/(max_val-min_val)
    
    out=cv2.imwrite(r'C:\Users\Matt\Desktop\Virginia Tech\CV\QR\Threshold\QR_IMG'+qr+'.png',img)
    out=cv2.imwrite(r'C:\Users\Matt\Desktop\Virginia Tech\CV\QR\Threshold\QR_Threshold'+qr+'.png',res)

How do I address these ghosts?

I included a compressed version of the input. It is a picture of a QR code front and center in a grocery store without template any ghosts:

enter image description here

Also see this version of the output without binarization of the input:

enter image description here

Thanks so much for your help I have been stuck on this problem for some time.

Upvotes: 0

Views: 311

Answers (1)

Gralex
Gralex

Reputation: 4485

You use wrong technique for dot detection. Template matching not have size and rotation robustness. The best way to solve your problem is to manually analyze each row of the image and find pattern: N black, N white, 2*N black, N white, N black. This is how real QR code detector works.

For implementation on C++ you can checkout this code. And here you can find some comments about algorithm.

There other way to find this dots. If you use some library for QR detection, this library can provide corners of QR code and you can calculate dot location.

Upvotes: 2

Related Questions