Virtual Hand Cricket Game using OpenCV

Harshini Raju
Geek Culture
Published in
5 min readAug 21, 2021
Screenshot from the game

A virtual Hand Cricket game implemented using OpenCV and Machine learning technologies to enable plyers to relive the game virtually with a bot.

Objective :

As children, a lot of us grew up playing the game of hand cricket with our friends and had a lot of fun! During times of social distancing, I figured it would be fun to play the game virtually. Hence I opted for OpenCV to implement the game.

In this game, you have the Player(or User) and the Bot. The model will recognize the number the player shows and the bot will randomly generate a number. When both Player and Bot play the same number the user batting will get out and the other tries to beat them.

OpenCV

OpenCV (Open Source Computer Vision Library) is an open-source computer vision and machine learning software library. OpenCV was built to provide a common infrastructure for computer vision applications and to accelerate the use of machine perception in commercial products.

Importing Libraries

  • cv2: OpenCV [pip install opencv]
  • numpy: for handling arrays as well as for math [pip install numpy]
  • imutills: convenience functions to make basic image processing functions such as translation, rotation, resizing more easier with OpenCV[pip install imutils]
import cv2 as cv
import numpy as np
import imutils

Setting Initial Player and Bot Score

player_score = 0 
bot_score = 0
player = False
bot = True
player_status = False
bot_status = False
Game_status = “Player Begins”
def check_status(player_score, bot_score):
if player_score > bot_score:
print(‘* * * Player wins * * *’)
else:
print(‘* * * Bot wins * * *’)

Detecting the fingers/ Score of Player

To calculate the score of the player we will use OpenCV to detect the number of fingers live during video display. We are using contours, masks, convex hulls, and defect detection to identify the same.

Masks

  • hsv: Change BGR (blue, green, red) image to HSV (hue, saturation, value).
  • lower_skin: lower range of skin color in HSV.
  • upper_skin: upper range of skin color in HSV.
  • mask: Detect skin on the range of lower and upper pixel values in the HSV colorspace.
  • blur: blurring the image to improve masking
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_skin = np.array([0, 20, 80], dtype=np.uint8) upper_skin = np.array([20,255,255], dtype=np.uint8)
mask = cv2.inRange(hsv, lower_skin, upper_skin)
mask = cv2.dilate(mask,kernel,iterations = 4)
mask = cv2.GaussianBlur(mask,(5,5),100).

Contours

contours,hierarchy= cv2.findContours(mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)                          if len(contours) > 0:                
areas = [cv2.contourArea(c) for c in contours]
max_index = np.argmax(areas)
cnt = contours[max_index]
epsilon = 0.0005*cv2.arcLength(cnt,True)
approx= cv2.approxPolyDP(cnt,epsilon,True)

After identifying the maximum area and drawing the contours on the hand, we approximate it to get a much more accurate contour.

Convex Hull

hull = cv2.convexHull(cnt)
areahull = cv2.contourArea(hull)
areacnt = cv2.contourArea(cnt)

Counting Defects (Fingers)

According to the convex hull, we have formed, we are going to identify the defects. The defects are points that belong to the convex hull but not the contours.

Defects explained, image from: https://medium.com/analytics-vidhya/hand-detection-and-finger-counting-using-opencv-python-5b594704eb08
hull = cv2.convexHull(approx, returnPoints=False)          
defects = cv2.convexityDefects(approx, hull)

Counting Defects:

#code for finding no. of defects due to fingers            
for i in range(defects.shape[0]):
s,e,f,d = defects[i,0]
start = tuple(approx[s][0])
end = tuple(approx[e][0])
far = tuple(approx[f][0])

Cosine Theorem

We have calculated the number of fingers using the cosine theorem.

In trigonometry, the law of cosines relates the lengths of the sides of a triangle to the cosine of one of its angles.

Formula

Using this theorem and OpenCV’s Convexity Defects,m we are detecting and counting the fingers. Convexity Defects returns an array where each row contains these values: start point, endpoint, farthest point, and approximate distance to the farthest point.

# find length of all sides of triangle                
a = math.sqrt((end[0] - start[0])**2 + (end[1] - start[1])**2)
b= math.sqrt((far[0] - start[0])**2 + (far[1] - start[1])**2)
c = math.sqrt((end[0] - far[0])**2 + (end[1] - far[1])**2) # apply cosine rule here
angle = math.acos((b**2 + c**2 - a**2)/(2*b*c)) * 57
if angle <= 90:
count_defect += 1
cv2.circle(img, far, 5, (255,0,0), -1)
#draw lines around hand
cv2.line(img,start, end, (255,0,0), 3)
Finding defects using Cosine Theorem

Finally, assing the number of defects + 1 to the player’s score

count_defect += 1
player_num = count_defect

Calculating the Bot Score and Displaying

Assing the random function to the bot score when the Player is not batting and compare both scores and display.

If the Player bats first, add up the score of the player in each iteration.

Else, update the bot score accordingly.

Score Display

Flask API

To connect the model to Flask, there are 3 steps:

  1. Add the VideoCamera function
class VideoCamera(object):
def __init__(cap):
#real time video capture
cap.video = cv2.VideoCapture(0, cv2.CAP_DSHOW)
def __del__(cap):
cap.video.release()
def get_frame(cap):
try:

2. App.py

Add the output from the VideoCamera function to the flask app route function and import the necessary request.

3. index.html

Create a template folder and add an index.html file with similar content. Add the video feed from the function as the image tag in the HTML. If you want add more details to the HTML page.

<html>
<head>
<title>Hand Cricket API</title>
</head>
<body>
<h1>Hand Cricket API</h1>
<img id="bg" src="{{ url_for('game') }}">
</body>
</html>
API- Score Display During a Game

Also check out my GitHub repository for the whole code and star the repo: https://github.com/HarshiniR4/Virtual-Hand-Cricket

If you like the blog, do leave a star!

Happy Coding!

References:

--

--

Harshini Raju
Geek Culture

I’m a computer science student interested in Data Science and IoT. I also have a passion for writing and am a budding content writer.