映像関連

映像関連の研究につけられるカテゴリー

超解像の基礎


情報工学科3年、AI班班長の渡邉です。研究室の決定の際にメンタルがグワングワンしていましたが今は元気です。

今回は下級生の機械学習の実践として理解しやすく、結果もわかりやすい超解像の分野に関して、その初歩の部分の論文を簡単に解説していこうと思います。

超解像とは?

すごい簡単に言えば画質を上げるやつです。waifu2xなどは有名ですが、最近ではA.I.Gigapixelなどの商品も出てきているので、技術の進歩を感じますね。

最初の論文

機械学習が超解像の分野に用いられたのは2014年のImage Super-Resolution Using Deep Convolutional Networks.が最初だといわれています(確認してないので違ったら教えてください)
この論文内で採用されているモデルは3層と非常に浅く、損失関数は最小二乗誤差となっています。これを図や数式で示すと以下のようになります。尚、モデル図や損失関数の式は上の本論文から引用しています。
srcnn

$$
L(\Theta) = \frac{1}{n}\sum_{i=1}^{n}{|F(\boldsymbol{Y_i:\Theta)}-\boldsymbol{X_i}|}
$$
$$
\Theta = {W_i,W_2,W_3,B_1,B_2,B_3}
$$
このような今からだとチュートリアルにも思えるような簡単なモデルですが、PSNR(ピーク信号雑音比)という指標において既存手法を上回る性能を発揮しています。当時の既存手法と結果を比較したものが論文中に示されているのでこれも提示します。
SRCNN-result
このままだと何も違いが判りませんが、拡大するとわかりやすくなると思います。

そしてこの論文以降、機械学習を超解像に用いるのがブームになっていきました。

SRGAN

機械学習により超解像の分野にはある種ブレイクスルーが訪れたと考えられていましたが、最小二乗法を用いると、CNNで圧縮された値を最小化しようとするため、PSNRベースで見れば確かに雑音が小さいものが出力されますが、人間の視覚的にはあまりそれらしくないという状況が発生していました。これを解決する手法として用いられたのがGANです。要は、GANでは(うまくいけば)それらしいものを生成することができるので、これを使って超解像を行うことで、人間の目から見てそれっぽいものを作れるのではないかと考えられるようになり、実際にうまくいったものととして紹介されたのがPhoto-Realistic Single Image Super-Resolution Using a Generative Adversarial Network(2016)、通称SRGANです。この論文内では、新たな主な取り組みとしては、Pixelshuffler、Content loss、Adversarial lossの採用等が挙げられますが。次はこれらの解説を簡単に行おうと思います。

Pixelshuffler

通常のdeconvolutionでは、生成された画像が格子状になっている箇所があるものが比較的よくみられました。それは、画素ごとに参照回数に差があるためであり、実際にhttps://distill.pub/2016/deconv-checkerboard/にある動画を見てもらうと直感的にわかると思います。


そしてこれを解決するために用いられたのがPixelshufflerであり、Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Networkに初めて登場しています。これが、実際にはどのような操作を行っているのかというと、各チャネルの画素をその場に展開するという手法をとっています。言葉だけではわかりにくいので、元論文から画像を引用します。
pixelshuffler
画像が小さくなることを忘れていたので言葉でも頑張ってなるべくわかりやすくすることにします。convolution等を行った後のサイズが$$w\times h\times c^2$$であったときに、Pixelshufflerでは、これを$$wc\times hc\times 1$$として出力することで、deconvolutionに相当する操作を行っています。

Content loss

これは、style-transfer界隈から用いられたもので、各画素の値を比較するのではなく、学習済みのVGGに画像を流し、中間層での特徴量を比較することによって、鮮明な画像を出力することができるようにしたものです。数式としてはi番目のMaxPooling層の前のJ番目の畳み込み層(アクティベーション後)の特徴量などを逐次計算しています。(数式が入力できなかったのでこれで許してください、Hackmdで入力できたのになぜ)

Adversarial loss

GANの損失関数です。数式が入力できなくなった(添え字が複数段階つく数式などが表示できない)のでこれもほとんど通常のGANの損失関数と変化がないのでこれだけにしておきます。

SRGANのモデル

