mieki256's diary



2021/06/29(火) [n年前の日記]

#1 [love2d] グリーンバック映像からアルファチャンネルとRGBの2つの動画を作成

グリーンバック映像を元にして、RGBA動画(アルファチャンネルを含んだ動画)を作成したい。更にそこから、アルファチャンネルだけを取り出した白黒(グレー)のRGB動画と、透明な部分を真っ黒にしたRGB動画の2つを作りたい。

環境は Windows10 x64 20H2。

グリーンバッグ映像の入手 :

今回は、以下のサイトから、お姉さんが踊ってるグリーンバック映像を入手させてもらった。

_Free stock videos - Pexels Videos

現時点でのライセンスは以下のようになっていた。
  • 「写真と動画は無料で使える」
  • 「帰属は必要無し」
  • 「写真や動画を変更せずに販売や再配布してはいけない」

_Free Stock Photo & Video License - Pexels

とりあえず、実験に使うだけだから、問題は無いだろう…。たぶん。

映像サイズを1280x720に変更。 :

グリーンバック映像の元動画は、3840x2160, 24fps だった。サイズを 1280x720 にしたい。普段使い慣れている Avidemux 2.7.6 を使ってリサイズ(縮小)した。

_Avidemux のダウンロードと使い方 - k本的に無料ソフト・フリーソフト

  • 映像出力 → フィルター → 拡大縮小(swScale) → 1280x720を指定。
  • 映像出力は、可逆圧縮であろう、(FF)HuffYUV を選択。
  • 出力形式は AVI Muxer を選択。

avi として保存。

ffmpegを使ってリサイズしたほうが楽かもしれない。

_【ffmpeg】動画の解像度を指定してリサイズ、アスペクト比を維持したまま解像度を変更する、回転する - Qiita
_FFmpegで動画をリサイズする - Askthewind’s diary
_リサイズする scale | ニコラボ

グリーンバック映像をRGBA動画に変換。 :

グリーンバック部分を透明にして、RGBA動画として保存したい。

今回は、AviUtl 1.10 + 拡張編集プラグインを使った。

_AviUtlのお部屋

  • 拡張編集プラグインのウインドウを表示する。設定 → 拡張編集の設定。
  • 拡張編集プラグインのウインドウ上で右クリックして、新規プロジェクトの作成。
  • 1280x720,24FPSのプロジェクトとして新規作成。

Layer1 に、1280x720にしたグリーンバック映像(.avi)を追加する。
  • Layer1 の横で右クリック → メディアオブジェクトの追加 → 動画ファイル。
  • 参照ファイル、をクリックして、.avi を選択。

グリーンバック部分を透明にする。拡張編集プラグインのフィルタの中に、クロマキーがあるので利用する。

_【AviUtl】透明化エフェクト(クロマキー・カラーキー・ルミナンスキー)の使い方【キーイング】 | AviUtlの易しい使い方
_すんなりわかるAviUtlのクロマキーの使い方・やり方 - Aviutl簡単使い方入門|すんなりわかる動画編集

  • 「+」アイコンをクリックして、クロマキーを選択。
  • 「キー色の取得」をクリックして、透明にしたい緑色の部分をクリック。

aviutl_ckey_ss1.png

aviutl_ckey_ss2.png

aviutl_ckey_ss3.png

これで、緑色の部分が真っ黒な表示になって透明化された。

この状態で、RGBA動画として保存したい。拡張編集プラグインのウインドウ上で右クリックして、ファイル → メディアオブジェクトのAVI/BMP出力(RGBA)、を選べば、UtVide RGBA codec 等を使ったRGBA動画(.avi)として出力できる。

aviutl_ckey_ss4.png

アルファチャンネルだけを取り出した白黒動画にする。 :

ffmpegを使えば、アルファチャンネルだけを取り出した白黒動画にできるのだとか。

_アルファチャンネルをグレーで出力する alphaextract | ニコラボ

「-vf alphaextract」を指定すればいいらしい…?

今回は、ffmpeg 4.3.2-2021-02-27-full_build-www.gyan.dev を使用した。保存時のフォーマットは、可逆圧縮の UtVideo RGB を使った。
ffmpeg -i input_rgba.avi -vcodec utvideo -vf alphaextract mask_rgb.avi

RGBA動画をRGB動画にする。 :

RGBA動画の透明部分を、完全な黒にしたい。おそらく ffmpeg でも処理できそうな気はするけれど、今回は、AviUtl + 拡張編集プラグインを使って作業した。
  • Layer2にRGBA動画を配置。
  • Layer1には、メディアオブジェクトの追加 → 図形。「背景」にして、RGB=(0,0,0) を設定。

これで、透明部分を完全に黒い状態にできた。

