├── .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 |
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 |
--------------------------------------------------------------------------------