0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Mask R-CNN:自動(dòng)從視頻中制作目標(biāo)物體的GIF動(dòng)圖

zhKF_jqr_AI ? 2018-02-03 14:19 ? 次閱讀

在上一篇文章中,我們介紹了用深度學(xué)習(xí)結(jié)合攝像機(jī)的方法自動(dòng)檢測(cè)并拍攝小鳥(niǎo)的照片。今天,我們用另一種新穎的深度學(xué)習(xí)模型——Mask R-CNN,自動(dòng)從視頻中制作目標(biāo)物體的GIF動(dòng)圖。

Mask R-CNN已經(jīng)有很多應(yīng)用了,論智君此前還介紹過(guò)Facebook利用這一模型實(shí)現(xiàn)全身AR的項(xiàng)目。不過(guò)在這個(gè)項(xiàng)目中,作者Kirk Kaiser使用的是MatterPort版本。它支持Python 3,擁有超棒的樣本代碼,也許是最容易安裝的版本了。

第一步,輸入正確的內(nèi)容

在開(kāi)始制作gif自動(dòng)生成器時(shí),我選擇先做一件最蠢的事,這種模式在有創(chuàng)意性編碼項(xiàng)目中表現(xiàn)得很好。

首先,輸入的視頻中只能含有一個(gè)人,不要嘗試跟蹤監(jiān)測(cè)視頻中的多個(gè)人。這樣我們就可以將目標(biāo)物體與其他對(duì)象隔離開(kāi),同時(shí)更容易評(píng)估模型掩蓋目標(biāo)對(duì)象的程度如何。如果目標(biāo)對(duì)象不見(jiàn)了,我們就能發(fā)現(xiàn),同時(shí)還能看到模型識(shí)別邊框的噪聲。

我選用的是自己在后院拍攝的視頻。

用Python處理視頻

盡管用Python處理視頻有其他方法,但我更喜歡將視頻轉(zhuǎn)換為圖像序列,然后再使用ffmpeg將其轉(zhuǎn)換回來(lái)。

使用以下命令,我們就能從輸入的視頻中獲取一系列圖像。根據(jù)輸入的視頻來(lái)源,它可能在每秒24到60幀之間。你需要跟蹤每秒輸入的視頻幀數(shù),以便在轉(zhuǎn)換后保持同步。

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

這將創(chuàng)建一個(gè)5位、0填充的圖像序列,如果您輸入的視頻長(zhǎng)度超過(guò)5位,則可以將%05d改成%09d。

數(shù)字序列將與視頻持續(xù)的時(shí)間一樣長(zhǎng)(以秒為單位),乘以每秒的幀數(shù)。所以一個(gè)時(shí)長(zhǎng)為三秒、每秒24幀的視頻,將有72幀。

由此,我們得到了一系列靜止的圖像,可以使用我們的靜態(tài)掩碼R-CNN代碼輸入。

完成了對(duì)圖像的處理后,稍后將使用以下命令把它們重新放回視頻中:

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

參數(shù)-r規(guī)定了每秒中我們需要使用構(gòu)建輸出視頻的幀數(shù)。如果我們想放慢視頻,可以降低參數(shù)的值,如果想加快速度,可以增加參數(shù)的值。

按照順序,讓我們先用Mask R-CNN來(lái)檢測(cè)并處理圖像。

檢測(cè)并標(biāo)記圖像

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

一旦你在本地設(shè)置好了repo,我建議在demo筆記本上運(yùn)行,并評(píng)估圖像檢測(cè)工作的水平。

通常掩碼是無(wú)符號(hào)的8位整數(shù),形狀與輸入的圖像一致。當(dāng)沒(méi)有檢測(cè)到目標(biāo)對(duì)象時(shí),掩碼是0或者黑色。當(dāng)檢測(cè)到對(duì)象時(shí),掩碼是255或白色。

為了處理蒙版,我們需要把它作為一個(gè)通道,復(fù)制或粘貼另一張圖像。用類似下面的代碼,可以從每個(gè)視頻的圖像中將單個(gè)人物摳出來(lái),生成一張透明底的圖像:

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數(shù)據(jù)集分出的不同事物的類別。然后只需要把列表中的任意類別的名字更換成if r[class_ids][b] == class_names.index(‘person’),你就可以從視頻中獲取帶有蒙版的版本了。

