Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
826 changes: 702 additions & 124 deletions CardDetector.py

Large diffs are not rendered by default.

21 changes: 18 additions & 3 deletions Cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,12 @@ def find_cards(thresh_image):
from largest to smallest."""

# Find contours and sort their indices by contour size
dummy,cnts,hier = cv2.findContours(thresh_image,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contours = cv2.findContours(thresh_image,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
if len(contours) == 3:
dummy,cnts,hier = contours
else: # OpenCV 4 compatibility
cnts,hier = contours
dummy = None
index_sort = sorted(range(len(cnts)), key=lambda i : cv2.contourArea(cnts[i]),reverse=True)

# If there are no contours, do nothing
Expand Down Expand Up @@ -212,7 +217,12 @@ def preprocess_card(contour, image):
Qsuit = query_thresh[186:336, 0:128]

# Find rank contour and bounding rectangle, isolate and find largest contour
dummy, Qrank_cnts, hier = cv2.findContours(Qrank, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contours = cv2.findContours(Qrank, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
if len(contours) == 3:
dummy, Qrank_cnts, hier = contours
else:
Qrank_cnts, hier = contours
dummy = None
Qrank_cnts = sorted(Qrank_cnts, key=cv2.contourArea,reverse=True)

# Find bounding rectangle for largest contour, use it to resize query rank
Expand All @@ -224,7 +234,12 @@ def preprocess_card(contour, image):
qCard.rank_img = Qrank_sized

# Find suit contour and bounding rectangle, isolate and find largest contour
dummy, Qsuit_cnts, hier = cv2.findContours(Qsuit, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contours = cv2.findContours(Qsuit, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
if len(contours) == 3:
dummy, Qsuit_cnts, hier = contours
else:
Qsuit_cnts, hier = contours
dummy = None
Qsuit_cnts = sorted(Qsuit_cnts, key=cv2.contourArea,reverse=True)

# Find bounding rectangle for largest contour, use it to resize query suit
Expand Down
81 changes: 58 additions & 23 deletions Rank_Suit_Isolator.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### Runs through A - K ranks and then the 4 suits.

# Import necessary packages
import argparse
import cv2
import numpy as np
import time
Expand All @@ -20,23 +21,39 @@
SUIT_WIDTH = 70
SUIT_HEIGHT = 100

# If using a USB Camera instead of a PiCamera, change PiOrUSB to 2
PiOrUSB = 1

if PiOrUSB == 1:
# Import packages from picamera library
from picamera.array import PiRGBArray
from picamera import PiCamera

# Initialize PiCamera and grab reference to the raw capture
camera = PiCamera()
camera.resolution = (IM_WIDTH,IM_HEIGHT)
camera.framerate = 10
rawCapture = PiRGBArray(camera, size=(IM_WIDTH,IM_HEIGHT))

if PiOrUSB == 2:
# Initialize USB camera
cap = cv2.VideoCapture(0)
parser = argparse.ArgumentParser(description="Rank/Suit isolator camera settings")
parser.add_argument("--camera-type", choices=["auto","pi","usb"], default="auto",
help="Select camera backend: 'pi' for PiCamera, 'usb' for USB/Continuity Camera, 'auto' tries Pi then USB.")
parser.add_argument("--camera-index", type=int, default=0,
help="USB camera index (ignored for PiCamera). Use when multiple cameras are connected.")
args = parser.parse_args()

camera = None
rawCapture = None
cap = None
camera_type_used = None

if args.camera_type in ("pi", "auto"):
try:
from picamera.array import PiRGBArray
from picamera import PiCamera
camera = PiCamera()
camera.resolution = (IM_WIDTH,IM_HEIGHT)
camera.framerate = 10
rawCapture = PiRGBArray(camera, size=(IM_WIDTH,IM_HEIGHT))
camera_type_used = "pi"
except ModuleNotFoundError:
if args.camera_type == "pi":
raise
print("picamera module not found; defaulting to USB camera.")

if camera_type_used != "pi":
cap = cv2.VideoCapture(args.camera_index)
if not cap.isOpened():
raise RuntimeError(f"Unable to open USB camera at index {args.camera_index}.")
cap.set(cv2.CAP_PROP_FRAME_WIDTH, IM_WIDTH)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, IM_HEIGHT)
camera_type_used = "usb"

# Use counter variable to switch from isolating Rank to isolating Suit
i = 1
Expand All @@ -51,7 +68,7 @@



if PiOrUSB == 1: # PiCamera
if camera_type_used == "pi": # PiCamera
rawCapture.truncate(0)
# Press 'p' to take a picture
for frame in camera.capture_continuous(rawCapture, format="bgr",use_video_port=True):
Expand All @@ -64,7 +81,7 @@

rawCapture.truncate(0)

if PiOrUSB == 2: # USB camera
if camera_type_used == "usb": # USB camera
# Press 'p' to take a picture
while(True):

Expand All @@ -81,7 +98,12 @@
retval, thresh = cv2.threshold(blur,100,255,cv2.THRESH_BINARY)

# Find contours and sort them by size
dummy,cnts,hier = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contours = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
if len(contours) == 3:
dummy,cnts,hier = contours
else:
cnts,hier = contours
dummy = None
cnts = sorted(cnts, key=cv2.contourArea,reverse=True)

# Assume largest contour is the card. If there are no contours, print an error
Expand Down Expand Up @@ -114,7 +136,12 @@
# Isolate suit or rank
if i <= 13: # Isolate rank
rank = corner_thresh[20:185, 0:128] # Grabs portion of image that shows rank
dummy, rank_cnts, hier = cv2.findContours(rank, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contours = cv2.findContours(rank, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
if len(contours) == 3:
dummy, rank_cnts, hier = contours
else:
rank_cnts, hier = contours
dummy = None
rank_cnts = sorted(rank_cnts, key=cv2.contourArea,reverse=True)
x,y,w,h = cv2.boundingRect(rank_cnts[0])
rank_roi = rank[y:y+h, x:x+w]
Expand All @@ -123,7 +150,12 @@

if i > 13: # Isolate suit
suit = corner_thresh[186:336, 0:128] # Grabs portion of image that shows suit
dummy, suit_cnts, hier = cv2.findContours(suit, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contours = cv2.findContours(suit, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
if len(contours) == 3:
dummy, suit_cnts, hier = contours
else:
suit_cnts, hier = contours
dummy = None
suit_cnts = sorted(suit_cnts, key=cv2.contourArea,reverse=True)
x,y,w,h = cv2.boundingRect(suit_cnts[0])
suit_roi = suit[y:y+h, x:x+w]
Expand All @@ -141,4 +173,7 @@
i = i + 1

cv2.destroyAllWindows()
camera.close()
if camera_type_used == "pi":
camera.close()
elif camera_type_used == "usb" and cap is not None:
cap.release()
Binary file added __pycache__/Cards.cpython-313.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added __pycache__/VideoStream.cpython-313.pyc
Binary file not shown.