pythonopencvimage-processingsiftorb

OpenCV Orb Algorithm QR Code Match Issues


I'm following a video tutorial about, feature detection and matching by using Python OpenCV. Video uses the ORB (Oriented FAST and Rotated BRIEF) algorithm, as seen in the link below:

https://youtu.be/nnH55-zD38I

So i decided to use it the example 2 images i have, with little modification on the code. There are 2 input images, 1 with single QR code (single.jpg), other with a few different QR codes inside (multiple.jpg). The aim is to find the most similar region in the bigger image (multiple.jpg). But getting matches with totally different QR codes.

Why it is marking different region, and can we do an improvement on this example?

import cv2

MULTIPLE_NAME ="...multiple.jpg"
SINGLE_NAME = "...single.jpg"

multiple = cv2.imread(MULTIPLE_NAME)
single = cv2.imread(SINGLE_NAME)

orb=cv2.ORB_create()

kpsingle,dessingle = orb.detectAndCompute(single,None)
kpmultiple,desmultiple = orb.detectAndCompute(multiple,None)

bf=cv2.BFMatcher()
matches = bf.knnMatch(dessingle, desmultiple, k=2)

good=[]
for m, n in matches:
    if m.distance < 2*n.distance:
        good.append([m])

img3 = cv2.drawMatchesKnn(single, kpsingle, multiple, kpmultiple, good, None, flags=2)

cv2.imshow("img",multiple)
cv2.imshow("crop",single)
cv2.imshow("img3",img3)
cv2.waitKey()

single multiple img3 expected


Solution

  • Method 1: pyzbar QR code (you need to pip or conda install pyzbar)

    I tried and got this

    import cv2
    import numpy as np
    import pyzbar.pyzbar as pyzbar
    
    YELLOW = (0,255,255)
    RED = (0,0,255)
    font = cv2.FONT_HERSHEY_SIMPLEX
    
    
    img = cv2.imread(r"C:\some-path\qr-codes-green.jpg")
    
    # Create a qrCodeDetector Object
    dec_objs = pyzbar.decode(img)
    
    for d in dec_objs:
        pts = [[p.x,p.y] for p in d.polygon]
        txt_org = (d.rect.left,d.rect.top)
        txt = d.data.decode("utf-8")
        cv2.putText(img,txt,txt_org,font,0.5,YELLOW,1,cv2.LINE_AA)
        poly = np.int32([pts])
        cv2.polylines(img,poly,True,RED,thickness=1,lineType=cv2.LINE_AA)
    
    
    
    cv2.imshow('QR-scanner',img)
    cv2.waitKey(0)
    

    Results enter image description here


    Method 2: wechat QR code

    import cv2
    import numpy as np
    import pyzbar.pyzbar as pyzbar
    
    YELLOW = (0,255,255)
    RED = (0,0,255)
    font = cv2.FONT_HERSHEY_SIMPLEX
    
    
    img = cv2.imread(r"C:\some-path\qr-codes-green.jpg")
    
    mod_path = r'C:\some-path\model\\'
    detector = cv2.wechat_qrcode_WeChatQRCode(mod_path+'detect.prototxt',
        mod_path+'detect.caffemodel',
        mod_path+'sr.prototxt',
        mod_path+'sr.caffemodel')
    
    
    res, points = detector.detectAndDecode(img)
    
    
    for i in range(len(res)):
        poly = points[i].astype(np.int32)
        txt = res[i]
        print(poly)
        txt_org = poly[0]
        cv2.putText(img,txt,txt_org,font,0.5,YELLOW,1,cv2.LINE_AA)
        cv2.polylines(img, [poly], True, RED, thickness=1, lineType=cv2.LINE_AA)
    
    
    cv2.imshow('QR-scanner',img)
    cv2.waitKey(0)
    
    

    enter image description here

    Good references here

    https://learnopencv.com/opencv-qr-code-scanner-c-and-python/

    https://learnopencv.com/wechat-qr-code-scanner-in-opencv/