いろいろ書きましたが、結局SRGANのモデルは以下のようになっています。
SRGAN-models
また、損失関数に関しては、generatorはContent loss と Adversarial loss を1:0.001の割合で足し合わせて使用しているそうです。
では、SRGANがどの程度の性能を出すことができたのかを比較してみましょう。

SRGANの性能

元論文では、以下のような差が出たことが報告されています。
srganresultimage

確かに、SRGANの性能が他のSRCNN等と比較してよくなっていることがわかります。また、SRGANは特に人間が主観的に判断した際の美しさ(MOS)の値がよいことが知られており、それを示している結果は以下の画像の通りです。
srganresurltable2
尚、これらの画像において、SRGANのAdversarial lossを考慮しないものはSRResNetと呼ばれています。

最近の研究

これらの超解像の技術の進歩の結果、PSNRなどの数式で表すことができるような定量的な指標と、人間の主観で判断するMOSなどの定量的な指標の間にはトレードオフの関係があることがわかっており、どちらかに特化した手法が最近は開発される流れになってきています。具体的な例としては、SRGANの中のAdversarial lossのgenaratorの部分のlossに関しても考慮し、その中間層の特徴を生かすような構造を用いたSRFeatや、PSNRの向上に特化したRCANや、SRGANに対して、さらに他の手法で用いられた手法を取り込むことでさらにMOSの評価を上げたESRGANなどが開発されています。

所感

記事の冒頭にも書きましたが、このような分野の大きな利点は成果を実際に見て確認することができることだと思います。また、自分で記事を書いてみて、改めて基礎分野の重要性を感じました。
 

RadeonRaysを使ってみた

どうも,チョコです.

最近レイトレーシングをちょっとやってるんですけど,流石に自分でメモリ構造体を作るのが不効率すぎて辛い.昨日Siggraph Asia行った時に見たRenderMan22が速すぎて衝撃を受けました.

そこで,AMDが開発したRadeonRays(以下RR)というオープンソースなライブラリを見つけました.しかもopencl1.2なのでいろんな環境で動きますね.

(ここでレイトレプロのみなさんへの忠告です.この記事を書いた僕はくそレイトレ―シング初心者です.画像を見て吐き気がしたら見るのをやめましょう.)

さて,RRのサンプルを動かしてみよう.ここではVisualStudioを使ってCornellBoxサンプルをコンパイルして見ましょう.

DmqIdRdUwAA2Wmt.jpg large

おう.すごい.

しかし,これだとレイトレっぽくないので,とりあえず反射を入れましょう.

反射とは要するに,レイをdとしたら,表面の法線nに対して

d’=d2(dn)n

を計算すればいいですね.また,この時,最終の色は元の色と乗算します.

DmqWF7MV4AEb7vS.jpg large

レイトレっぽくなりましたね.

次に,反射をDiffuseにしましょう.ここではLambertを使います.Lambertは簡単にいうと,入射角と法線の内積で明るさが決まりますね.まずは単純に,表面から半球の法線をランダムに決めて内積を取って乗算します.ただし,ここでは光源を円に変え,円に当たらなかったレイは黒にします.

cwe

ノイズ高いですね(適当).

Diffuseの次は当然Specularですね.ここではBeckmannを使います.説明が面倒なのでググって.ただし,普通にランダムに取ると収束まで結構時間がかかりますので,ここではImportance Samplingを行います.

BeckmannのImportance Samplingはここを見てください.

LambertのImportance Samplingはここを見てください.

Specularだけだとこうなります(Beckmann coefficient = 0.2).

s

ピカピカですね.

DiffuseとSpecularの組み合わせはShlick’s Fresnelを使います.とりあえず単純に,このFresnelの値を確率のカットオフとして,ランダム値がこの値より小さかったらSpecular反射を解散して,そうでなかったらDiffuseということにします.こういうことです.

すると結果はこうなります(Specular = 0.4).

wv

ノイズ高いですね(これしかコメント言えん).

箱は見飽きたので,サルを入れてみましょう.サルは金属にしましょう.

Screenshot (381)

ふむ....

サルは可愛くないので,シャロちゃんを入れましょう().CornellBoxも消して,Skyboxを入れましょう.

