0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Mask R-CNN:自动从视频中制作目标物体的GIF动图

zhKF_jqr_AI 2018-02-03 14:19 次阅读

在上一篇文章中,我们介绍了用深度学习结合摄像机的方法自动检测并拍摄小鸟的照片。今天,我们用另一种新颖的深度学习模型——Mask R-CNN,自动从视频中制作目标物体的GIF动图。

Mask R-CNN已经有很多应用了,论智君此前还介绍过Facebook利用这一模型实现全身AR的项目。不过在这个项目中,作者Kirk Kaiser使用的是MatterPort版本。它支持Python 3,拥有超棒的样本代码,也许是最容易安装的版本了。

第一步,输入正确的内容

在开始制作gif自动生成器时,我选择先做一件最蠢的事,这种模式在有创意性编码项目中表现得很好。

首先,输入的视频中只能含有一个人,不要尝试跟踪监测视频中的多个人。这样我们就可以将目标物体与其他对象隔离开,同时更容易评估模型掩盖目标对象的程度如何。如果目标对象不见了,我们就能发现,同时还能看到模型识别边框的噪声。

我选用的是自己在后院拍摄的视频。

用Python处理视频

尽管用Python处理视频有其他方法,但我更喜欢将视频转换为图像序列,然后再使用ffmpeg将其转换回来。

使用以下命令,我们就能从输入的视频中获取一系列图像。根据输入的视频来源,它可能在每秒24到60帧之间。你需要跟踪每秒输入的视频帧数,以便在转换后保持同步。

$ ffmpeg -i FILENAME.mp4 -qscale:v 2 %05d.jpg

这将创建一个5位、0填充的图像序列,如果您输入的视频长度超过5位,则可以将%05d改成%09d。

数字序列将与视频持续的时间一样长(以秒为单位),乘以每秒的帧数。所以一个时长为三秒、每秒24帧的视频,将有72帧。

由此,我们得到了一系列静止的图像,可以使用我们的静态掩码R-CNN代码输入。

完成了对图像的处理后,稍后将使用以下命令把它们重新放回视频中:

$ ffmpeg -r 60 -f image2 -i %05d.jpg OUTPUT.mp4

参数-r规定了每秒中我们需要使用构建输出视频的帧数。如果我们想放慢视频,可以降低参数的值,如果想加快速度,可以增加参数的值。

按照顺序,让我们先用Mask R-CNN来检测并处理图像。

检测并标记图像

Matterport版的Mask R-CNN附带了Jupyter Notebook,帮助深入了解Mask R-CNN的工作原理

一旦你在本地设置好了repo,我建议在demo笔记本上运行,并评估图像检测工作的水平。

通常掩码是无符号的8位整数,形状与输入的图像一致。当没有检测到目标对象时,掩码是0或者黑色。当检测到对象时,掩码是255或白色。

为了处理蒙版,我们需要把它作为一个通道,复制或粘贴另一张图像。用类似下面的代码,可以从每个视频的图像中将单个人物抠出来,生成一张透明底的图像:

import numpy as np

import os

import coco

import model as modellib

import glob

import imageio

import cv2

# Root directory to project

ROOT_DIR = os.getcwd()

# Directory to save logs and trained model

MODEL_DIR = os.path.join(ROOT_DIR, "logs")

# Path to trained weights file

# Download this file and place in the root of your

# project (See README file for details)

COCO_MODEL_PATH = os.path.join(ROOT_DIR, "mask_rcnn_coco.h5")

classInferenceConfig(coco.CocoConfig):

# Set batch size to 1 since we'll be running inference on

# one image at a time. Batch size = GPU_COUNT * IMAGES_PER_GPU

GPU_COUNT = 1

IMAGES_PER_GPU = 1

config = InferenceConfig()

# Create model object in inference mode.

model = modellib.MaskRCNN(mode="inference", model_dir=MODEL_DIR, config=config)

# Load weights trained on MS-COCO