把圖片轉(zhuǎn)換成GIF

現(xiàn)在我們有了一組透明圖像,可以打開(kāi)看看它們的效果。我的結(jié)果并不是很好,人物摳的不是很精致,不過(guò)也挺有趣的。

然后我們就可以將圖像輸入進(jìn)ffmpeg中制作動(dòng)圖了,只需要找到圖像序列的最大寬度(width)和高度(height),然后將其粘貼到一個(gè)新的圖像序列中:

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)

上面的代碼打開(kāi)了我們的giffer0這個(gè)目錄,并在所有圖像中迭代,尋找最大尺寸圖像的width和height。然后它將這些圖像都放到一個(gè)新目錄(gifready)中,我們就能將其生成gif。

在這里,我們利用Imagemagick生成gif:

$ convert -dispose Background *.png outty.gif

但是僅僅從視頻中自動(dòng)生成動(dòng)圖也沒(méi)什么好激動(dòng)的,讓我們繼續(xù)把它們混合起來(lái),看看會(huì)發(fā)生什么……

在Pygame或視頻中應(yīng)用生成的GIFs

最近,我直接將這些提取的圖像用在了Pygame中。我并沒(méi)有將它們轉(zhuǎn)換成gifs,而是保留了原始PNG格式。

我自創(chuàng)了一個(gè)創(chuàng)意性小編程環(huán)境,其中包括一個(gè)setup和draw功能,將圖像序列作為輸入。使用這個(gè)設(shè)置,我可以將圖像旋轉(zhuǎn)、縮放或干擾它們。以下是代碼:

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))

它將每個(gè)目錄中的圖像加載到一個(gè)alphapygame.surface中。其中的每一個(gè)都被添加到列表中,然后我們可以在循環(huán)中blit或?qū)⒚繌垐D片畫到屏幕上。

這只是基本設(shè)置,更高級(jí)的操作請(qǐng)看上面的代碼,或者到我的GitHub中查看其他有趣的實(shí)驗(yàn)。

用提取的Mask修改輸入視頻

為了產(chǎn)生上圖的效果,我記錄了視頻的前n幀,以及人物(person)和滑板(skateboard)的位置。

然后我將把之前摳出來(lái)的圖一個(gè)一個(gè)疊好,最后粘貼最后一張圖像。

除此之外我還試著將我的蒙版和其他視頻混合起來(lái)。這里就是合成的一個(gè)案例:

同時(shí)調(diào)試環(huán)境和滑板者的每一幀,然后在環(huán)境上蓋上蒙版,覆蓋在滑板視頻的頂部。這個(gè)代碼也可以在我的GitHub里找到。

結(jié)語(yǔ)

想將深度學(xué)習(xí)與藝術(shù)結(jié)合,這種項(xiàng)目只是一個(gè)開(kāi)始。另外還有一個(gè)名為OpenPose的模型,能夠預(yù)測(cè)一個(gè)人的動(dòng)作,并且模型十分穩(wěn)定。我計(jì)劃將OpenPose合并到未來(lái)的項(xiàng)目中,創(chuàng)建更有趣的作品。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 視頻
    +關(guān)注

    關(guān)注

    6

    文章

    1914

    瀏覽量

    72517
  • python
    +關(guān)注

    關(guān)注

    53

    文章

    4753

    瀏覽量

    84070
  • 深度學(xué)習(xí)
    +關(guān)注

    關(guān)注

    73

    文章

    5422

    瀏覽量

    120587

原文標(biāo)題:用Mask R-CNN自動(dòng)創(chuàng)建動(dòng)圖

