Gizeh+Moviepy透明背景渲染伪影问题技术求助
问题描述
使用Gizeh绘制带圆盘的Surface帧,通过Moviepy合成视频时,将Surface的bg_color从(0.2,0.5,0.2,1.0)改为(0.2,0.5,0.2,0.0)设置透明背景后,移动的圆盘在运动方向前方出现异常伪影,圆盘重叠时还会出现颜色渗色问题,尝试多种Alpha值后问题仍存在。
核心绘制函数代码
def make_frame(t): surface = gizeh.Surface(1080,1080,bg_color=(0.2,0.5,0.2,1.0)) #draw border border_width= 40.00 Border=gizeh.rectangle(1080, 1080, xy=((1080//2,1080//2)), stroke = (1.0,1.0,1.0), stroke_width = border_width) Border.draw(surface) for disc in discs: Ball_w=gizeh.circle(r=(disc.size), xy=[disc.position[0] ,disc.position[1]], fill= (disc.color)) Ball_w.draw(surface) disc.collide_with_wall(table_width, table_height, border_width) #disc.collide_with_disc(discs) disc.move() return surface.get_npimage(transparent=True)
背景修改点
bg_color=(0.2,0.5,0.2,1.0) # 修改前 bg_color=(0.2,0.5,0.2,0.0) # 修改后
Disc类实现代码
class Disc: def __init__(self, size, density, position, velocity, color): self.size = size self.density = density self.mass = size*size*density self.position = position self.velocity = velocity self.color = color def move(self): # Update the position of the disc based on its velocity self.position[0] = (self.position[0] + self.velocity[0]) self.position[1] = (self.position[1] + self.velocity[1]) def update_position(self, new_position): self.position = new_position def update_velocity(self, new_velocity): self.velocity = new_velocity def collide_with_wall(self, width, height, border_width): # Check for collisions with the walls of the pool table if self.position[0] <=0+self.size+border_width/2: self.velocity[0] =abs(self.velocity[0]) # Reverse the x-direction velocity if self.position[0] >= width-self.size-border_width/2: self.velocity[0] =-abs(self.velocity[0]) # Reverse the x-direction velocity if self.position[1] <=0+self.size+border_width/2: self.velocity[1] =abs(self.velocity[1]) # Reverse the y-direction velocity if self.position[1] >= height-self.size-border_width/2: self.velocity[1] =-abs(self.velocity[1]) # Reverse the y-direction velocity
帧合成代码
for frame_no in range (0, int(num_frames)): clip=get_array_clip(discs,frame_no) palette_clip.append(clip) final_vid=concatenate_videoclips(palette_clip, method="chain" ) final_vid.set_start(palette_start_time) clip=[] clip.append(final_vid.set_start(palette_start_time).set_position((0,420))) return clip
解决建议
强制每帧全透明初始化:替换原半透明背景为纯透明,避免Gizeh混合逻辑导致的帧残留。创建Surface后手动填充全透明画布:
surface = gizeh.Surface(1080,1080,bg_color=(0,0,0,0)) # 确保画布完全清空 gizeh.rectangle(1080,1080, xy=(540,540), fill=(0,0,0,0)).draw(surface)调整抗锯齿设置:伪影和渗色多来自透明背景下的抗锯齿边缘混合。绘制元素时显式关闭抗锯齿:
Border=gizeh.rectangle(1080, 1080, xy=(540,540), stroke=(1.0,1.0,1.0), stroke_width=border_width, anti_alias=False) Ball_w=gizeh.circle(r=disc.size, xy=[disc.position[0],disc.position[1]], fill=disc.color, anti_alias=False)若需要抗锯齿,可使用高分辨率渲染后缩小:
surface = gizeh.Surface(1080,1080,bg_color=(0,0,0,0), pxratio=2) # 绘制完成后缩至原尺寸 frame = surface.get_npimage(transparent=True)[::2,::2] return frame修改Moviepy合成模式:用
compose替代chain,确保每帧完全覆盖,避免帧间残留:final_vid=concatenate_videoclips(palette_clip, method="compose")同时确认每个clip的帧数组为RGBA 4通道格式,创建clip时明确
is_mask=False。隔离帧间状态:原代码直接修改全局
discs对象会导致帧间状态污染,每帧生成时使用对象副本:from copy import deepcopy def make_frame(t): frame_discs = deepcopy(discs) surface = gizeh.Surface(1080,1080,bg_color=(0,0,0,0)) # 后续绘制逻辑使用frame_discs副本
内容的提问来源于stack exchange,提问作者Quote
相关产品推荐
相关产品推荐