レイが表面にぶつからなかった時,方向を使ってSkyboxから色をこのように取ります.ただし,レイがまだ反射していないものなら黒にします.

するとこのようになります(適当).

Screenshot (385)

かわいい...


まだまだダメですが満足したのでやめます.最後にコメントです.

RRのGeneratePerspectiveRaysは視野を気にしないので,表示の縦横比を帰ると変になります.そのため,GLMの行列を使って書き換えます.

Importance Samplingが入っているLambertとBeckmannのコードです.ただし,乱数生成器はXorshiftを使います.

では.

女の子を描いてみた。

こんにちは、しゃちです。

一年生でこのような記事をかくことに慣れていないので温かい目で見てくれれば幸いです。

今回は春学期に私が個人で練習したデジタルイラストに関する記事を書こうと思います。

描くものは今話題のバーチャルユーチューバーで私が推しているヤマトイオリを描こうと思います。

設定、下描き、線画をする。

まず、イラストの新規ファイルを作成します。このときに作成するイラストのファイル名、解像度などを設定します。今回は750dpiとして描いて行こうと思います。

ファイルを開いたらキャンパスが出てきますので、まず薄い鉛筆で下描きしたあと、Gペンで線画しました。このとき、線画、下描き、各部位の塗り、背景など種類によってレイヤーをわけておきます。今回はした図のように、肌、目、髪、服、背景などレイヤーを作ります。こうすることであとの塗りの作業で特定のパーツだけ塗れるようになります。

スクリーンショット (108)

 

下塗りをする。

レイヤーをわけて各パーツに色を塗ります。

 

スクリーンショット (110)

目、肌の影を塗る。

基本、影を塗る場合は下塗りした色より少しくらい色をおいていきます。肌の影を塗ります。肌の下塗りしたレイヤーの上に新規レイヤーを作成し、クリッピングという作業をします。こうすることでクリッピングしたレイヤーに置かれている色の領域でしかそのレイヤーにおいて色がおけなくなります。はっきりした影はGペンで、ぼんやりとした形はエアブラシでおいていきます。

スクリーンショット (111)

目においては何枚もレイヤーを重ねて塗っていきます。

スクリーンショット (113)

スクリーンショット (114)

スクリーンショット (117)

髪の毛を塗る。

髪の毛においても同様に何枚もレイヤーをかさなて影を置いていきます。私が塗った順番としては、

大まかな影→髪の毛のグラデーション→髪の毛の一本一本の流れ→光の反射

です。

ここで影を塗るレイヤーの設定を「乗算」とすることで下のレイヤーに塗られている色より濃い色を塗れるようになります。

スクリーンショット (120)

スクリーンショット (122)

スクリーンショット (123)

服を塗る。

服も同様に塗ります。ここで花柄はCLIP STUDIO PAINT で配布されているユーザーが作ったものを使用しています。

服を塗るにあたって、服の素材を引きだたせたいとおもいます。一度Gペンではっきり塗った後、「ぼかし」ツールで上の部分をやんわりとさせます。

スクリーンショット (128)

スクリーンショット (129)

背景、仕上げ

最後に背景や全体的な質感を醸し出すための調整をして完成です。

スクリーンショット (127)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

止めると見えない動画

INVISIBLEWHILESTOPPING

唐突に思いついたので、止めると見えなくなる動画を作成しました。次をご覧ください。

動画再生中は、正方形が中央を中心に公転運動しているのがわかると思います。

理論的には、次のようになっています。


動画の画素Iを空間と時間の関数\(I(t,x)\)とする。

\(I(t,x)\)が必ずランダムに、\(dI/dt (t,x)\)が、希望する映像を反映したものとする。

すると、動画を再生したときには、\(dI/dt\)が知覚されることによって希望する映像を何らかの形で反映した映像を見ることができるが、静止画では、ある時間\(t\)においての\(I\)しか知覚されないため、ランダム画像として認識される。

このような性質を満たすために、汎関数\(R(I(x))\)を、ランダム性が確保されているかどうかを測定する指標を導入して性質を満たすような画素を常に生成することを考える。(ゼロ以上でランダムではないと判定されるとする。Rは画素の空間的な分布を調べる関数であり、時間的分布は調べない)\(\)

