Inherit the will of fire and play with fire in combination with key point detection~_ copy

Link from AI Studio project https://aistudio.baidu.com/aistudio/projectdetail/3537977

Big brother didn't lose! Will to inherit fire~

Elder brother, how can you lose? It's clearly that yiwozuo is playing tricks. Yiwozuo is not allowed to go!

I'm huntingOn the way, I'm still a few fork s away. I can catch up with him and avenge my eldest brother. I haven't heard of any quarterly awards for projects. Really~

This project is simple. First, it describes how to draw the fire of pixel wind, and then combined with key point detection, put a fire in the place we specify. Cough~

Particle Effect

Particle effects are widely used in games, especially in general elements (Feng Shui, fire, etc.) and skill effects (knife light, sword shadow, magic and arcane)~
So in this project, we also use particle effects to draw fire. The simplest is to use pyGame to draw such images. (in fact, we only use opencv, but pyGame is easier to implement.)
When it comes to particle effects, the three common concepts are particle birth, particle motion and particle death. More commonly, we usually use multiple particles together to show a certain effect, and the expressiveness of a single particle is still insufficient.
Generally, we will have an emitter, and all particles are generated by the emitter.
After generation, we draw the motion of particles in each frame. Generally speaking, when the particle moves to a certain time or place, it ends its mission and ushers in the death of particles.

Let's first look at the writing of particle classes

Here we define the position of x and y particles, how many seconds life particles can survive, the radius of r particles, and the angle of motion of several examples

class Particle:
    def __init__(self, x, y):
        self.x, self.y = x, y
        particleSize = 10#2.9
        self.maxlife = randint(13 + int(particleSize*5), 27 + int(particleSize*10))
        self.life = self.maxlife
        self.dir = choice((-2, -1, 1, 2))
        self.sin = randint(-10, 10)/7
        self.sinr = randint(5, 10)
        self.r = randint(4,8)

        self.ox = randint(-1, 1)
        self.oy = randint(-1, 1)

We manage the generation, movement and death of particles by the emitter. Let's look at the generation of particles first

We will maintain a list of emitter classes self Particles to manage all particles, the birth of particles is constantly like self append new particle instance in particles

