-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcard_detector
executable file
·135 lines (108 loc) · 4.39 KB
/
card_detector
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
#!/usr/bin/python
# -*- coding: utf8 -*-
# A card detector using OpenCV and Python
# This code uses ORB to extract features and BRIEF to compute descriptors
# OpenCV Version: 2.4.9
# Python Version: 2.7.8
import numpy as np
import cv2
import sys
from espeak import espeak
# Sets the minimum of matches required to consider the card as detected
MIN_MATCH_COUNT = 40
# Configures input from the webcam and opens the template file to detect
# It sets the template as grayscale to make the processing faster
cap = cv2.VideoCapture(0)
template_file = "template.png"
template = cv2.imread(template_file)
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
#Cards List
card_files = [
"cards/tne.png",
"cards/crut.png",
"cards/cnet.png",
"cards/creducm.png",
"cards/lic.png"
]
card_names = [
"Tarjeta Nacional Estudiantil",
"Cuenta rut",
"Carnet de Identidad",
"Credencial Universidad Católica del Maule",
"Licencia de Conducir"
]
# Initializes feature detector as ORB and feature descriptor as BRIEF
detector = cv2.FeatureDetector_create("ORB")
descriptor = cv2.DescriptorExtractor_create("BRIEF")
# ORB feature detector detects features from the template Image
# BRIEF then computes descriptors for the detected features
tpl_keypoints = detector.detect(template)
(tpl_keypoints, tpl_descriptors) = descriptor.compute(template, tpl_keypoints)
card_keypoints = []
card_descriptors = []
for i in range(len(card_files)):
tmp_image = cv2.imread(card_files[i])
tmp_image = cv2.cvtColor(tmp_image, cv2.COLOR_BGR2GRAY)
tmp_keypoints = detector.detect(tmp_image)
(tmp_keypoints, tmp_descriptors) = descriptor.compute(tmp_image, tmp_keypoints)
card_keypoints.append(tmp_keypoints)
card_descriptors.append(tmp_descriptors)
# A matcher object is initialized to match features from the webcam
# input with the template image features
matcher = cv2.DescriptorMatcher_create('BruteForce-Hamming')
#Sets voice synthesizer language
espeak.set_voice('spanish-latin-am')
last_detected = -1
while cap.isOpened():
ret, img = cap.read()
# Input image preprocessing
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.equalizeHist(img)
# The detector object detects features from the input image, then extracts
# descriptors from the image and matches them to the template descriptors
img_keypoints = detector.detect(img)
(img_keypoints, img_descriptors) = descriptor.compute(img, img_keypoints)
for i in range(len(card_files)):
matches = matcher.match(card_descriptors[i], img_descriptors)
# This stage extracts the best matches from the poorer ones
dist = [m.distance for m in matches]
thres_dist = (sum(dist) / len(dist)) * 0.5
good = [m for m in matches if m.distance < thres_dist]
# If the best matches are more than the MIN_MATCH_COUNT variable, then a card is
# detected
if len(good) > MIN_MATCH_COUNT:
if i != last_detected:
print "Has detectado la tarjeta:",card_names[i]
espeak.synth(card_names[i])
last_detected = i
# The points of matched features are stored in numpy arrays
src_pts = np.float32([ card_keypoints[i][m.queryIdx].pt for m in good ]).reshape(-1,1,2)
dst_pts = np.float32([ img_keypoints[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
# An homography is calculated to obtain the perspective transform
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
M2, mask2 = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC, 5.0)
matchesMask = mask.ravel().tolist()
h, w = template.shape
pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
# The perspective from the matched points is transformed according
# to the homography matrix M and contours are drawn over the input image
dst = cv2.perspectiveTransform(pts,M)
cv2.polylines(img,[np.int32(dst)],True,255,3, cv2.CV_AA)
# The card image is rectified using the M2 homography matrix
card = cv2.warpPerspective(img, M2, (img.shape[1], img.shape[0]))
card = card[0:h-1, 0:w-1]
cv2.imshow('Rectified Image', card)
# Prints to console that a card has been detected
#print 'A card has been detected \r',
sys.stdout.flush()
else:
# Prints to console that not enough matches have been found
print 'Not enough matches are found - %3d/%3d\r' % (len(good),MIN_MATCH_COUNT),
sys.stdout.flush()
matchesMask = None
cv2.imshow('Template', template)
cv2.imshow('Card Detection', img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()