すると、満たすべき条件は、\( R(I(t,x)) <0 \)となる。これは、いかなる時刻においても、\(R(I(t,x))<0\)となるように,\(I(t,x)\)を選べば良いことを示している、

この\(R\)が、どのような関数となっているかについての厳密な議論をすると、大変な文量になってしまうので、ここでは簡易的なモデルを考える。ランダム列とは、等確率性と無規則性を満たすものであるから、この2つを簡易的に調べられるような関数を作成すればよい。今回は、次のようにする。

  • ある領域を準ランダムに選択して、その平均を調べる。この操作を何回か行って、然るべき分布との乖離(二乗誤差とか)から、閾値を引いた値をRとする。

このようにすれば、ある程度の無規則性や等確率性が調べられると考えられる。このとき、準ランダム的に選択、とは、規則的となっている画素列を発見するための選択方法を用いる、ということである。たとえば、

0,1,2,0,1,2,0,1,2,0,1,2

という列は、等確率性を満たしているが規則的である。これを発見するために領域をn=3k+p(p=ランダム)というように選択すれば、(0,0,0,0),(2,2,2,2)のような列が選択されて、平均値の分布は一様分布となる。ランダム列の平均値の分布は一様分布ではないので、これは規則性のある分布であると検出できる。

このように定義されたランダム指標\(R\)を満たすように、I(t,x)を生成する方法を考えたいところだが、一般的な方法論を導き出すのは難しそうなので、より特殊な方法を考えた。それは、次のような方法である。シード値\(h\)により生成されるランダム画像\(J(h)\)があるとする.ここで、hの値が近いほど似たような画像となるようにする。この画像\(J(h)\)は、R<0を満たす。ここで、複数のシード値から生成される画像の部分部分を切り取ってきて、一枚の画像を構成するときも、R<0を満たす[*]。よって、例えば二値化映像を元映像に用いる場合は、黒い部分の領域を\(J(h_1(t))\),白い部分の領域を\(J(h_2(t))\)として画像を構成する(\(h_i(t)\)は連続関数とする)このようにすれば、R<0となるのは明らかで、かつ同色な領域では似たような映像で、色の境界では時間的に不自然な模様(微分が際立つ)ができあがる。

[*]ある領域を準ランダムに選択して、その平均を調べ,それが常に正しい分布になっているようなランダム画像があるとする。この画像から、部分を切り取って、画像を構成するとき、切り取られる部分だけを選択して選んだ準ランダム領域も、正しい分布に従う。よって、正しい分布に従う部分領域を複数用意しても、正しい分布となる。


少々議論が危ういところがありますが、結論をいいますと、複数の「ランダムな画像」から、一つの画像を構成しても、またランダムになることを利用する。ということです。ここで注目するべきなのは、「ランダムな画像」とは、別にノイズ画像ではなくてもよい点です。最初に示した画像は、ランダムな大きさの円が規則的に並んでいますが、これは「ランダムであるということ」が「円の大きさ」だけで判定されるということです。これによって、多様な「止めると見えない動画」を生成することが可能であると考えられます。

最初に示した方法を使って、某有名な影絵を表示してみました。

 

 

 

 

レイトレーシングを実装(v2)

これの続き。

材質を追加しました(ランバート拡散反射)

・結果

image

画像の床部分と大きな球が拡散反射の材質を持っている。

色付き球と床の接触部分付近や大きな球に、色が写り込んでいるのがわかりますね。

 

おまけ 模様つき

rtlbt2

おまけ2 twitter動画埋め込みテスト

レイトレーシングを実装(v1)

慶応大学は、春季休校に入りました。期末試験が終わり開放感を感じる中、自分のまだ知らないことを色々勉強していかなければならないと思いました。

とはいえ、テスト終わりすぐに難しい本やらを読むのは気が引けるので、きばらしとして簡単なレイトレーシングを実装してみることにした。ただしライブラリに頼るのは本末転倒であるので、今回は何もライブラリを使わずに1からやってみようと思った。(しばりプレイ)

・やること
簡単なレイトレーシングをする。
外部ライブラリは一切使わない。(画像表示、画像保存、線形代数、などの基礎ライブラリも使いません)
使えるものはVisualStudio(C++)で標準的に使えるもののみ。