ファイル → AVI出力。UtVideo RGB codec を選んで avi として出力。

RGB動画をogvに変換。 :

ここまでの作業で、アルファチャンネルだけを動画にしたRGB動画、mask.avi と、透明部分を真っ黒にしたRGB動画、rgb.avi が得られた。

ffmpeg を使って、love2d でも扱える動画フォーマット、.ogv (Theora) に変換する。
ffmpeg -i mask.avi -c:v libtheora -q:v 10 mask.ogv
ffmpeg -i rgb.avi -c:v libtheora -q:v 10 rgb.ogv

これで、mask.ogv と rgb.ogv の2つの動画が得られた。

ようやく、love2dで実験できる…。

ffmpegを使って動画を連番画像にする。 :

余談。今回は使用しなかったが、ffmpeg を使って動画を連番画像に変換することもできる。連番画像にしてしまえば、色々と変換処理する場合も、何かしら楽になったりするのかもしれない…。

_ffmpeg 動画から連番画像を作成する - Kinaconの技術ブログ

ffmpeg -i input.avi -vcodec png -r 24 images\image_%04d.png

さらに余談。 :

Shotcut という動画編集ソフトでもクロマキー合成云々という記事を見かけたので最初はそれで試してたのだけど。

_【Shotcut】クロマキー合成のやり方【クロマキー:シンプル】 | nyanco! ブログ

RGBA動画として出力する方法が分からなくて挫折した。そんな出力はできるのだろうか…。とりあえず、Shotcutの中でクロマキー合成をして最終動画まで持っていく、といった作業をする分には、おそらくフツーに使えそうではあるなと…。

#2 [love2d] love2dで2つの動画を使って動画の一部を透明に見せかける

RGBA動画を元にして、RGB動画と、アルファチャンネルのみ取り出した白黒のRGB動画を作成することができた。この2つの動画を使って、love2d上で、動画の一部を透明にした感じの描画ができるかどうか試してみる。

念のために書いておくけど、love2d で扱える動画フォーマット ogv (Theora) はアルファチャンネルを含めることができないので、動画の一部を透明にしたい場合、何かしら頓智が必要になるわけで。

環境は、Windows10 x64 20H2 + love2d 11.3。

手順としては、昨日試した通り。

_ogvファイルとアルファチャンネル

再度、流れを書くけど…。 これを、2つの動画を使って行う。

ソースは以下。

_main.lua
function love.load()
  -- load bg image
  bgimg = love.graphics.newImage("bg.jpg")
  
  -- load video(.ogv)
  maskvideo = love.graphics.newVideo("mask.ogv")
  rgbvideo = love.graphics.newVideo("rgb.ogv")
  maskvideo:play()
  rgbvideo:play()
end

function love.update(dt)
end

function love.draw()
  -- loop video play
  if not rgbvideo:isPlaying() then
    maskvideo:rewind()
    rgbvideo:rewind()
    maskvideo:play()
    rgbvideo:play()
  end
  
  -- canvas clear
  love.graphics.clear(0, 0, 0, 1)

  -- draw bg
  love.graphics.setColor(1, 1, 1, 1)
  love.graphics.draw(bgimg, 0, 0)

  -- draw video
  love.graphics.setBlendMode("subtract")
  love.graphics.draw(maskvideo, 0, 0)
  
  love.graphics.setBlendMode("add")
  love.graphics.draw(rgbvideo, 0, 0)

  -- draw text
  love.graphics.setBlendMode("alpha")
  love.graphics.setColor(1, 1, 1, 1)
  love.graphics.print("ESC to exit.", 8, 4)
end

function love.keypressed(key, scancode, isrepeat)
  if key == "escape" then
    love.event.quit()
  end
end

_conf.lua
function love.conf(t)
  t.window.width = 1280
  t.window.height = 720
  t.window.title = "Draw video alpha"
  t.window.fullscreen = false
  -- t.window.fullscreentype = "exclusive"
end

必要な画像、動画は以下。

_bg.jpg
_mask.ogv
_rgb.ogv

念のために、ソース、画像、動画をまとめてzipにして置いときます。

_draw_video_alpha.zip

さて。実行してみたら、こうなった。



一見すると上手く行ってるように思えたけれど、よく観察してみると、どうも周辺に残像のようなものがチラチラと表示される…。

デスクトップを60fpsでキャプチャして、一部分をクロップして4fpsにしてみた。



アルファチャンネル担当の動画と、RGB動画の、同期が取れていないようだなと…。RGB動画のほうが1フレーム遅れて描画される瞬間が何度も発生しているように見える。それで輪郭がチラチラするというか、残像のようなものが見えてしまう模様。

