全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2023-10-13_使用图像分割技术,实现视频特效!

您的位置:首页 >> 新闻 >> 行业资讯

使用图像分割技术,实现视频特效! 点击关注公众号,回复”福利”即可参与文末抽奖 一、前言在许多视频对话软件中,都可以选择视频的背景。其原理就是将人像抠出来,把非人像部分替换。而大多数软件是切换图片背景,或者是动图背景。利用图像分割技术,可以实现更复杂的背景替换,最终结果就像电影特效。 许多特效拍摄会使用绿幕背景,而图像分割技术可以在不使用绿幕的情况下达到类似的效果,不过相较绿幕要差一些。 今天我们要做的就是使用开源的人像分割项目来完成视频背景替换的操作。我们会在原有项目的基础上继续开发。 二、项目介绍2.1 项目运行 今天我们要使用的是一个视频转绿幕的项目。项目地址:https://github.com/PeterL1n/RobustVideoMatting 首先需要下载项目: git clone https://github.com/PeterL1n/RobustVideoMatting.git 下载完成后,安装对应的依赖: cd RobustVideoMatting pip install -r requirements_inference.txt 然后下载对应的模型:https://github.com/PeterL1n/RobustVideoMatting#download 可以选择rvm_mobilenetv3.pth、rvm_resnet50.pth其中一个,放在项目目录下。 然后在项目下创建一个Python文件,写入下面的代码: importtorch frommodelimportMattingNetwork frominferenceimportconvert_video #选择mobilenetv3或resnet50,对应前面下载的两个模型 model=MattingNetwork('mobilenetv3').eval().cuda()#or"resnet50" model.load_state_dict(torch.load('rvm_mobilenetv3.pth')) convert_video( model,#模型 input_source='input.mp4',#视频或者图片目录 output_type='video',#选"video"或"png_sequence" output_composition='com.mp4',#输出路径 output_alpha="pha.mp4"#预测的alpha通道 output_video_mbps=4, downsample_ratio=None, seq_chunk=12, ) 运行上面代码就可以完成视频抠人像的操作,输出的com.mp4是一个绿幕视频,pha.mp4是一个黑白视频(人像为白,背景为黑)。下面是一些例子: 2.2 定义图片抠图和视频抠图函数 在项目中,没有提供自己抠图的代码,所以我们自己编写对应的代码。项目中model.MattingNetwork就是一个人像分割网络,我们调用它的前向传播方法,输入图片,它就会返回抠取的alpha通道,代码如下: importcv2 importtorch fromPILimportImage fromtorchvision.transformsimporttransforms frommodelimportMattingNetwork device="cuda"iftorch.cuda.is_available()else"cpu" #加载模型 segmentor=MattingNetwork('resnet50').eval().cuda() segmentor.load_state_dict(torch.load('rvm_resnet50.pth')) defhuman_segment(model,image): src=(transforms.PILToTensor()(image)/255.)[None] src=src.to(device) #抠图 withtorch.no_grad(): fgr,pha,*rec=model(src) segmented=torch.cat([src.cpu(),pha.cpu()],dim=1).squeeze(0).permute(1,2,0).numpy() segmented=cv2.normalize(segmented,None,0,255,cv2.NORM_MINMAX,cv2.CV_8U) returnImage.fromarray(segmented) human_segment(segmentor,Image.open('xscn.jpg')).show() 现在只需要调用human_segment函数就能实现抠图操作了。而抠视频的操作也非常简单,在项目下提供了下面的代码: fromtorch.utils.dataimportDataLoader fromtorchvision.transformsimportToTensor frominference_utilsimportVideoReader,VideoWriter reader=VideoReader('input.mp4',transform=ToTensor()) writer=VideoWriter('output.mp4',frame_rate=30) bgr=torch.tensor([.47,1,.6]).view(3,1,1).cuda()#Greenbackground. rec=[None]*4#Initialrecurrentstates. downsample_ratio=0.25#Adjustbasedonyourvideo. withtorch.no_grad(): forsrcinDataLoader(reader):#RGBtensornormalizedto0~1. fgr,pha,*rec=model(src.cuda(),*rec,downsample_ratio)#Cycletherecurrentstates. com=fgr*pha+bgr*(1-pha)#Compositetogreenbackground. writer.write(com)#Writeframe. 我们也可以自己编写代码用于视频转换,这里的操作就是逐帧读取,然后调用human_segment函数。这里写一个示例代码: capture=cv2.VideoCapture("input.mp4") whileTrue: ret,frame=capture.read() ifnotret: break image=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB) result=human_segment(segmentor,Image.fromarray(image)) result=cv2.cvtColor(np.array(result),cv2.COLOR_RGB2BGR) cv2.imshow("result",result) cv2.waitKey(10) cv2.destroyAllWindows() 不过上述代码显示时无法显示透明效果。 三、视频背景切换视频背景切换的思路可以分为下面几个步骤: 读取人像视频帧和背景视频帧对每一帧进行抠图把抠出来的人像与背景混合把混合结果写入视频下面我们一步步来实现。其中1、2步我们已经实现了,下面要做的就是3、4两个步骤。 3.1 png图片切换背景 第三步可以看做是给png图片换背景的操作,可以把这一步实现为一个函数,代码如下: fromPILimportImage defchange_background(image,background): w,h=image.size background=background.resize((w,h)) background.paste(image,(0,0),image) returnbackground 其中image和background都是Pillow图片。 3.2 写入视频 最后就是写入视频的操作了,这个可以用OpenCV实现,代码如下: #读取人像视频和背景视频 capture=cv2.VideoCapture("input.mp4") capture_background=cv2.VideoCapture('background.mp4') #获取画面大小 fps=capture.get(cv2.CAP_PROP_FPS) width=int(capture.get(cv2.CAP_PROP_FRAME_WIDTH)) height=int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT)) size=(width,height) #写入视频 fourcc=cv2.VideoWriter_fourcc(*'mp4v') out=cv2.VideoWriter('output.mp4',fourcc,fps,size) frames=min(capture.get(cv2.CAP_PROP_FRAME_COUNT),capture_background.get(cv2.CAP_PROP_FRAME_COUNT)) bar=tqdm(total=frames) whileTrue: ret1,frame1=capture.read() ret2,frame2=capture_background.read() #如果有一个视频结束了,则结束 ifnotret1ornotret2: break image=cv2.cvtColor(frame1,cv2.COLOR_BGR2RGB) segmented=human_segment(segmentor,Image.fromarray(image)) background=Image.fromarray(cv2.cvtColor(frame2,cv2.COLOR_BGR2RGB)) changed=change_background(segmented,background) changed=cv2.cvtColor(np.array(changed),cv2.COLOR_RGB2BGR) out.write(changed) bar.update(1) out.release() 上面的代码就是完成了本章开始提到的四个步骤,最后会输出一个视频。 在代码中,读取了人像和背景视频,而且不要求两个视频长度一样。程序会自动选取较短的视频作为输出视频的时长。 在代码中有一部分BGR转RBG、cv转Pillow的操作,这部分代码还能做一些改进。 点击小卡片,参与粉丝专属福利!!如果文章对你有帮助的话欢迎「关注+点赞+收藏」 阅读原文

上一篇:2022-11-23_校园福利 | 你一个学期的会员我全包了! 下一篇:2024-05-21_大疆车载负责人:沈劭劼 团队荣获2023年IEEE-TRO顶刊最佳论文奖

TAG标签:

15
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价