importcv2fromPILimportImageimportnumpyasnpimportosimportpaddlehubashubfrommoviepy.editorimport*
#从视频提取图片defvideo2img(video_path,out_path):cap=cv2.VideoCapture(video_path)i=1whileTrue:ret,frame=cap.read()ifframeisNone:breakelse:cv2.imwrite(out_path+str(i)+".jpg",frame)i+=1return
#抠图defimg2seg(img_path,out_path):#loadmodelmodule=hub.Module(name="deeplabv3p_xception65_humanseg")#configtest_img_path=[os.path.join(img_path,f_name)forf_nameinos.listdir(img_path)]input_dict={"image":test_img_path}
results=module.segmentation(data=input_dict,output_dir=out_path)
#合成图片defblend_images(fore_image,base_image,out_path,img_num):#defblend_images(fore_image,base_image):"""将抠出的人物图像换背景fore_image:前景图片,抠出的人物图片base_image:背景图片"""#读入图片base_image=Image.open(base_image).convert('RGB')fore_image=Image.open(fore_image).resize(base_image.size)
#图片加权合成scope_map=np.array(fore_image)[:,:,-1]/255scope_map=scope_map[:,:,np.newaxis]scope_map=np.repeat(scope_map,repeats=3,axis=2)res_image=np.multiply(scope_map,np.array(fore_image)[:,:,:3])+np.multiply((1-scope_map),np.array(base_image))
#保存图片res_image=Image.fromarray(np.uint8(res_image))f_name=str(img_num)+".jpg"res_image.save(os.path.join(out_path,f_name))
#把图片合成视频defimg2video(img_path,org_video_path,out_path):#查看原始视频的参数cap=cv2.VideoCapture(org_video_path)ret,frame=cap.read()height=frame.shape[0]width=frame.shape[1]fps=cap.get(cv2.CAP_PROP_FPS)#返回视频的fps--帧率
#把参数用到我们要创建的视频上video=cv2.VideoWriter(out_path,cv2.VideoWriter_fourcc('m','p','4','v'),fps,(width,height))#创建视频流对象"""参数1即将保存的文件路径参数2VideoWriter_fourcc为视频编解码器cv2.VideoWriter_fourcc('m','p','4','v')文件名后缀为.mp4参数3为帧播放速率参数4(width,height)为视频帧大小"""
#获取图片总数file_list=os.listdir(img_path)img_num=len(file_list)
foriinrange(img_num):f_name=str(i+1)+'.jpg'item=os.path.join(img_path,f_name)img=cv2.imread(item)#使用opencv读取图像,直接返回numpy.ndarray对象,通道顺序为BGR,注意是BGR,通道值默认范围0-255。video.write(img)#把图片写进视频video.release()#释放
#从原始视频上提取声音合成到新生成的视频上defsound2video(org_video_path,new_video_path,out_video_path):#读取原始视频video_o=VideoFileClip(org_video_path)#获取原始视频的音频部分audio_o=video_o.audio
#读取新生成视频video_clip=VideoFileClip(new_video_path)#指向新生成视频的音频部分video_clip2=video_clip.set_audio(audio_o)#修改音频部分并输出最终视频video_clip2.write_videofile(out_video_path)
#Config#人物视频地址human_video_path='./a.mp4'#背景视频地址back_video_path='./b.mp4'#提取人物视频图像的存放地址human_video_img_path='./human_video_img/'#提取背景视频图片的存放地址back_video_img_path='./back_video_img/'#抠图后存放地址human_img_seg_path='./human_img_seg/'#人物和背景合成后图片存放地址blend_img_path='./blend_img/'#合成视频存放地址img2video_path='./c.mp4'#添加声音后的视频最终输出地址out_video_path='./d.mp4'
if__name__=="__main__":
#第一步:人物视频->人物图像ifnotos.path.exists(human_video_img_path):os.mkdir(human_video_img_path)video2img(video_path=human_video_path,out_path=human_video_img_path)
#第二步:抠图ifnotos.path.exists(human_img_seg_path):os.mkdir(human_img_seg_path)img2seg(img_path=human_video_img_path,out_path=human_img_seg_path)
#第三步:背景视频->背景图片ifnotos.path.exists(back_video_img_path):os.mkdir(back_video_img_path)video2img(video_path=back_video_path,out_path=back_video_img_path)
#第四步:抠图+背景图片->合成ifnotos.path.exists(blend_img_path):os.mkdir(blend_img_path)#由于人物视频长度和背景视频长度可能不同,所以要以短的为准iflen(os.listdir(human_img_seg_path)) #第五步:合成视频ifnotos.path.exists(img2video_path):img2video(img_path=blend_img_path,org_video_path=human_video_path,out_path=img2video_path)else:print('视频已存在,请查看输出路径')