大家好。前几天大家都看过下面的视频了吗?博主本来想证明自己的背景是真实的,结果被网友恶搞,换成各种背景“打假”。今天就来凑热闹,用AI技术自动更换背景。这个想法并不难。我们先将原视频中的人物分离出来,然后将分离出来的人物“粘贴”到新的背景视频中。用于从视频中对人物进行分类的关键技术是计算机视觉中的实例分割。我在之前的文章中介绍过目标检测技术。比如人脸检测目标检测就是通过一个矩形框来标记检测到的目标,比较容易。实例分割是一个比较精细的工作,因为需要对每个像素点进行分类,准确勾勒出物体的轮廓。今天我们使用detectron2进行实例分割,它是FacebookAI研究院的一个开源项目。它功能强大,使用方便。1、安装detectron2支持在Linux和macOS系统上安装。linux可以直接通过pip安装,而mac只能通过源码编译安装。建议您使用Linux。支持GPU和CPU运算,我用的是3090显卡,CUDA11.1,Pytorch1.8。2.运行我们使用官方预训练模型对图像进行分割。2.1加载模型配置文件fromdetectron2.configimportget_cfgfromdetectron2importmodel_zoocfg=get_cfg()model_cfg_file=model_zoo.get_config_file('COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml')cfg.merge_from_file(model)_comment_file('COCO-InstanceSegmentation/mask_rcnn_R35.yaml')cfg.merge_from_file(model)_comment_cfg训练好的实例分割模型。mask_rcnn_R_50_FPN_3x.yaml是用于模型训练的配置信息。从下图也可以看出,detectron2除了实例分割模型外,还提供了目标检测、关键点检测等模型,比较全面。2.2加载模型model_weight_url=model_zoo.get_checkpoint_url('COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml')cfg.MODEL.WEIGHTS=model_weight_urlmask_rcnn_R_50_FPN_3x.yaml文件存储预训练模型的url。在进行实例分割时,程序会自动将模型从url下载到本地。存放位置为:但程序自动下载方式可能比较慢。这时候可以使用迅雷自己下载模型文件,放到对应的路径下。2.3实例分割首先读取一张480*640大小的图片。img=cv2.imread('./000000439715.jpg')实例化DefaultPredictor对象。fromdetectron2.engineimportDefaultPredictorpredictor=DefaultPredictor(cfg)将图像分割成instancesout=predictor(img)out变量存储每个分割目标的类别id、检测框和目标mask。out["instances"].pred_classes获取目标的类别id。这里检测到15个目标。在配置文件中可以找到类别id和类别名称的映射关系。其中0代表人,17代表马。out["instances"].pred_masks得到目标的掩码,我们拿单个目标的掩码来研究一下它的用处。可以看到,它的值是Boolean,它的形状和图片的大小一样。因此mask是实例分割的结果,其中每个元素对应图像的一个像素,值为True表示该像素为检测到的目标像素。因此,我们可以通过遮罩给目标加上一层不透明,从而准确标记出目标。img_copy=img.copy()alpha=0.8color=np.array([0,255,0])img_copy[mask>0,:]=img_copy[mask>0,:]*alpha+颜色*(1-alpha)给上面的目标添加一层绿色的不透明度,效果如下:可以看到马上的人已经被标记出来了。3.自动合成背景有了上面的基础,我们就可以轻松合成视频了。读取原视频的每一帧进行人物分割,将分割后的人物直接叠加到新背景视频中对应的帧上。核心代码:#读取原视频ret,frame_src=cap.read()#读取新背景视频ret,frame_bg=cap_bg.read()#调整背景大小与原视频相同frame_bg=cv2.resize(frame_bg,sz)#分割原始视频人物person_mask=instance_seg.predict(frame_src)#合成frame_bg[person_mask,:]=frame_src[person_mask,:]
