Source code for perception.squareClass

import cv2
import numpy as np


[docs]class Square: """ Class holding the position, index, corners, empty colour and state of a chess square """ def __init__(self, position, c1, c2, c3, c4, index, image, state=''): # ID self.position = position self.index = index # Corners self.c1 = c1 self.c2 = c2 self.c3 = c3 self.c4 = c4 # State self.state = state # Actual polygon as a numpy array of corners self.contours = np.array([c1, c2, c3, c4], dtype=np.int32) # Properties of the contour self.area = cv2.contourArea(self.contours) self.perimeter = cv2.arcLength(self.contours, True) M = cv2.moments(self.contours) cx = int(M['m10'] / M['m00']) cy = int(M['m01'] / M['m00']) # ROI is the small circle within the square on which we will do the averaging self.roi = (cx, cy) self.radius = 5 # Empty color. The colour the square has when it's not occupied, i.e. shade of black or white. By storing these # at the beginnig of the game, we can then make much more robust predictions on how the state of the board has # changed. self.emptyColor = self.roiColor(image)
[docs] def draw(self, image, color=(0, 0, 255), thickness=2): """ Draws the square onto an image. """ cv2.drawContours(image, [self.contours], 0, color, thickness) ## DEBUG cv2.circle(image, self.roi, self.radius, (0, 0, 255), 1)
[docs] def getDepth(self, depthImage): depth = depthImage[self.roi[1], self.roi[0]] coordinates = self.roi[0], self.roi[1], depth[0] return coordinates
[docs] def roiColor(self, image): """ Finds the averaged color within the ROI within the square. The ROI is a circle with radius r from the centre of the square. """ # Initialise mask maskImage = np.zeros((image.shape[0], image.shape[1]), np.uint8) # Draw the ROI circle on the mask cv2.circle(maskImage, self.roi, self.radius, (255, 255, 255), -1) # Find the average color average_raw = cv2.mean(image, mask=maskImage)[::-1] # Need int format so reassign variable average = (int(average_raw[1]), int(average_raw[2]), int(average_raw[3])) ## DEBUG # print(average) return average
[docs] def classify(self, image, drawParam=False, debug=False): """ Returns the RGB 3-dimensional distance from a squares current color to its empty color. """ if debug: print("The empty color of the square is: " + str(self.emptyColor)) # Find Color of ROI rgb = self.roiColor(image) if debug: print("The current color of the square is: " + str(rgb)) # Flag state = '' # Distance to empty color in 3D color space summed = 0 for i in range(len(rgb)): summed += (self.emptyColor[i] - rgb[i])**2 distance = np.sqrt(summed) print("Distance of match to empty square color: " + str(distance)) threshold = 40 # If distance is below threshold assign empty # if distance < threshold: # print("Square is empty again. Assigning State E to: " + str(self.position)) # state = 'E' if drawParam: cv2.putText(image, state, self.roi, cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1, cv2.LINE_AA) ## DEBUG # print(flag) return distance