├── .pypirc ├── LICENSE ├── PingPong.png ├── README.md ├── build └── lib │ └── virtualpp │ ├── __init__.py │ └── final.py ├── dist ├── virtualpp-0.0.7-py3-none-any.whl └── virtualpp-0.0.7.tar.gz ├── setup.py └── virtualpp ├── __init__.py ├── __pycache__ ├── __init__.cpython-36.pyc └── final.cpython-36.pyc └── final.py /.pypirc: -------------------------------------------------------------------------------- 1 | [distutils] 2 | index-servers=pypi 3 | [pypi] 4 | repository = https://upload.pypi.org/legacy/ 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 The Python Packaging Authority 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /PingPong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhijithneilabraham/virtualpp/3882b84b7091c23a0fc1ea8542282282c76c1b08/PingPong.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SINGLE PINGPONG-hand 2 | Playing a pingpong game with just color detection using opencv and python scripts 3 |

4 | PONG 6 |

7 | 8 | 9 | 10 | Using opencv, to detect a specific colour(of the glove),and draw a contour over it and use the glove movements to move the centroid obtained from the operations.This will in turn move the paddle for the game. 11 | 12 | The Game is written such a way that there is only a single player and you gotta survive for as much time as possible. 13 | 14 | **Installation** 15 | 16 | ``` 17 | pip install virtualpp 18 | ``` 19 | 20 | Example 21 | 22 | ``` 23 | from virtualpp import final 24 | final.GameColor("Green") 25 | ``` 26 | 27 | 28 | (optional)You can integrate this into a projector inside a dark room and it will give good results. 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /build/lib/virtualpp/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Tue Aug 27 23:51:36 2019 5 | 6 | @author: abhijithneilabraham 7 | """ 8 | 9 | name = "virtualpp" -------------------------------------------------------------------------------- /build/lib/virtualpp/final.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | import random 4 | import pygame 5 | from pygame.locals import * 6 | 7 | cap = cv2.VideoCapture(0) #This enables the camera.The value 1 is for external camera,0 for internal camera 8 | p=100 9 | i=0 10 | pygame.init() 11 | fps = pygame.time.Clock() 12 | 13 | #colors 14 | WHITE = (255,255,255) 15 | RED = (255,0,0) 16 | GREEN = (0,255,0) 17 | BLACK = (0,0,0) 18 | 19 | #globals 20 | WIDTH = 600 21 | HEIGHT = 400 22 | BALL_RADIUS = 20 23 | PAD_WIDTH = 8 24 | PAD_HEIGHT = 80 25 | HALF_PAD_WIDTH = PAD_WIDTH // 2 26 | HALF_PAD_HEIGHT = PAD_HEIGHT // 2 27 | ball_pos = [0,0] 28 | ball_vel = [0,0] 29 | paddle1_vel = 0 30 | paddle2_vel = 0 31 | l_score = 0 32 | r_score = 0 33 | 34 | #canvas declaration 35 | window = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32) 36 | pygame.display.set_caption('Ping Pong') 37 | 38 | # helper function that spawns a ball, returns a position vector and a velocity vector 39 | # if right is True, spawn to the right, else spawn to the left 40 | def ball_init(right): 41 | global ball_pos, ball_vel # these are vectors stored as lists 42 | ball_pos = [WIDTH//2,HEIGHT//2] 43 | horz = random.randrange(2,4) 44 | vert = random.randrange(1,3) 45 | 46 | if right == False: 47 | horz = - horz 48 | 49 | ball_vel = [horz,-vert] 50 | 51 | # define event handlers 52 | def init(): 53 | global paddle1_pos, paddle2_pos, paddle1_vel, paddle2_vel,l_score,r_score # these are floats 54 | global score1, score2 # these are ints 55 | paddle1_pos = [HALF_PAD_WIDTH - 1,HEIGHT//2] 56 | paddle2_pos = [WIDTH +1 - HALF_PAD_WIDTH,HEIGHT//2] 57 | l_score = 0 58 | r_score = 0 59 | if random.randrange(0,2) == 0: 60 | ball_init(True) 61 | else: 62 | ball_init(False) 63 | 64 | 65 | #draw function of canvas 66 | def draw(canvas): 67 | global paddle1_pos, paddle2_pos, ball_pos, ball_vel, l_score, r_score 68 | 69 | canvas.fill(BLACK) 70 | pygame.draw.line(canvas, WHITE, [WIDTH // 2, 0],[WIDTH // 2, HEIGHT], 1) 71 | pygame.draw.line(canvas, WHITE, [PAD_WIDTH, 0],[PAD_WIDTH, HEIGHT], 1) 72 | pygame.draw.line(canvas, WHITE, [WIDTH - PAD_WIDTH, 0],[WIDTH - PAD_WIDTH, HEIGHT], 1) 73 | pygame.draw.circle(canvas, WHITE, [WIDTH//2, HEIGHT//2], 70, 1) 74 | 75 | # update paddle's vertical position, keep paddle on the screen 76 | if paddle1_pos[1] > HALF_PAD_HEIGHT and paddle1_pos[1] < HEIGHT - HALF_PAD_HEIGHT: 77 | paddle1_pos[1] += paddle1_vel 78 | elif paddle1_pos[1] == HALF_PAD_HEIGHT and paddle1_vel > 0: 79 | paddle1_pos[1] += paddle1_vel 80 | elif paddle1_pos[1] == HEIGHT - HALF_PAD_HEIGHT and paddle1_vel < 0: 81 | paddle1_pos[1] += paddle1_vel 82 | 83 | if paddle2_pos[1] > HALF_PAD_HEIGHT and paddle2_pos[1] < HEIGHT - HALF_PAD_HEIGHT: 84 | paddle2_pos[1] += paddle2_vel 85 | elif paddle2_pos[1] == HALF_PAD_HEIGHT and paddle2_vel > 0: 86 | paddle2_pos[1] += paddle2_vel 87 | elif paddle2_pos[1] == HEIGHT - HALF_PAD_HEIGHT and paddle2_vel < 0: 88 | paddle2_pos[1] += paddle2_vel 89 | 90 | #update ball 91 | ball_pos[0] += int(ball_vel[0]) 92 | ball_pos[1] += int(ball_vel[1]) 93 | 94 | #draw paddles and ball 95 | pygame.draw.circle(canvas, RED, ball_pos, 20, 0) 96 | pygame.draw.polygon(canvas, GREEN, [[paddle1_pos[0] - HALF_PAD_WIDTH, paddle1_pos[1] - HALF_PAD_HEIGHT], [paddle1_pos[0] - HALF_PAD_WIDTH, paddle1_pos[1] + HALF_PAD_HEIGHT], [paddle1_pos[0] + HALF_PAD_WIDTH, paddle1_pos[1] + HALF_PAD_HEIGHT], [paddle1_pos[0] + HALF_PAD_WIDTH, paddle1_pos[1] - HALF_PAD_HEIGHT]], 0) 97 | pygame.draw.polygon(canvas, GREEN, [(592,0),(600,0),(600,1000),(592,1000)], 0) 98 | 99 | #ball collision check on top and bottom walls 100 | if int(ball_pos[1]) <= BALL_RADIUS: 101 | ball_vel[1] = - ball_vel[1] 102 | if int(ball_pos[1]) >= HEIGHT + 1 - BALL_RADIUS: 103 | ball_vel[1] = -ball_vel[1] 104 | 105 | #ball collison check on gutters or paddles 106 | if int(ball_pos[0]) <= BALL_RADIUS + PAD_WIDTH and int(ball_pos[1])>=paddle1_pos[1]-HALF_PAD_HEIGHT and int(ball_pos[1])<=paddle1_pos[1]+HALF_PAD_HEIGHT: 107 | ball_vel[0] = -ball_vel[0] 108 | ball_vel[0] *= 1.3 109 | ball_vel[1] *= 1.3 110 | elif int(ball_pos[0]) <= BALL_RADIUS + PAD_WIDTH: 111 | r_score += 1 112 | ball_init(True) 113 | 114 | if int(ball_pos[0]) >= WIDTH + 1 - BALL_RADIUS - PAD_WIDTH and int(ball_pos[1]) in range(0,592 + 500,1): 115 | ball_vel[0] = -ball_vel[0] 116 | ball_vel[0] *= 1.3 117 | ball_vel[1] *= 1.3 118 | 119 | #update scores 120 | myfont1 = pygame.font.SysFont("Comic Sans MS", 20) 121 | label1 = myfont1.render("Score "+str(l_score), 1, (255,255,0)) 122 | canvas.blit(label1, (50,20)) 123 | 124 | myfont2 = pygame.font.SysFont("Comic Sans MS", 20) 125 | label2 = myfont2.render("Score "+str(r_score), 1, (255,255,0)) 126 | canvas.blit(label2, (470, 20)) 127 | 128 | 129 | #keydown handler 130 | def keydown(event): 131 | global paddle1_vel, paddle2_vel 132 | ''' 133 | if event.key == K_w: 134 | paddle2_vel = -8 135 | elif event.key == K_s: 136 | paddle2_vel = 8 137 | ''' 138 | if event == 1 and paddle1_pos[1]>40: 139 | #paddle1_vel = -8 140 | paddle1_pos[1] += -0.5 141 | ''' 142 | elif event.key == K_DOWN: 143 | paddle1_vel = 8 144 | ''' 145 | 146 | #keyup handler 147 | def keyup(event): 148 | global paddle1_vel, paddle2_vel 149 | ''' 150 | if event.key in (K_UP, K_DOWN): 151 | paddle1_vel = 0 152 | ''' 153 | if event==1 and paddle1_pos[1]<360: 154 | #paddle2_vel = 8 155 | paddle1_pos[1] += 0.5 156 | 157 | init() 158 | 159 | def game(ColorLow,ColorHigh): 160 | #game loop 161 | cX=25 162 | cY=25 163 | while True: 164 | ret, frame = cap.read() #returns ret=either true or false. the frame variable has the frames 165 | hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 166 | ''' 167 | why did we convert to hsv ? because while using BGR,we have to use 3 values for color combinations(eg.(255,90,30)) 168 | But in case of hsv,for getting the required color,we have to change only one parameter,that is ,hue ,and the two other parameters can be changed just to change the saturation and values. 169 | ''' 170 | blur = cv2.GaussianBlur(hsv,(5,5),5) 171 | ''' 172 | The blurring is set to high here. we did blurring because,blurring eliminates the image noise and reduce detail. 173 | ''' 174 | lower_orange = np.array(ColorLow)#see,the hue from 0,30 is used here for orange,but remeber to set the other values too according to your need.If the other two values are zero,then you will get black because of zero intensity 175 | upper_orange = np.array(ColorHigh) 176 | mask = cv2.inRange(blur, lower_orange, upper_orange) 177 | ''' 178 | the color from lower orange to upper orange is noted here. 179 | ''' 180 | ret, thresh_img = cv2.threshold(mask,91,255,cv2.THRESH_BINARY) 181 | ''' 182 | Here, the matter is straight forward. 183 | If pixel value is greater than a threshold value, it is assigned one value (may be white), else it is assigned another value (may be black). 184 | The function used is cv.threshold. First argument is the source image, which should be a grayscale image. 185 | Second argument is the threshold value which is used to classify the pixel values. 186 | Third argument is the maxVal which represents the value to be given if pixel value is more than (sometimes less than) the threshold value. 187 | OpenCV provides different styles of thresholding and it is decided by the fourth parameter of the function. 188 | ''' 189 | contours = cv2.findContours(thresh_img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)[-2]#ah,the cool fun part!draw contours over the required orange area! 190 | ''' 191 | I gave the parameter thresh_img here as input. If I gave frame as input I would get contours for every shape in the camera. 192 | But by masking and thresholding, I have concentrated my interests into just the orange area . 193 | ''' 194 | M = cv2.moments(mask) 195 | if M["m00"]!=0 : 196 | cX = int(M["m10"] / M["m00"]) 197 | cY = int(M["m01"] / M["m00"]) 198 | #These moments and cX and cY ,i used to draw centroids.I will be using the centroid of the orange area. 199 | cv2.circle(frame, (cX, cY), 5, (255, 255, 255), -1) 200 | cv2.putText(frame, "centroid", (cX - 25, cY - 25),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2) 201 | for c in contours: 202 | cv2.drawContours(frame, [c], -1, (0,255,0), 3)#in previous function of contours i just only found contours. Now here I am drawing 203 | cv2.imshow("frame",frame) 204 | p=200 205 | i=0 206 | if cY>=p: 207 | for j in range(int((cY-p)/10)): 208 | keydown(1) 209 | 210 | p=cY 211 | ''' 212 | Simulating down arrow pressing when the centroid moves down 213 | ''' 214 | else: 215 | for j in range(int((p-cY)/10)): 216 | keyup(1) 217 | p=cY 218 | ''' 219 | Simulating up arrow pressing when the centroid moves up 220 | ''' 221 | if cv2.waitKey(1) & 0xFF == ord('q'): 222 | break 223 | draw(window) 224 | pygame.display.update() 225 | fps.tick(100) 226 | 227 | cap.release()#release the camera beast 228 | cv2.destroyAllWindows() 229 | def GameColor(color): 230 | if color=="GREEN": 231 | game([51,74,160],[90,147,255]) 232 | if color=="ORANGE": 233 | game([0,150,150],[30,255,255]) 234 | -------------------------------------------------------------------------------- /dist/virtualpp-0.0.7-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhijithneilabraham/virtualpp/3882b84b7091c23a0fc1ea8542282282c76c1b08/dist/virtualpp-0.0.7-py3-none-any.whl -------------------------------------------------------------------------------- /dist/virtualpp-0.0.7.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhijithneilabraham/virtualpp/3882b84b7091c23a0fc1ea8542282282c76c1b08/dist/virtualpp-0.0.7.tar.gz -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Tue Aug 27 23:27:34 2019 5 | 6 | @author: abhijithneilabraham 7 | """ 8 | 9 | 10 | import setuptools 11 | 12 | with open("README.md", "r") as fh: 13 | long_description = fh.read() 14 | 15 | setuptools.setup( 16 | name="virtualpp", 17 | version="0.0.7", 18 | author="Abhijith Neil Abraham", 19 | author_email="abhijithneilabrahampk@gmail.com", 20 | description="An opencv based virtual pingpong", 21 | long_description=long_description, 22 | long_description_content_type="text/markdown", 23 | url="https://github.com/abhijithneilabraham/PINGPONG-hand", 24 | packages=setuptools.find_packages(), 25 | classifiers=[ 26 | "Programming Language :: Python :: 3", 27 | "License :: OSI Approved :: MIT License", 28 | "Operating System :: OS Independent", 29 | ], 30 | ) 31 | -------------------------------------------------------------------------------- /virtualpp/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Tue Aug 27 23:51:36 2019 5 | 6 | @author: abhijithneilabraham 7 | """ 8 | 9 | name = "virtualpp" -------------------------------------------------------------------------------- /virtualpp/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhijithneilabraham/virtualpp/3882b84b7091c23a0fc1ea8542282282c76c1b08/virtualpp/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /virtualpp/__pycache__/final.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhijithneilabraham/virtualpp/3882b84b7091c23a0fc1ea8542282282c76c1b08/virtualpp/__pycache__/final.cpython-36.pyc -------------------------------------------------------------------------------- /virtualpp/final.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | import random 4 | import pygame 5 | from pygame.locals import * 6 | 7 | cap = cv2.VideoCapture(0) #This enables the camera.The value 1 is for external camera,0 for internal camera 8 | p=100 9 | i=0 10 | pygame.init() 11 | fps = pygame.time.Clock() 12 | 13 | #colors 14 | WHITE = (255,255,255) 15 | RED = (255,0,0) 16 | GREEN = (0,255,0) 17 | BLACK = (0,0,0) 18 | 19 | #globals 20 | WIDTH = 600 21 | HEIGHT = 400 22 | BALL_RADIUS = 20 23 | PAD_WIDTH = 8 24 | PAD_HEIGHT = 80 25 | HALF_PAD_WIDTH = PAD_WIDTH // 2 26 | HALF_PAD_HEIGHT = PAD_HEIGHT // 2 27 | ball_pos = [0,0] 28 | ball_vel = [0,0] 29 | paddle1_vel = 0 30 | paddle2_vel = 0 31 | l_score = 0 32 | r_score = 0 33 | 34 | #canvas declaration 35 | window = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32) 36 | pygame.display.set_caption('Ping Pong') 37 | 38 | # helper function that spawns a ball, returns a position vector and a velocity vector 39 | # if right is True, spawn to the right, else spawn to the left 40 | def ball_init(right): 41 | global ball_pos, ball_vel # these are vectors stored as lists 42 | ball_pos = [WIDTH//2,HEIGHT//2] 43 | horz = random.randrange(2,4) 44 | vert = random.randrange(1,3) 45 | 46 | if right == False: 47 | horz = - horz 48 | 49 | ball_vel = [horz,-vert] 50 | 51 | # define event handlers 52 | def init(): 53 | global paddle1_pos, paddle2_pos, paddle1_vel, paddle2_vel,l_score,r_score # these are floats 54 | global score1, score2 # these are ints 55 | paddle1_pos = [HALF_PAD_WIDTH - 1,HEIGHT//2] 56 | paddle2_pos = [WIDTH +1 - HALF_PAD_WIDTH,HEIGHT//2] 57 | l_score = 0 58 | r_score = 0 59 | if random.randrange(0,2) == 0: 60 | ball_init(True) 61 | else: 62 | ball_init(False) 63 | 64 | 65 | #draw function of canvas 66 | def draw(canvas): 67 | global paddle1_pos, paddle2_pos, ball_pos, ball_vel, l_score, r_score 68 | 69 | canvas.fill(BLACK) 70 | pygame.draw.line(canvas, WHITE, [WIDTH // 2, 0],[WIDTH // 2, HEIGHT], 1) 71 | pygame.draw.line(canvas, WHITE, [PAD_WIDTH, 0],[PAD_WIDTH, HEIGHT], 1) 72 | pygame.draw.line(canvas, WHITE, [WIDTH - PAD_WIDTH, 0],[WIDTH - PAD_WIDTH, HEIGHT], 1) 73 | pygame.draw.circle(canvas, WHITE, [WIDTH//2, HEIGHT//2], 70, 1) 74 | 75 | # update paddle's vertical position, keep paddle on the screen 76 | if paddle1_pos[1] > HALF_PAD_HEIGHT and paddle1_pos[1] < HEIGHT - HALF_PAD_HEIGHT: 77 | paddle1_pos[1] += paddle1_vel 78 | elif paddle1_pos[1] == HALF_PAD_HEIGHT and paddle1_vel > 0: 79 | paddle1_pos[1] += paddle1_vel 80 | elif paddle1_pos[1] == HEIGHT - HALF_PAD_HEIGHT and paddle1_vel < 0: 81 | paddle1_pos[1] += paddle1_vel 82 | 83 | if paddle2_pos[1] > HALF_PAD_HEIGHT and paddle2_pos[1] < HEIGHT - HALF_PAD_HEIGHT: 84 | paddle2_pos[1] += paddle2_vel 85 | elif paddle2_pos[1] == HALF_PAD_HEIGHT and paddle2_vel > 0: 86 | paddle2_pos[1] += paddle2_vel 87 | elif paddle2_pos[1] == HEIGHT - HALF_PAD_HEIGHT and paddle2_vel < 0: 88 | paddle2_pos[1] += paddle2_vel 89 | 90 | #update ball 91 | ball_pos[0] += int(ball_vel[0]) 92 | ball_pos[1] += int(ball_vel[1]) 93 | 94 | #draw paddles and ball 95 | pygame.draw.circle(canvas, RED, ball_pos, 20, 0) 96 | pygame.draw.polygon(canvas, GREEN, [[paddle1_pos[0] - HALF_PAD_WIDTH, paddle1_pos[1] - HALF_PAD_HEIGHT], [paddle1_pos[0] - HALF_PAD_WIDTH, paddle1_pos[1] + HALF_PAD_HEIGHT], [paddle1_pos[0] + HALF_PAD_WIDTH, paddle1_pos[1] + HALF_PAD_HEIGHT], [paddle1_pos[0] + HALF_PAD_WIDTH, paddle1_pos[1] - HALF_PAD_HEIGHT]], 0) 97 | pygame.draw.polygon(canvas, GREEN, [(592,0),(600,0),(600,1000),(592,1000)], 0) 98 | 99 | #ball collision check on top and bottom walls 100 | if int(ball_pos[1]) <= BALL_RADIUS: 101 | ball_vel[1] = - ball_vel[1] 102 | if int(ball_pos[1]) >= HEIGHT + 1 - BALL_RADIUS: 103 | ball_vel[1] = -ball_vel[1] 104 | 105 | #ball collison check on gutters or paddles 106 | if int(ball_pos[0]) <= BALL_RADIUS + PAD_WIDTH and int(ball_pos[1])>=paddle1_pos[1]-HALF_PAD_HEIGHT and int(ball_pos[1])<=paddle1_pos[1]+HALF_PAD_HEIGHT: 107 | ball_vel[0] = -ball_vel[0] 108 | ball_vel[0] *= 1.3 109 | ball_vel[1] *= 1.3 110 | elif int(ball_pos[0]) <= BALL_RADIUS + PAD_WIDTH: 111 | r_score += 1 112 | ball_init(True) 113 | 114 | if int(ball_pos[0]) >= WIDTH + 1 - BALL_RADIUS - PAD_WIDTH and int(ball_pos[1]) in range(0,592 + 500,1): 115 | ball_vel[0] = -ball_vel[0] 116 | ball_vel[0] *= 1.3 117 | ball_vel[1] *= 1.3 118 | 119 | #update scores 120 | myfont1 = pygame.font.SysFont("Comic Sans MS", 20) 121 | label1 = myfont1.render("Score "+str(l_score), 1, (255,255,0)) 122 | canvas.blit(label1, (50,20)) 123 | 124 | myfont2 = pygame.font.SysFont("Comic Sans MS", 20) 125 | label2 = myfont2.render("Score "+str(r_score), 1, (255,255,0)) 126 | canvas.blit(label2, (470, 20)) 127 | 128 | 129 | #keydown handler 130 | def keydown(event): 131 | global paddle1_vel, paddle2_vel 132 | ''' 133 | if event.key == K_w: 134 | paddle2_vel = -8 135 | elif event.key == K_s: 136 | paddle2_vel = 8 137 | ''' 138 | if event == 1 and paddle1_pos[1]>40: 139 | #paddle1_vel = -8 140 | paddle1_pos[1] += -0.5 141 | ''' 142 | elif event.key == K_DOWN: 143 | paddle1_vel = 8 144 | ''' 145 | 146 | #keyup handler 147 | def keyup(event): 148 | global paddle1_vel, paddle2_vel 149 | ''' 150 | if event.key in (K_UP, K_DOWN): 151 | paddle1_vel = 0 152 | ''' 153 | if event==1 and paddle1_pos[1]<360: 154 | #paddle2_vel = 8 155 | paddle1_pos[1] += 0.5 156 | 157 | init() 158 | 159 | def game(ColorLow,ColorHigh): 160 | #game loop 161 | cX=25 162 | cY=25 163 | while True: 164 | ret, frame = cap.read() #returns ret=either true or false. the frame variable has the frames 165 | hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 166 | ''' 167 | why did we convert to hsv ? because while using BGR,we have to use 3 values for color combinations(eg.(255,90,30)) 168 | But in case of hsv,for getting the required color,we have to change only one parameter,that is ,hue ,and the two other parameters can be changed just to change the saturation and values. 169 | ''' 170 | blur = cv2.GaussianBlur(hsv,(5,5),5) 171 | ''' 172 | The blurring is set to high here. we did blurring because,blurring eliminates the image noise and reduce detail. 173 | ''' 174 | lower_orange = np.array(ColorLow)#see,the hue from 0,30 is used here for orange,but remeber to set the other values too according to your need.If the other two values are zero,then you will get black because of zero intensity 175 | upper_orange = np.array(ColorHigh) 176 | mask = cv2.inRange(blur, lower_orange, upper_orange) 177 | ''' 178 | the color from lower orange to upper orange is noted here. 179 | ''' 180 | ret, thresh_img = cv2.threshold(mask,91,255,cv2.THRESH_BINARY) 181 | ''' 182 | Here, the matter is straight forward. 183 | If pixel value is greater than a threshold value, it is assigned one value (may be white), else it is assigned another value (may be black). 184 | The function used is cv.threshold. First argument is the source image, which should be a grayscale image. 185 | Second argument is the threshold value which is used to classify the pixel values. 186 | Third argument is the maxVal which represents the value to be given if pixel value is more than (sometimes less than) the threshold value. 187 | OpenCV provides different styles of thresholding and it is decided by the fourth parameter of the function. 188 | ''' 189 | contours = cv2.findContours(thresh_img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)[-2]#ah,the cool fun part!draw contours over the required orange area! 190 | ''' 191 | I gave the parameter thresh_img here as input. If I gave frame as input I would get contours for every shape in the camera. 192 | But by masking and thresholding, I have concentrated my interests into just the orange area . 193 | ''' 194 | M = cv2.moments(mask) 195 | if M["m00"]!=0 : 196 | cX = int(M["m10"] / M["m00"]) 197 | cY = int(M["m01"] / M["m00"]) 198 | #These moments and cX and cY ,i used to draw centroids.I will be using the centroid of the orange area. 199 | cv2.circle(frame, (cX, cY), 5, (255, 255, 255), -1) 200 | cv2.putText(frame, "centroid", (cX - 25, cY - 25),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2) 201 | for c in contours: 202 | cv2.drawContours(frame, [c], -1, (0,255,0), 3)#in previous function of contours i just only found contours. Now here I am drawing 203 | cv2.imshow("frame",frame) 204 | p=200 205 | i=0 206 | if cY>=p: 207 | for j in range(int((cY-p)/10)): 208 | keydown(1) 209 | 210 | p=cY 211 | ''' 212 | Simulating down arrow pressing when the centroid moves down 213 | ''' 214 | else: 215 | for j in range(int((p-cY)/10)): 216 | keyup(1) 217 | p=cY 218 | ''' 219 | Simulating up arrow pressing when the centroid moves up 220 | ''' 221 | if cv2.waitKey(1) & 0xFF == ord('q'): 222 | break 223 | draw(window) 224 | pygame.display.update() 225 | fps.tick(100) 226 | 227 | cap.release()#release the camera beast 228 | cv2.destroyAllWindows() 229 | def GameColor(color): 230 | if color=="GREEN": 231 | game([51,74,160],[90,147,255]) 232 | if color=="ORANGE": 233 | game([0,150,150],[30,255,255]) 234 | --------------------------------------------------------------------------------