-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcard_img.py
151 lines (110 loc) · 4.33 KB
/
card_img.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
"""
Card Recognition using OpenCV
Code from the blog post
http://arnab.org/blog/so-i-suck-24-automating-card-games-using-opencv-and-python
Usage:
./card_img.py filename num_cards training_image_filename training_labels_filename num_training_cards
Example:
./card_img.py test.JPG 4 train.png train.tsv 56
Note: The recognition method is not very robust; please see SIFT / SURF for a good algorithm.
"""
import sys
import numpy as np
sys.path.insert(0, "/usr/local/lib/python2.7/site-packages/")
import cv2
###############################################################################
# Utility code from
# http://git.io/vGi60A
# Thanks to author of the sudoku example for the wonderful blog posts!
###############################################################################
def rectify(h):
h = h.reshape((4,2))
hnew = np.zeros((4,2),dtype = np.float32)
add = h.sum(1)
hnew[0] = h[np.argmin(add)]
hnew[2] = h[np.argmax(add)]
diff = np.diff(h,axis = 1)
hnew[1] = h[np.argmin(diff)]
hnew[3] = h[np.argmax(diff)]
return hnew
###############################################################################
# Image Matching
###############################################################################
def preprocess(img):
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(5,5),2)
thresh = cv2.adaptiveThreshold(blur,255,1,1,11,1)
return thresh
def imgdiff(img1,img2):
img1 = cv2.GaussianBlur(img1,(5,5),5)
img2 = cv2.GaussianBlur(img2,(5,5),5)
diff = cv2.absdiff(img1,img2)
diff = cv2.GaussianBlur(diff,(5,5),5)
flag, diff = cv2.threshold(diff, 200, 255, cv2.THRESH_BINARY)
return np.sum(diff)
def find_closest_card(training,img):
features = preprocess(img)
return sorted(training.values(), key=lambda x:imgdiff(x[1],features))[0][0]
###############################################################################
# Card Extraction
###############################################################################
def getCards(im, numcards=4):
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(1,1),1000)
flag, thresh = cv2.threshold(blur, 120, 255, cv2.THRESH_BINARY)
image, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=cv2.contourArea,reverse=True)[:numcards]
for card in contours:
peri = cv2.arcLength(card,True)
# print(peri)
approx = rectify(cv2.approxPolyDP(card,0.02*peri,True))
print(approx)
box = np.int0(approx)
cv2.drawContours(im,[box],0,(255,255,0),6)
imx = cv2.resize(im,(1000,600))
cv2.imshow('a',imx)
h = np.array([ [0,0],[449,0],[449,449],[0,449] ],np.float32)
transform = cv2.getPerspectiveTransform(approx,h)
warp = cv2.warpPerspective(im,transform,(450,450))
yield warp
def get_training(training_labels_filename,training_image_filename,num_training_cards,avoid_cards=None):
training = {}
labels = {}
for line in open(training_labels_filename, 'r'):
key, num, suit = line.strip().split()
labels[int(key)] = (num,suit)
print ("Training")
im = cv2.imread(training_image_filename)
for i,c in enumerate(getCards(im,num_training_cards)):
if avoid_cards is None or (labels[i][0] not in avoid_cards[0] and labels[i][1] not in avoid_cards[1]):
training[i] = (labels[i], preprocess(c))
print ("Done training")
return training
if __name__ == '__main__':
filename = "/Users/anais/Desktop/OpenCV/test_set.jpg"
num_cards = 4
training_image_filename = "/Users/anais/Desktop/OpenCV/train_copy.png"
training_labels_filename = "/Users/anais/Desktop/OpenCV/train_set_mini.tsv"
num_training_cards = 56
print("test one")
training = get_training(training_labels_filename,training_image_filename,num_training_cards)
im = cv2.imread(filename)
preprocess(im)
width = im.shape[0]
height = im.shape[1]
if width < height:
im = cv2.transpose(im)
im = cv2.flip(im,1)
print("test two")
# Debug: uncomment to see registered images
# for i,c in enumerate(getCards(im,num_cards)):
# card = find_closest_card(training,c,)
# cv2.imshow(str(card),c)
# cv2.waitKey(0)
print("test three")
cards = [find_closest_card(training,c) for c in getCards(im,num_cards)]
print("test four")
print (cards)
print("test final")
# else:
# print __doc__