SIFT method give me bad results, recognizing 4 shapes

589 views Asked by At

I'm trying to recognize playing cards with open cv, but I have some problems. Firstly I would like to recognize color (hearts, diamonds, spades or clubs). I was staring with red colors. So I detect color, and cut diamond or heart and try recognize with sift - i choose good matches and match color which will be have more (I'm sure its stupid, but I didnt have any idea how to do this). I get result like the one as follows:

this

This is code of my match function:

def match(img, models):
goods = []
for name, value in models:
    sift = cv2.xfeatures2d.SIFT_create()
    kp1, des1 = sift.detectAndCompute(name, None)
    kp2, des2 = sift.detectAndCompute(img, None)
    if des1 is None or des2 is None:
        continue
    bf = cv2.BFMatcher()
    matches = bf.knnMatch(des1, des2, k=2)
    good = []
    if matches is None:
        continue
    for m, n in matches:
        if m.distance < 0.75 * n.distance:
            good.append([m])
    img3 = cv2.drawMatchesKnn(img, kp1, name, kp2, good, None, flags=2)
    plt.imshow(img3), plt.show()
    goods.append([len(good), value])
maxi = 0
ret = None
for l, v in goods:
    if l > maxi:
        maxi = l
        ret = v
if maxi < 3:
    return 0
return ret

If you have any tip, I will be grateful.

1

There are 1 answers

0
ebeneditos On BEST ANSWER

You should have 4 model images, one for each shape.

First you should classify the color, so you only have to compare the image with 2 of the models (either heart/diamond or spade/club).

Now, as the color is not important anymore, you should binarize the image, a Gauss + Otsu should be enough, it can be done as follows:

# Otsu's thresholding after Gaussian filtering
blur = cv2.GaussianBlur(img,(5,5),0)
ret, th = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

Finally I would do the feature matching of th with the 2 model images and the one that gets more feature mathings (len(good)) is the one you are looking for.

Note that the model images must be binarized and should be of the same size.

Hope this helped!