model.load_weights(COCO_MODEL_PATH, by_name=True)

class_names = ['BG', 'person', 'bicycle', 'car', 'motorcycle', 'airplane',

'bus', 'train', 'truck', 'boat', 'traffic light',

'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird',

'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear',

'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie',

'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',

'kite', 'baseball bat', 'baseball glove', 'skateboard',

'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup',

'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',

'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',

'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed',

'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote',

'keyboard', 'cell phone', 'microwave', 'oven', 'toaster',

'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors',

'teddy bear', 'hair drier', 'toothbrush']

numFiles = len(glob.glob('extractGif/*.jpg'))

counter = 0

for i in range(1, numFiles):

filename = 'extractGif/%05d.jpg' % i

print("doing frame %s" % filename)

frame = cv2.imread(filename)

results = model.detect([frame], verbose=0)

r = results[0]

masky = np.zeros((frame.shape[0], frame.shape[1]), dtype='uint8')

humans = []

if r['rois'].shape[0] >= 1:

for b in range(r['rois'].shape[0]):

if r['class_ids'][b] == class_names.index('person'):

masky += r['masks'][:,:,b] * 255

humansM = r['masks'][:,:,b] * 255

y1, x1, y2, x2 = r['rois'][b]

humansCut = frame[y1:y2, x1:x2]

humansCut = cv2.cvtColor(humansCut.astype(np.uint8), cv2.COLOR_BGR2RGBA)

humansCut[:,:,3] = humansM[y1:y2, x1:x2]

humans.append(humansCut)

if len(humans) >= 1:

counter += 1

for j, human in enumerate(humans):

fileout = 'giffer%i/%05d.png' % (j, counter)

ifnot os.path.exists('giffer%i' % j):

os.makedirs('giffer%i' % j)

print(fileout)

#frame = cv2.cvtColor(frame.astype('uint8'), cv2.COLOR_BGRA2BGR)

imageio.imwrite(fileout, human)

其中的class_names变量非常重要,它表示我们用COCO数据集分出的不同事物的类别。然后只需要把列表中的任意类别的名字更换成if r[class_ids][b] == class_names.index(‘person’),你就可以从视频中获取带有蒙版的版本了。

把图片转换成GIF

现在我们有了一组透明图像,可以打开看看它们的效果。我的结果并不是很好,人物抠的不是很精致,不过也挺有趣的。

然后我们就可以将图像输入进ffmpeg中制作动图了,只需要找到图像序列的最大宽度(width)和高度(height),然后将其粘贴到一个新的图像序列中:

import glob

from PIL importImage

maxW = 0

maxH = 0

DIRECTORY = 'wave-input'

numFiles = len(glob.glob(DIRECTORY + '/*.png'))

for num in range(numFiles - 1):

im = Image.open(DIRECTORY + '/%05d.png' % (num + 1))

if im.width > maxW:

maxW = im.width

if im.height > maxH:

maxH = im.height

for num in range(numFiles - 1):

each_image = Image.new("RGBA", (maxW, maxH))

im = Image.open(DIRECTORY + '/%05d.png' % (num + 1))

each_image.paste(im, (0,0))

each_image.save('gifready/%05d.png' % num)

上面的代码打开了我们的giffer0这个目录,并在所有图像中迭代,寻找最大尺寸图像的width和height。然后它将这些图像都放到一个新目录(gifready)中,我们就能将其生成gif。

在这里,我们利用Imagemagick生成gif:

$ convert -dispose Background *.png outty.gif

但是仅仅从视频中自动生成动图也没什么好激动的,让我们继续把它们混合起来,看看会发生什么……

在Pygame或视频中应用生成的GIFs

最近,我直接将这些提取的图像用在了Pygame中。我并没有将它们转换成gifs,而是保留了原始PNG格式。

我自创了一个创意性小编程环境,其中包括一个setup和draw功能,将图像序列作为输入。使用这个设置,我可以将图像旋转、缩放或干扰它们。以下是代码:

import pygame

import random

import time

import math

import os

import glob

imageseq = []

def setup(screen, etc):

global imageseq

numIn = len(glob.glob('wave-input/*.png'))

for i in range(numIn):

if os.path.exists('wave-input/%05d.png' % (i + 1)):

imagey = pygame.image.load('wave-input/%05d.png' % (i + 1)).convert_alpha()

imageseq.append(imagey)

counter = 1

def draw(screen, etc):

# our current animation loop frame

global counter

current0 = imageseq[counter % len(imageseq)]

counter += 1

for i in range(0, 1920, 200):

screen.blit(current0, (i, 1080 // 2 - 230))

它将每个目录中的图像加载到一个alphapygame.surface中。其中的每一个都被添加到列表中,然后我们可以在循环中blit或将每张图片画到屏幕上。

这只是基本设置,更高级的操作请看上面的代码,或者到我的GitHub中查看其他有趣的实验。

用提取的Mask修改输入视频

为了产生上图的效果,我记录了视频的前n帧,以及人物(person)和滑板(skateboard)的位置。

然后我将把之前抠出来的图一个一个叠好,最后粘贴最后一张图像。

除此之外我还试着将我的蒙版和其他视频混合起来。这里就是合成的一个案例:

同时调试环境和滑板者的每一帧,然后在环境上盖上蒙版,覆盖在滑板视频的顶部。这个代码也可以在我的GitHub里找到。

结语

想将深度学习与艺术结合,这种项目只是一个开始。另外还有一个名为OpenPose的模型,能够预测一个人的动作,并且模型十分稳定。我计划将OpenPose合并到未来的项目中,创建更有趣的作品。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 视频
    +关注

    关注

    6

    文章

    1891

    浏览量

    71903
  • python
    +关注

    关注

    51

    文章

    4677

    浏览量

    83468
  • 深度学习
    +关注

    关注

    73

    文章

    5239

    浏览量

    119912

原文标题:用Mask R-CNN自动创建动图

文章出处:【微信号:jqr_AI,微信公众号:论智】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    手把手教你使用LabVIEW实现Mask R-CNN图像实例分割(含源码)

    使用LabVIEW实现Mask R-CNN图像实例分割
    的头像 发表于 03-21 13:39 1409次阅读
    手把手教你使用LabVIEW实现<b class='flag-5'>Mask</b> <b class='flag-5'>R-CNN</b>图像实例分割(含源码)

    求问如何利用stm32实现gif的显示呢

    如何利用stm32实现gif的显示呢
    发表于 10-08 09:01

    基于YOLOX目标检测算法的改进

    通过算法生成候选区域,第二阶段利用 CNN 网络对候选区域进行 特征提取并根据提取的特征进行分类工作,得到最终的检测结果。R-CNN 系列目标检测算法以较慢的速度换取了较高的检测精度,在自动
    发表于 03-06 13:55

    介绍目标检测工具Faster R-CNN,包括它的构造及实现原理

    在本篇文章中,公司的研究人员介绍了他们在研究过程中所使用的先进目标检测工具Faster R-CNN,包括它的构造及实现原理。
    的头像 发表于 01-27 11:49 1.8w次阅读
    介绍<b class='flag-5'>目标</b>检测工具Faster <b class='flag-5'>R-CNN</b>,包括它的构造及实现原理

    什么是Mask R-CNNMask R-CNN的工作原理

    它的概念很简单:对于每个目标对象,Faster R-CNN都有两个输出,一是分类标签,二是候选窗口;为了分割目标像素,我们可以在前两个输出的基础上增加第三个输出——指示对象在窗口中像素位置的二进制
    的头像 发表于 07-20 08:53 6.7w次阅读

    引入Mask R-CNN思想通过语义分割进行任意形状文本检测与识别

    网络架构由四部分组成,骨干网feature pyramid network (FPN) ,文本候选区域生成网络region proposal network (RPN) ,文本包围盒回归网络Fast R-CNN ,文本实例分割与字符分割网络mask branch。
    的头像 发表于 08-07 14:24 1.4w次阅读

    手把手教你操作Faster R-CNNMask R-CNN

    R-CNN又承继于R-CNN,因此,为了能让大家更好的理解基于CNN目标检测方法,我们从R-CNN开始切入,一直介绍到
    的头像 发表于 04-04 16:32 1.3w次阅读

    一种新的带有不确定性的边界框回归损失,可用于学习更准确的目标定位

    目标检测是一种多任务学习问题,包含目标定位和目标分类。当前最佳的目标检测器(比如 Faster RCNN、Cascade R-CNN
    的头像 发表于 04-23 16:38 6153次阅读
    一种新的带有不确定性的边界框回归损失,可用于学习更准确的<b class='flag-5'>目标</b>定位

    基于MASK模型的视频问答机制设计方案

    视频问答是深度学习领域的研究热点之一,广泛应用于安防和广告等系统中。在注意力机制框架下,建立先验MASK注意力机制模型,使用 Faster R-CNN模型提取视频关键帧以及
    发表于 03-11 11:43 2次下载
    基于<b class='flag-5'>MASK</b>模型的<b class='flag-5'>视频</b>问答机制设计方案

    基于改进Faster R-CNN目标检测方法

    为提高小尺度行人检测的准确性,提出一种基于改进 Faster r-CNN目标检测方法。通过引入基于双线性插值的对齐池化层,避免感兴趣区域池化过程中两次量化操作导致的位置偏差,同时设计基于级联的多层
    发表于 03-23 14:52 3次下载
    基于改进Faster <b class='flag-5'>R-CNN</b>的<b class='flag-5'>目标</b>检测方法

    一种基于Mask R-CNN的人脸检测及分割方法

    针对现有主流的人脸检测算法不具备像素级分割,从而存在人脸特征具有噪声及检测精度不理想的问题提出了一种基于 Mask r-CNN的人脸检测及分割方法。通过 Res Net-l01结合RPN网络生成候选
    发表于 04-01 10:42 5次下载
    一种基于<b class='flag-5'>Mask</b> <b class='flag-5'>R-CNN</b>的人脸检测及分割方法

    基于Mask R-CNN的遥感图像处理技术综述

    较为密集,且容易与港口混合。当前对舰船检测的输岀结果主要是检测框,缺少对舰船掩码的输岀,使得无法全面分析岀模型存在的不足;冋时,由于遙感图像中的舰船停靠密集,容易产生漏检问題。为解决上述问题,利用 Mask r-cnn对舰
    发表于 05-08 16:39 3次下载

    用于实例分割的Mask R-CNN框架

    我们的方法称为 Mask R-CNN,扩展了 Faster RCNN ,方法是在每个感兴趣区域 (RoI) 上添加一个用于预测分割掩码的分支,与用于分类和边界框回归的现有分支并行(图 1)。掩码分支
    的头像 发表于 04-13 10:40 2208次阅读

    PyTorch教程14.8之基于区域的CNN(R-CNN)

    电子发烧友网站提供《PyTorch教程14.8之基于区域的CNN(R-CNN).pdf》资料免费下载
    发表于 06-05 11:09 0次下载
    PyTorch教程14.8之基于区域的<b class='flag-5'>CNN</b>(<b class='flag-5'>R-CNN</b>)

    PyTorch教程-14.8。基于区域的 CNN (R-CNN)

    14.8。基于区域的 CNN (R-CNN)¶ Colab [火炬]在 Colab 中打开笔记本 Colab [mxnet] Open the notebook in Colab
    的头像 发表于 06-05 15:44 387次阅读
    PyTorch教程-14.8。基于区域的 <b class='flag-5'>CNN</b> (<b class='flag-5'>R-CNN</b>)