def add_particles(self, x, y):
    if self.init:
        dist = sqrt((x-self.lx)**2+(y-self.ly)**2)
        a = atan2(y-self.ly, x-self.lx)
        for d in range(0, int(dist), 10):
            _x = x+cos(a)*d
            _y = y+sin(a)*d
            for _ in range(round(self.density)):
                self.particles.append(Particle(_x//self.res, _y//self.res))
        else:
            for _ in range(round(self.density)):
                self.particles.append(Particle(x//self.res, y//self.res))
        self.lx = x
        self.ly = y
    else:
        self.lx = x
        self.ly = y
        self.init = True

Motion of particles

The motion and of particles is to calculate the position, color and size of particles in a new frame
In our project, the position of the particle will float bit by bit relative to its birth point (fire burns up)
In terms of color, this project defines a palette with six preset colors, corresponding to the degree of flame combustion. The closer the particles are to the fire source, the more yellow they are, then red, and finally black
The larger the size of the particle, the farther away it will be from the fire source
We also judge whether the particle should die here. If the particle is dead, we put it into the maintenance self Dead list, delete all dead particles before the next calculation of motion

def emit(self, j):
    if self.particles:
        self.delete_particles()
        for p in self.particles:
            p.life -= 1
            if p.life == 0:
                self.dead.append(p)
                continue

            i = int((p.life/p.maxlife)*6)
            p.y -= self.rise
            p.x += ((p.sin * sin( j / (p.sinr)))/2)*self.spread + self.wind

            if not randint(0, 5):
                p.r += 0.88

            x, y = p.x, p.y

            x += p.ox * (5 - i)
            y += p.oy * (5 - i)

            alpha = 255
            if p.life < p.maxlife/4:
                alpha = int((p.life/p.maxlife) * 255)
            
            pygame.draw.circle(self.bsurf, palette[i] + (alpha,), (x, y), p.r, 0)

            if i == 0:
                pygame.draw.circle(self.bsurf, (0, 0, 0, 0), (x+randint(-1, 1), y-4), p.r*(((p.maxlife-p.life)/p.maxlife)/0.88), 0)
            else:
                pygame.draw.circle(self.bsurf, palette[i-1] + (alpha,), (x+randint(-1, 1), y-3), p.r/1.5, 0)

Particle death

There's nothing to say. Ha ha, just throw away the particles in the dead list

def delete_particles(self):
        for p in self.dead:
            self.particles.remove(p)
        self.dead.clear()

Combined with the key point detection model in paddedetection

Here, the key point detection is encapsulated into a thread. Here, hrnet in paddedetection is used
In fact, it is easy to replace it with other models here. For example, I also provided a file that uses the key point model of the hand. The directly used PaddleHub model is very simple to use!

class MyThread(Thread):
    def __init__(self, video_file = "mykeypointdetector/mine.mp4", debug=True):
        global shape
        super(MyThread, self).__init__()  
        self.md = MyDetector("mykeypointdetector/output_inference/hrnet_w32_384x288/", True)
        self.video_file = video_file
        self.debug = debug
        self.capture = cv2.VideoCapture(self.video_file)
        self.h = self.capture.get(4)
        self.w = self.capture.get(3)
        shape = [self.h, self.w]

    def run(self):
        global results
        global lock
        global rframe
        while (1):
            ret, frame = self.capture.read()
            if not ret:
                break
            frame = cv2.flip(frame, 1)
            tresults = self.md.detector.predict(frame)
            if tresults['keypoint'][0][0][10][2] > 0.5 and tresults['keypoint'][0][0][8][2] > 0.5:
                lock.acquire()
                results = tresults
                rframe = frame.copy()
                lock.release()
            else:
                lock.acquire()
                results = tresults
                rframe = frame.copy()
                lock.release()
            '''watch image'''
            if self.debug:
                if tresults is not None:
                    for key in tresults['keypoint'][0][0]:
                        cv2.circle(frame,(int(key[0]), int(key[1])), 5, (0,0,255), -1)
                cv2.imshow("Debug", frame)
cle(frame,(int(key[0]), int(key[1])), 5, (0,0,255), -1)
                cv2.imshow("Debug", frame)
                cv2.waitKey(1)

Since aistudio cannot interact directly, download it locally to play~

Run Python interaction directly locally Py is OK

Then try to press up, down, left and right buttons to see what effect it has~

Summary:

This project mainly introduces the example special effects commonly used in the game and how to use python to realize simple flame special effects.
In fact, the later part combined with key points can be replaced with other key point detection models. The reason why I use this one in the project is completely because it is easy. Cough.
In fact, there is a professional key point detection model of face in PaddleHub, which should be more convenient to use. Moreover, the model runs very fast and does not need to be written in a multi-threaded way as in my project.
Of course, the place where we generate particles can be not only the eyes, but also any part of the body, and even the sword in our hands! But how to make the sword catch fire may require other methods, such as PaddleSeg? You can try~
After that, we will also bring you other particle special effects projects. Let's play together~
If you like this project, please give me some love and fork. See you next time

Project flame particle effect reference: pygame-vfx

Personal profile

Baidu PaddlePaddle developer technical expert PPDE

Head of Shanghai pilot group

Members of Baidu PaddlePaddle's official help group and answering team

18th master of National Tsinghua University

I was not sensible before, now I just want to make money ~ welcome to do it together, hahaha

I got the supreme level in AI Studio and lit 10 badges to interact with each other!!!

https://aistudio.baidu.com/aistudio/personalcenter/thirdview/311006

Station B ID: Nine Tailed demon bear

Other interesting items:

Padoodle: use human key point detection to make graffiti villains move

Transform angry birds using key point detection and classification model

Making "King land" filter with PaddleHub

Making Dragon Boat Festival somatosensory games with Paddlehub

Panda head expression generator [Wechaty+Paddlehub]

How to become a super Saiya (I) – handsome hairstyle

[AI Creation Camp] if you are a geek, do you insist on 100 seconds?

In Aistudio, everyone can be the master of shadow flow [PaddleSeg]

What are you doing? Come and row with DQN

Use PaddleSeg to steal the day ~

Keywords: Deep Learning NLP paddlepaddle BERT

Added by vestax1984 on Sun, 06 Mar 2022 04:18:23 +0200