ちなみに、元動画がそもそも1フレームずれているのではないかと疑って、AviUtl + 拡張編集プラグインを使って、2つの動画を重ねて確認してみたけれど、元動画はずれてるように見えなかった。というか、24fpsの動画で1フレームずれていたら、こんなもんじゃ済まない。もっと盛大なずれになる。つまりコレは、love2dで再生・描画した際に、love2dのフレームレートで、1フレームずれる時がある、ということだろう…。

解決策はあるのだろうか…。

そもそも love2dは、再生される動画は1つ、という前提で作られてそうな気もする。フツー、2つの動画を、両方一度に再生するとは思わないよな…。

1つの動画にしてみる。 :

2つの動画を同時に再生して同期が取れてないのが問題なら、1つの動画にまとめてしまえばいいのではないかと思いついた。

つまり、以下のような見た目になっている、1つの動画にしてしまえば…。

comb_frame.png

これを、以下のような仕組みで利用する。

draw_video_alpha2_about.png

これなら動画の同期云々なんて考えなくてもよいのではないか。

試してみた。ソースは以下。

_main.lua
function love.load()
  videocanvas = love.graphics.newCanvas(1280, 1440)
  
  -- load bg image
  bgimg = love.graphics.newImage("bg.jpg")
  
  -- load video(.ogv)
  video = love.graphics.newVideo("comb.ogv")
  video:play()
end

function love.update(dt)
end

function love.draw()
  -- loop video play
  if not video:isPlaying() then
    video:rewind()
    video:play()
  end
  
  -- canvas clear
  love.graphics.clear(0, 0, 0, 1)

  -- draw bg
  love.graphics.setBlendMode("alpha")
  love.graphics.setColor(1, 1, 1, 1)
  love.graphics.draw(bgimg, 0, 0)
  
  -- draw video to video canvas
  love.graphics.setCanvas(videocanvas)
  love.graphics.draw(video, 0, 0)
  love.graphics.setCanvas()

  -- draw video canvas
  love.graphics.setBlendMode("subtract")
  love.graphics.draw(videocanvas, 0, 0)
  
  love.graphics.setBlendMode("add")
  love.graphics.draw(videocanvas, 0, -720)

  -- draw text
  love.graphics.setBlendMode("alpha")
  love.graphics.setColor(1, 1, 1, 1)
  love.graphics.print("ESC to exit.", 8, 4)
  
end

function love.keypressed(key, scancode, isrepeat)
  if key == "escape" then
    love.event.quit()
  end
end

_conf.lua
function love.conf(t)
  t.window.width = 1280
  t.window.height = 720
  t.window.title = "Draw video alpha2"
  t.window.fullscreen = false
  -- t.window.fullscreentype = "exclusive"
end

動作に必要な画像、動画は以下。

_bg.jpg
_comb.ogv

実行してみたら、こうなった。



一部をクロップして4fpsで再生してみる。



これで上手く行ったのではなかろうか。

ということで、love2d上で疑似的に、アルファチャンネルを持ってるかのような見た目で動画再生することも一応できる、と分かった。

考えてみたら、こういう見た目の素材をどこかで見たなと…。紙芝居ゲームの制作ツールで、こういう画像を用意せよと要求してくる事例があったような…。そのやり方を動画にも流用できるよ、という話になるのかな。

ちなみに、RGB動画とアルファチャンネル動画を上下に並べた動画を作成する作業には、AviUtl + 拡張編集プラグインを使った。ただ、その後ググってみたら、ffmpeg でも上下に繋げた動画を作成できたらしい。

_研究で使うFFmpegコマンドまとめ - Qiita

ffmpeg -i mask.avi -i rgb.avi -filter_complex "vstack" -vcodec utvideo out.avi

入力動画ファイルを2つ指定して、-filter_complex "vstack" を指定すればいいようだなと…。

#3 [movie] 「ピーターラビット」を視聴していたことをメモ

先週の金曜日に放送されていたソレを視聴していたことをメモ。HDDレコーダから消す前にメモしておかないと、視聴したことをそのうち忘れてしまう…。

感想としては、CGが凄いなと…。CGキャラと実写の役者さんが喧嘩するカットはどうやって作ったんだろうと…。モーションは手付けなんだろうか。モーションキャプチャは…ウサギだから使えないよな、たぶん。作業内容を想像すると、ゾッとする…。

話のジャンルとしてはトムとジェリーあたりに近いのだろうか。こっちはトム、じゃなくて人間が可哀相になってくる展開というか。でもまあ最後はアレがソレになるからファミリー向けとしても安心だなと…。

何にせよ、こんな映像が作れるようになったとは…。スゴイ時代になった…。

以上、1 日分です。

過去ログ表示

Prev - 2021/06 - Next
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project