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