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 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.
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:
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!