"Pilot group" face recognition aircraft war

Posted by NewBob on Thu, 13 Jan 2022 13:08:14 +0100

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.

Topics: Python Computer Vision pygame paddlepaddle