・結果

sphere_rt

表示は自力BMP。

床だけは赤い床で、上からの平行光源と、光を鏡反射する球3つと床のみで構成。

よく見ると、何度も光が反射することによってできる跡が伺える。(床からの反射がわかりやすい)

図形はこのような配置にしている。

図_srr

注:実際はもっと床が下にある。

おまけ 2方向からの光

test02

3方向
test03

【MMD】くぁいい雪ミクで『好き!雪!本気マジック』

こんちぁ~す、いつもはMMD実写合成上げてる奴です。
今日はちょうど来月がクリスマスということで、すこし道をそれて普通のMMDの動画を作ってみました。

いやー、しつこいですけどこれが無料で作れる世の中ってすごいですね。

では、また。

MMD実写合成~その4~足元を魅せよう

全然関係ない話なんですが、「KCS」でぐぐったときのKCSのページよりも「MMD実写合成」でぐぐったこの記事の方が上位に来てて割かしビックリしてかなり責任感じています。

で、本題です。前回のを見てない方はまずそちらからの方が話の流れがわかりやすいかとこの記事のシリーズ一覧は記事の一番下にあるタグから見れば見れるはずです。

正直なところ前回までは技術的な分野の話は一切しておらず、これからもMMD技術的な話はしないつもりですが、これからは実写合成というテーマの元「どうすれば実写っぽくなるか」という点をみなさんと共有していきたいと思います。まぁ、ほとんどが僕の考えたアイデアとかでなくネットで拾ってきた情報なのですが…。

それで、今回は「足元を魅せよう」というお題で進めます。要は影をだそうってことです。 まずこちらを見比べてください。 小さくて差がわかんないのでクリックで拡大してください。

影なし MME付き影なし影あり MME付き影有り

MMDでも普通の黒い影なら出せますが、このように映ったような感じの影の出力には働く床こと「WorkingFloor」(リンク先でダウンロードできます)を使います。今回もそれを使ってます。

ちょっとあまりに細かいところなのでわかりにくいかもしれませんが、足元を見るとミクの影が写っているのがわかります。右側の方が影があってよりそこにいる感じがあります。 よく考えてみればこれは当たり前のことです。なぜなら「現実の世界になんか影響与えてる」->「現実世界にいる」という思考がめぐるのはどこも不思議でないからです。

実際には今回の写真には影以外にもいろいろ弄ってはいるんですが影以外の特性はどちらも共通です。さらに欲を言えば影をぼかすなどの処理をしたいところですが正直このくらいの濃さだとあまり効果がありません。

MMDではなくてaviutlという動画編集ソフトを使って適当にぼかしてみたのですがaviutlで合成 結果は散々でした。合成するときにいろいろ風合いを損ねてしまったようです。しかも、足元はぼけてるって言うより消えてる。 そんなこんなで自分でも言ってみたところで結局できてないというダメダメ度。

で、今更感が否めませんが、この「足元を魅せる」っていう考え方は別に僕が最初に言い始めた訳がなく、事実多くの方が実写合成をする上で重要と位置付けているようです。

1に影をつける。
2にごまかす。(゚д゚)! です。

ごまかすっていうのはもうどうにもならん時はそもそも足元が映らないように工夫するということです。

bokeboke<これでOKちゃうん?

足元がなければ人間が勝手に妄想してくれるので楽でいいですがちょい構図が制限されます。さらに言うなら、多少なりとも合成画像としての質の上限は足元を入れる場合の方に軍配が上がりそうです。

最後になりましたが、今回使ったMMEのクレジットを込めた紹介をさせていただいて終わりにします。 詳細については後日語りましょうかね?

PanelLitght(http://www.nicovideo.jp/watch/sm19123817)そぼろ様

SSAO(http://www.nicovideo.jp/watch/sm13796840)mqdl様

ExcellentShadow(http://www.nicovideo.jp/watch/sm19123817)そぼろ様

dAdultshader((´・ω・`)改造dAdultsShader 15.ぬる肌 – 新肌質201502CGⅣ) (http://www.nicovideo.jp/watch/sm25514069)ドゥドゥ様

それではまた