-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathmain.py
112 lines (92 loc) · 5.06 KB
/
main.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
import cv2
import numpy as np
import cardData
import utils
def readCard():
phoneCamFeed = True # Flag signaling if images are being read live from phone camera or from image file
pathImage = 'testImages/tiltright.jpg' # File name of image
cam = cv2.VideoCapture(1) # Use Video source 1 = phone; 0 = computer webcam
# Scaled to the IRL height and width of a Pokemon card (6.6 cm x 8.8 cm)
widthCard = utils.getWidthCard()
heightCard = utils.getHeightCard()
while True:
# Create a blank image
blackImg = np.zeros((heightCard, widthCard, 3), np.uint8)
# Check if using phone camera or saved picture
if phoneCamFeed:
# Read in frame and rotate 90 degrees b/c video comes in horizontally
check, frame = cam.read()
rot90frame = cv2.rotate(frame, cv2.ROTATE_90_CLOCKWISE)
rot90frame = cv2.resize(rot90frame, (widthCard, heightCard))
else:
# Read in picture and resize it to normalize
pic = cv2.imread(pathImage)
rot90frame = pic.copy()
# Make image gray scale
grayFrame = cv2.cvtColor(rot90frame, cv2.COLOR_BGR2GRAY)
# Blur the image to reduce noise
blurredFrame = cv2.GaussianBlur(grayFrame, (3, 3), 0)
# Use Canny edge detection to get edges
edgedFrame = cv2.Canny(image=blurredFrame, threshold1=100, threshold2=200)
# Clean up edges
kernel = np.ones((5,5))
frameDial = cv2.dilate(edgedFrame, kernel, iterations=2)
frameThreshold = cv2.erode(frameDial, kernel, iterations=1)
# Get image contours
contourFrame = rot90frame.copy()
bigContour = rot90frame.copy()
contours, hierarchy = cv2.findContours(frameThreshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(contourFrame, contours, -1, (0, 255, 0), 10)
imgWarpColored = blackImg # Set imgWarpColored
# Get biggest contour
corners, maxArea = utils.biggestContour(contours)
if len(corners) == 4:
corners = [corners[0][0], corners[1][0], corners[2][0], corners[3][0]]
corners = utils.reorderCorners(corners) # Reorders corners to [topLeft, topRight, bottomLeft, bottomRight]
#cv2.drawContours(bigContour, corners, -1, (0, 255, 0), 10)
bigContour = utils.drawRectangle(bigContour, corners)
pts1 = np.float32(corners)
pts2 = np.float32([[0, 0], [widthCard, 0], [0, heightCard], [widthCard, heightCard]])
# Makes a matrix that transforms the detected card to a vertical rectangle
matrix = cv2.getPerspectiveTransform(pts1, pts2)
# Transforms card to a rectangle widthCard x heightCard
imgWarpColored = cv2.warpPerspective(rot90frame, matrix, (widthCard, heightCard))
# Resize all of the images to the same dimensions
# Note: imgWarpColored is already resized and matchingCard gets resized in utils.getMatchingCard()
rot90frame = cv2.resize(rot90frame, (widthCard, heightCard))
grayFrame = cv2.resize(grayFrame, (widthCard, heightCard))
blurredFrame = cv2.resize(blurredFrame, (widthCard, heightCard))
edgedFrame = cv2.resize(edgedFrame, (widthCard, heightCard))
contourFrame = cv2.resize(contourFrame, (widthCard, heightCard))
bigContour = cv2.resize(bigContour, (widthCard, heightCard))
# Check if a matching card has been found, and if so, display it
found, matchingCard = utils.findCard(imgWarpColored.copy()) # Check to see if a matching card was found
# An array of all 8 images
imageArr = ([rot90frame, grayFrame, blurredFrame, edgedFrame],
[contourFrame, bigContour, imgWarpColored, matchingCard])
# Labels for each image
labels = [["Original", "Gray", "Blurred", "Threshold"],
["Contours", "Biggest Contour", "Warped Perspective", "Matching Card"]]
# Stack all 8 images into one and add text labels
stackedImage = utils.makeDisplayImage(imageArr, labels)
# Display the image
cv2.imshow("Card Finder", stackedImage)
if not phoneCamFeed: # If reading image file, display image until key is pressed
if not found: # If a matching card has not been found
print('Please try another image. Your card could not be found.')
cv2.waitKey(0) # Keeps window open until any key is pressed
break
elif cv2.waitKey(1) & 0xFF == ord('q'): # If reading from video, quit if 'q' is pressed
break
elif found: # If the input is a video and a matching card has been found
print('\n\nPress any key to exit.')
cv2.waitKey(0)
break
# Stops cameras and closes display window
cam.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
isFirst = False # True if this is your first time running this code; will create a new database
if isFirst:
cardData.createDatabase()
readCard() # Finds and reads from a saved image or live feed