文章出處:【微信號(hào):jqr_AI,微信公眾號(hào):論智】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    手把手教你使用LabVIEW實(shí)現(xiàn)Mask R-CNN圖像實(shí)例分割(含源碼)

    使用LabVIEW實(shí)現(xiàn)Mask R-CNN圖像實(shí)例分割
    的頭像 發(fā)表于 03-21 13:39 ?2022次閱讀
    手把手教你使用LabVIEW實(shí)現(xiàn)<b class='flag-5'>Mask</b> <b class='flag-5'>R-CNN</b>圖像實(shí)例分割(含源碼)

    深度卷積神經(jīng)網(wǎng)絡(luò)在目標(biāo)檢測(cè)的進(jìn)展

    深度卷積神經(jīng)網(wǎng)絡(luò)(DCNN)在圖像分類和識(shí)別上取得了很顯著的提高。回顧2014到2016這兩年多的時(shí)間,先后涌現(xiàn)出了R-CNN,F(xiàn)ast R-CNN, Faster R-CNN, I
    發(fā)表于 11-16 01:41 ?5141次閱讀
    深度卷積神經(jīng)網(wǎng)絡(luò)在<b class='flag-5'>目標(biāo)</b>檢測(cè)<b class='flag-5'>中</b>的進(jìn)展

    介紹目標(biāo)檢測(cè)工具Faster R-CNN,包括它的構(gòu)造及實(shí)現(xiàn)原理

    在本篇文章,公司的研究人員介紹了他們?cè)谘芯窟^(guò)程中所使用的先進(jìn)目標(biāo)檢測(cè)工具Faster R-CNN,包括它的構(gòu)造及實(shí)現(xiàn)原理。
    的頭像 發(fā)表于 01-27 11:49 ?1.8w次閱讀
    介紹<b class='flag-5'>目標(biāo)</b>檢測(cè)工具Faster <b class='flag-5'>R-CNN</b>,包括它的構(gòu)造及實(shí)現(xiàn)原理

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

    它的概念很簡(jiǎn)單:對(duì)于每個(gè)目標(biāo)對(duì)象,F(xiàn)aster R-CNN都有兩個(gè)輸出,一是分類標(biāo)簽,二是候選窗口;為了分割目標(biāo)像素,我們可以在前兩個(gè)輸出的基礎(chǔ)上增加第三個(gè)輸出——指示對(duì)象在窗口中像素位置的二進(jìn)制
    的頭像 發(fā)表于 07-20 08:53 ?6.8w次閱讀

    引入Mask R-CNN思想通過(guò)語(yǔ)義分割進(jìn)行任意形狀文本檢測(cè)與識(shí)別

    網(wǎng)絡(luò)架構(gòu)由四部分組成,骨干網(wǎng)feature pyramid network (FPN) ,文本候選區(qū)域生成網(wǎng)絡(luò)region proposal network (RPN) ,文本包圍盒回歸網(wǎng)絡(luò)Fast R-CNN ,文本實(shí)例分割與字符分割網(wǎng)絡(luò)mask branch。
    的頭像 發(fā)表于 08-07 14:24 ?1.4w次閱讀

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

    R-CNN又承繼于R-CNN,因此,為了能讓大家更好的理解基于CNN目標(biāo)檢測(cè)方法,我們R-CNN
    的頭像 發(fā)表于 04-04 16:32 ?1.3w次閱讀

    一種新的帶有不確定性的邊界框回歸損失,可用于學(xué)習(xí)更準(zhǔn)確的目標(biāo)定位

    目標(biāo)檢測(cè)是一種多任務(wù)學(xué)習(xí)問(wèn)題,包含目標(biāo)定位和目標(biāo)分類。當(dāng)前最佳的目標(biāo)檢測(cè)器(比如 Faster RCNN、Cascade R-CNN
    的頭像 發(fā)表于 04-23 16:38 ?6328次閱讀
    一種新的帶有不確定性的邊界框回歸損失,可用于學(xué)習(xí)更準(zhǔn)確的<b class='flag-5'>目標(biāo)</b>定位

    基于MASK模型的視頻問(wèn)答機(jī)制設(shè)計(jì)方案

    視頻問(wèn)答是深度學(xué)習(xí)領(lǐng)域的研究熱點(diǎn)之一,廣泛應(yīng)用于安防和廣告等系統(tǒng)。在注意力機(jī)制框架下,建立先驗(yàn)MASK注意力機(jī)制模型,使用 Faster R-CNN模型提取
    發(fā)表于 03-11 11:43 ?2次下載
    基于<b class='flag-5'>MASK</b>模型的<b class='flag-5'>視頻</b>問(wèn)答機(jī)制設(shè)計(jì)方案

    基于改進(jìn)Faster R-CNN目標(biāo)檢測(cè)方法

    為提高小尺度行人檢測(cè)的準(zhǔn)確性,提出一種基于改進(jìn) Faster r-CNN目標(biāo)檢測(cè)方法。通過(guò)引入基于雙線性插值的對(duì)齊池化層,避免感興趣區(qū)域池化過(guò)程兩次量化操作導(dǎo)致的位置偏差,同時(shí)設(shè)計(jì)基于級(jí)聯(lián)的多層
    發(fā)表于 03-23 14:52 ?3次下載
    基于改進(jìn)Faster <b class='flag-5'>R-CNN</b>的<b class='flag-5'>目標(biāo)</b>檢測(cè)方法

    用MATLAB制作GIF格式動(dòng)資料下載

    電子發(fā)燒友網(wǎng)為你提供用MATLAB制作GIF格式動(dòng)資料下載的電子資料下載,更有其他相關(guān)的電路、源代碼、課件教程、中文資料、英文資料、參考
    發(fā)表于 03-27 08:45 ?19次下載
    用MATLAB<b class='flag-5'>制作</b><b class='flag-5'>GIF</b>格式<b class='flag-5'>動(dòng)</b><b class='flag-5'>圖</b>資料下載

    一種基于Mask R-CNN的人臉檢測(cè)及分割方法

    針對(duì)現(xiàn)有主流的人臉檢測(cè)算法不具備像素級(jí)分割,從而存在人臉特征具有噪聲及檢測(cè)精度不理想的問(wèn)題提出了一種基于 Mask r-CNN的人臉檢測(cè)及分割方法。通過(guò) Res Net-l01結(jié)合RPN網(wǎng)絡(luò)生成候選
    發(fā)表于 04-01 10:42 ?5次下載
    一種基于<b class='flag-5'>Mask</b> <b class='flag-5'>R-CNN</b>的人臉檢測(cè)及分割方法

    基于Mask R-CNN的遙感圖像處理技術(shù)綜述

    較為密集,且容易與港口混合。當(dāng)前對(duì)艦船檢測(cè)的輸岀結(jié)果主要是檢測(cè)框,缺少對(duì)艦船掩碼的輸岀,使得無(wú)法全面分析岀模型存在的不足;冋時(shí),由于遙感圖像的艦船??棵芗菀桩a(chǎn)生漏檢問(wèn)題。為解決上述問(wèn)題,利用 Mask r-cnn對(duì)艦
    發(fā)表于 05-08 16:39 ?3次下載

    用于實(shí)例分割的Mask R-CNN框架

    我們的方法稱為 Mask R-CNN,擴(kuò)展了 Faster RCNN ,方法是在每個(gè)感興趣區(qū)域 (RoI) 上添加一個(gè)用于預(yù)測(cè)分割掩碼的分支,與用于分類和邊界框回歸的現(xiàn)有分支并行( 1)。掩碼分支
    的頭像 發(fā)表于 04-13 10:40 ?2496次閱讀

    PyTorch教程14.8之基于區(qū)域的CNN(R-CNN)

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程14.8之基于區(qū)域的CNN(R-CNN).pdf》資料免費(fèi)下載
    發(fā)表于 06-05 11:09 ?0次下載
    PyTorch教程14.8之基于區(qū)域的<b class='flag-5'>CNN</b>(<b class='flag-5'>R-CNN</b>)

    PyTorch教程-14.8?;趨^(qū)域的 CNN (R-CNN)

    14.8。基于區(qū)域的 CNN (R-CNN)? Colab [火炬]在 Colab 打開(kāi)筆記本 Colab [mxnet] Open the notebook in Colab
    的頭像 發(fā)表于 06-05 15:44 ?550次閱讀
    PyTorch教程-14.8?;趨^(qū)域的 <b class='flag-5'>CNN</b> (<b class='flag-5'>R-CNN</b>)