Face recognition aircraft war
Do you have the following problems:
- The college has a garden party. Do you want to find an interactive game to show the characteristics of information specialty?
- The oars set up the stage to recruit new people. They yelled hard and sent out a lot of leaflets. Can't the atmosphere be lively?
- After watching the live broadcast of the summit, the boss's project configuration requirements are high, and the peripherals are too expensive to afford?
This project provides a demonstration project with simple code, strong modification and certain interest for new recruitment and other exhibition activities.
This project is modified based on the classic pyganme project - aircraft war game, and realizes real-time face detection based on open cv. It can be controlled in real time on personal computer. The project notes are complete and suitable for secondary development.
1. Game demonstration and introduction
1.1 demonstration effect
Your browser does not support video tags.1.2 introduction to aircraft war game
-
In the aircraft war game, players control the aircraft and win points by firing shells to kill other small aircraft. Finally, the top ten scores enter the ranking list.
-
The game uses WSAD / direction keys / face movement recognition to control aircraft movement in three ways.
-
The game ends when a missed plane is not destroyed or the player's plane collides with another plane
2. Main codes and notes
-
The code is only for comments. The notebook has no camera device and cannot run online
-
The game needs to work / aircraft War Game v1 Zip download to local unzip
-
After installing pygame and opencv Python libraries, run main Py file!!!
## Pay special attention to the need to install pygame package and open CV package in advance !pip install pygame !pip install opencv-python
# -*- coding: utf-8 -*- import pygame from pygame.locals import * from sys import exit import random import cv2 import numpy as np import pygame.camera import time # Set game screen size SCREEN_WIDTH = 480 SCREEN_HEIGHT = 800 import codecs # ZiDan class Bullet(pygame.sprite.Sprite): def __init__(self, bullet_img, init_pos): pygame.sprite.Sprite.__init__(self) self.image = bullet_img self.rect = self.image.get_rect() self.rect.midbottom = init_pos self.speed = 10 def move(self): self.rect.top -= self.speed # Player aircraft class Player(pygame.sprite.Sprite): def __init__(self, plane_img, player_rect, init_pos): pygame.sprite.Sprite.__init__(self) self.image = [] # A list used to store player aircraft pictures for i in range(len(player_rect)): self.image.append(plane_img.subsurface(player_rect[i]).convert_alpha()) self.rect = player_rect[0] # Initializes the rectangle where the picture is located self.rect.topleft = init_pos # Initializes the coordinates of the upper left corner of the rectangle self.speed = 2 # Initialize the player's aircraft speed. Here is a certain value self.bullets = pygame.sprite.Group() # A collection of bullets fired by a player's aircraft self.img_index = 0 # Player plane picture index self.is_hit = False # Is the player hit # Fire bullets def shoot(self, bullet_img): bullet = Bullet(bullet_img, self.rect.midtop) self.bullets.add(bullet) # To move up, you need to judge the boundary def moveUp(self,speedRatio): if self.rect.top <= 0: self.rect.top = 0 else: self.rect.top -= self.speed * speedRatio # To move down, you need to judge the boundary def moveDown(self,speedRatio): if self.rect.top >= SCREEN_HEIGHT - self.rect.height: self.rect.top = SCREEN_HEIGHT - self.rect.height else: self.rect.top += self.speed * speedRatio # To move to the left, you need to judge the boundary def moveLeft(self,speedRatio): if self.rect.left <= 0: self.rect.left = 0 else: self.rect.left -= self.speed * speedRatio # To move to the right, you need to judge the boundary def moveRight(self,speedRatio): if self.rect.left >= SCREEN_WIDTH - self.rect.width: self.rect.left = SCREEN_WIDTH - self.rect.width else: self.rect.left += self.speed * speedRatio # Enemy aircraft class Enemy(pygame.sprite.Sprite): def __init__(self, enemy_img, enemy_down_imgs, init_pos): pygame.sprite.Sprite.__init__(self) self.image = enemy_img self.rect = self.image.get_rect() self.rect.topleft = init_pos self.down_imgs = enemy_down_imgs self.speed = 3 self.down_index = 0 # Enemy aircraft movement, boundary judgment and deletion are handled in the main loop of the game def move(self): self.rect.top += self.speed # Convert the surface of pygame to numpy Array uses opencv for face detection def pygame_to_cvimage(face_cascade,surface): image_np = pygame.surfarray.array3d(surface) image_np = np.rot90(image_np, -1) frame = cv2.cvtColor(image_np, cv2.COLOR_BGR2RGB) faces = face_cascade.detectMultiScale(frame,scaleFactor=1.1,minNeighbors=5) # Face detection x,y,w,h =0,0,0,0 if len(faces)>0: x,y,w,h = faces[0] # If there are multiple faces, generally take the nearest one cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2) return frame,x+0.5*w,y+0.5*h # Operations on files # Write text: # The incoming parameters are content, string, path; Content is the content to be written, and the data type is string. # path is the write location, and the data type is string. String write mode # The incoming path needs to be defined as follows: path= r'd: \ text txt’ # f = codecs. In open (path, strip, 'utf8'), codecs is a package, which needs to be imported with importer. # Trim = 'a' means to write txt additionally, which can be replaced by 'w', which means to write overwrite. # 'utf8' indicates the code written, which can be replaced by 'utf16'. def write_txt(content, strim, path): f = codecs.open(path, strim, 'utf8') f.write(str(content)) f.close() # Read txt: # It means to read txt files by line, and UTF8 means to read files encoded as utf8, which can be changed to utf16 or GBK as required. # The returned is an array, and the elements of each array represent a row, # If you want to return the string format, you can rewrite it to return '\ n' join(lines) def read_txt(path): with open(path, 'r', encoding='utf8') as f: lines = f.readlines() return lines # Initialize pygame pygame.init() # Set the game interface size, background picture and title # Game interface pixel size screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) # Game interface title pygame.display.set_caption('Aircraft war') # Icon ic_launcher = pygame.image.load('resources/image/ic_launcher.png').convert_alpha() pygame.display.set_icon(ic_launcher) # Background map background = pygame.image.load('resources/image/background.png').convert() # Background image of Game Over game_over = pygame.image.load('resources/image/gameover.png') # Collection of pictures of aircraft and bullets plane_img = pygame.image.load('resources/image/shoot.png') def startGame(): # Set the picture list of player's aircraft in different states, and multiple pictures are displayed as animation effects player_rect = [] # Player plane picture player_rect.append(pygame.Rect(0, 99, 102, 126)) player_rect.append(pygame.Rect(165, 360, 102, 126)) # Player explosion picture player_rect.append(pygame.Rect(165, 234, 102, 126)) player_rect.append(pygame.Rect(330, 624, 102, 126)) player_rect.append(pygame.Rect(330, 498, 102, 126)) player_rect.append(pygame.Rect(432, 624, 102, 126)) player_pos = [200, 600] player = Player(plane_img, player_rect, player_pos) # Bullet picture bullet_rect = pygame.Rect(69, 77, 10, 21) bullet_img = plane_img.subsurface(bullet_rect) # List of pictures of enemy aircraft in different states, and multiple pictures are displayed as animation effects enemy1_rect = pygame.Rect(534, 612, 57, 43) enemy1_img = plane_img.subsurface(enemy1_rect) enemy1_down_imgs = [] enemy1_down_imgs.append(plane_img.subsurface(pygame.Rect(267, 347, 57, 43))) enemy1_down_imgs.append(plane_img.subsurface(pygame.Rect(873, 697, 57, 43))) enemy1_down_imgs.append(plane_img.subsurface(pygame.Rect(267, 296, 57, 43))) enemy1_down_imgs.append(plane_img.subsurface(pygame.Rect(930, 697, 57, 43))) # Store enemy aircraft enemies1 = pygame.sprite.Group() # Store destroyed aircraft for rendering destruction animation enemies_down = pygame.sprite.Group() # Initialize firing and enemy aircraft movement frequency shoot_frequency = 0 enemy_frequency = 0 # Effect processing after the player's plane is hit player_down_index = 16 # Initialization score score = 0 # Game cycle frame rate setting clock = pygame.time.Clock() # Parameters for judging game loop exit running = True # Read cv face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml") pygame.camera.init() device = pygame.camera.list_cameras() last_loc_x,last_loc_y,next_loc_x,next_loc_y = 0,0,0,0 cam = pygame.camera.Camera(device[0], [320, 320]) # Controlling the camera photo size can also effectively reduce Caton #for _ in range(1): #time.sleep(1) cam.start() # Game main loop # The camera is buffered and detected every few frames to effectively reduce the jamming camShuffleValue = 15 while running: if enemy_frequency%camShuffleValue == 0: image = cam.get_image() frame,x_,y_ = pygame_to_cvimage(face_cascade,image) if (next_loc_x ==0 and next_loc_y==0) or (x_==0 and y_==0): # Detected for the first time or not detected last_loc_x,last_loc_y = 0,0 next_loc_x,next_loc_y = x_,y_ else: # Non first detection last_loc_x,last_loc_y = next_loc_x,next_loc_y next_loc_x,next_loc_y = x_,y_ Hor = next_loc_x - last_loc_x Ver = next_loc_y - last_loc_y key_pressed = pygame.key.get_pressed() thresholdValue = 5 # Set the movement threshold to avoid drift caused by small jitter # Handle keyboard events (position of moving aircraft) + face detection if key_pressed[K_w] or key_pressed[K_UP] or Ver<-1*thresholdValue : player.moveUp(np.clip(np.sqrt(np.abs(Ver)),0,5)) # Distance after passing in function processing if key_pressed[K_s] or key_pressed[K_DOWN] or Ver>thresholdValue: player.moveDown(np.clip(np.sqrt(np.abs(Ver)),0,5)) if key_pressed[K_a] or key_pressed[K_LEFT] or Hor<-1*thresholdValue: player.moveLeft(np.clip(np.sqrt(np.abs(Hor)),0,5)) if key_pressed[K_d] or key_pressed[K_RIGHT] or Hor>thresholdValue: player.moveRight(np.clip(np.sqrt(np.abs(Hor)),0,5)) cv2.imshow('frame', frame) # Draw background screen.fill(0) screen.blit(background, (0, 0)) # Control the maximum frame rate of the game to 60 clock.tick(60) # To generate bullets, you need to control the firing frequency # First, judge whether the player's plane is not hit if not player.is_hit: if shoot_frequency % 15 == 0: player.shoot(bullet_img) shoot_frequency += 1 if shoot_frequency >= 15: shoot_frequency = 0 for bullet in player.bullets: # Move the bullet at a fixed speed bullet.move() # Delete bullet after moving out of screen if bullet.rect.bottom < 0: player.bullets.remove(bullet) # Show bullets player.bullets.draw(screen) # To generate enemy aircraft, you need to control the generation frequency if enemy_frequency % 50 == 0: enemy1_pos = [random.randint(0, SCREEN_WIDTH - enemy1_rect.width), 0] enemy1 = Enemy(enemy1_img, enemy1_down_imgs, enemy1_pos) enemies1.add(enemy1) enemy_frequency += 1 if enemy_frequency >= 100: enemy_frequency = 0 for enemy in enemies1: # Mobile enemy aircraft enemy.move() # Processing of collision effect between enemy aircraft and player aircraft if pygame.sprite.collide_circle(enemy, player): enemies_down.add(enemy) enemies1.remove(enemy) player.is_hit = True break # Delete the plane after moving out of the screen. The game is over if enemy.rect.top > SCREEN_HEIGHT-50:# Incorrect source code modification enemies1.remove(enemy) player.is_hit = True break # Effect processing of enemy aircraft hit by bullet # Add the hit enemy object to the destroy enemy Group to render the destroy animation enemies1_down = pygame.sprite.groupcollide(enemies1, player.bullets, 1, 1) for enemy_down in enemies1_down: enemies_down.add(enemy_down) # Draw player plane if not player.is_hit: screen.blit(player.image[player.img_index], player.rect) # Change the picture index to animate the aircraft player.img_index = shoot_frequency // 8 else: # Effect processing after the player's plane is hit player.img_index = player_down_index // 8 screen.blit(player.image[player.img_index], player.rect) player_down_index += 1 if player_down_index > 47: # After the hit effect processing is completed, the game ends running = False # Effect display of enemy aircraft hit by bullet for enemy_down in enemies_down: if enemy_down.down_index == 0: pass if enemy_down.down_index > 7: enemies_down.remove(enemy_down) score += 100 continue screen.blit(enemy_down.down_imgs[enemy_down.down_index // 2], enemy_down.rect) enemy_down.down_index += 1 # Display enemy aircraft enemies1.draw(screen) # Draw current score score_font = pygame.font.Font(None, 36) score_text = score_font.render(str(score), True, (255, 255, 255)) text_rect = score_text.get_rect() text_rect.topleft = [10, 10] screen.blit(score_text, text_rect) # Update screen pygame.display.update() # Process game exit for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() # Draw the end of the game background screen.blit(game_over, (0, 0)) # Show final score after Game Over font = pygame.font.Font(None, 48) text = font.render('Score: ' + str(score), True, (255, 0, 0)) text_rect = text.get_rect() text_rect.centerx = screen.get_rect().centerx text_rect.centery = screen.get_rect().centery + 24 screen.blit(text, text_rect) # Use system fonts xtfont = pygame.font.SysFont('SimHei', 30) # Restart button textstart = xtfont.render('restart ', True, (255, 0, 0)) text_rect = textstart.get_rect() text_rect.centerx = screen.get_rect().centerx text_rect.centery = screen.get_rect().centery + 120 screen.blit(textstart, text_rect) # Leaderboard button textstart = xtfont.render('Ranking List ', True, (255, 0, 0)) text_rect = textstart.get_rect() text_rect.centerx = screen.get_rect().centerx text_rect.centery = screen.get_rect().centery + 180 screen.blit(textstart, text_rect) # Judgment score update Leaderboard # Temporary variables are used when you get to the leaderboard j = 0 #Get the content in the file and convert it into a list. Use mr to split the content arrayscore = read_txt(r'score.txt')[0].split('mr') # The circular score list is sorted in the list for i in range(0, len(arrayscore)): # Judge whether the current score is greater than the score on the leaderboard if score > int(arrayscore[i]): # Replace the score with the current score if it is greater than the content on the leaderboard j = arrayscore[i] arrayscore[i] = str(score) score = 0 # The replaced score is moved by one digit if int(j) > int(arrayscore[i]): k = arrayscore[i] arrayscore[i] = str(j) j = k # Write circular score list to document for i in range(0, len(arrayscore)): # Judge the first score in the list if i == 0: # Overwrite the written content and append mr to facilitate content segmentation write_txt(arrayscore[i] + 'mr', 'w', r'score.txt') else: # Judge whether it is the last score if (i == 9): # The last score of recently added content does not add mr write_txt(arrayscore[i], 'a', r'score.txt') else: # Not the last score, add mr when adding write_txt(arrayscore[i] + 'mr', 'a', r'score.txt') # Ranking List def gameRanking(): screen2 = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) # Draw background screen2.fill(0) screen2.blit(background, (0, 0)) # Use system fonts xtfont = pygame.font.SysFont('SimHei', 30) # Restart button textstart = xtfont.render('Ranking List ', True, (255, 0, 0)) text_rect = textstart.get_rect() text_rect.centerx = screen.get_rect().centerx text_rect.centery = 50 screen.blit(textstart, text_rect) # Use system fonts xtfont = pygame.font.SysFont('SimHei', 30) # Restart button textstart = xtfont.render('restart ', True, (255, 0, 0)) text_rect = textstart.get_rect() text_rect.centerx = screen.get_rect().centerx text_rect.centery = screen.get_rect().centery + 120 screen2.blit(textstart, text_rect) # Get ranking document content arrayscore = read_txt(r'score.txt')[0].split('mr') # Cyclic leaderboard file display ranking for i in range(0, len(arrayscore)): # Show final score after Game Over font = pygame.font.Font(None, 48) # Rank 1 to 10 k=i+1 text = font.render(str(k) +" " +arrayscore[i], True, (255, 0, 0)) text_rect = text.get_rect() text_rect.centerx = screen2.get_rect().centerx text_rect.centery = 80 + 30*k # Draw score content screen2.blit(text, text_rect) # Start the game startGame() # Determine the click position and handle the game launch while True: for event in pygame.event.get(): # Close page game exit if event.type == pygame.QUIT: pygame.quit() exit() # Mouse click elif event.type == pygame.MOUSEBUTTONDOWN: # Judge whether the position of the mouse click is within the position range of the start button if screen.get_rect().centerx - 70 <= event.pos[0] \ and event.pos[0] <= screen.get_rect().centerx + 50 \ and screen.get_rect().centery + 100 <= event.pos[1] \ and screen.get_rect().centery + 140 >= event.pos[1]: # Restart the game startGame() # Determine whether the mouse clicks the leaderboard button if screen.get_rect().centerx - 70 <= event.pos[0] \ and event.pos[0] <= screen.get_rect().centerx + 50 \ and screen.get_rect().centery + 160 <= event.pos[1] \ and screen.get_rect().centery + 200 >= event.pos[1]: # Show Leaderboard gameRanking() # Update interface pygame.display.update() startGame() # Determine whether the mouse clicks the leaderboard button if screen.get_rect().centerx - 70 <= event.pos[0] \ and event.pos[0] <= screen.get_rect().centerx + 50 \ and screen.get_rect().centery + 160 <= event.pos[1] \ and screen.get_rect().centery + 200 >= event.pos[1]: # Show Leaderboard gameRanking() # Update interface pygame.display.update()
pygame 2.1.2 (SDL 2.0.16, Python 3.7.4) Hello from the pygame community. https://www.pygame.org/contribute.html ALSA lib confmisc.c:768:(parse_card) cannot find card '0' ALSA lib conf.c:4292:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings ALSA lib conf.c:4292:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory ALSA lib confmisc.c:1251:(snd_func_refer) error evaluating name ALSA lib conf.c:4292:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:4771:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM default --------------------------------------------------------------------------- error Traceback (most recent call last) /tmp/ipykernel_101/2257083983.py in <module> 124 # Set the game interface size, background picture and title 125 # Game interface pixel size --> 126 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) 127 # Game interface title 128 pygame.display.set_caption('Aircraft war') error: No available video device
3 instructions for use
- Add work / aircraft War Game v1 Download zip to the local and run main Py (opencv library and pygame library are required)
- At present, in order to ensure real-time performance, Haar Cascade is used for face recognition (open CV built-in)
- The game tries to let players stand in the center of the camera range and face the camera while moving
- At present, the difficulty is low. You can increase the difficulty of the game by modifying the number of enemy planes / bullet speed
4 Summary and Prospect
Thanks for super loose AI gesture recognition project Give inspiration and SongGe's own Q & A.
The project is anxious to use, so there is no in-depth learning. If there are a large number of forks, key point detection will be added in the follow-up to increase the playability of the game, including bullet enhancement, enriching game levels, etc.
Although it seems relatively simple, most of the time of the project is spent on parameter adjustment and real-time optimization.
Finally, I hope the big guys can do more projects with simple code deployment and strong interest. Demonstrate the profound technical accumulation of the platform in the offline of the pilot group.