吉澤 信
[email protected], 非常勤講師 大妻女子大学 社会情報学部画像情報処理論及び演習II
第10回講義
水曜日1限
教室6218
情報デザイン専攻-動画像処理-基礎、Video Stylization
Shin Yoshizawa: [email protected]
今日の授業内容
1. 連番画像とビデオ.
2. Artistic Stylization ⇒ Video Stylization
3. 演習:DoG画像、DoGビデオ、Artistic Stylization www.riken.jp/brict/Yoshizawa/Lectures/index.html www.riken.jp/brict/Yoshizawa/Lectures/Lec23.pdf 重要:↑は次回レポートの内容なので頑張ってp(^ ^)q +今日作るプログラム(クラス)を次回以降の演習で 使うので必ず来週までに作成してください!
レポート
05は今日〆切です!
レポート0
4の結果を取りに来てください!
動画像の基礎
Shin Yoshizawa: [email protected]
動画像フォーマット:
- ASF(wmv等), AVI, MPEG (mpg,mp4等), DVD,
RealVideo, DviX, Flash(flv), QuickTime, MP4,…
- Animated Gif, multipage TIFF, …
理論/数学的には1次元増えただけ⇒3D画像.
© New Line Productions, Inc.
2D画像 3D画像
3D:横幅、高さ、時間 2D:横幅、高さ
動画像の基礎2
Shin Yoshizawa: [email protected]
講義では複数の2D画像の組で3D画像を扱う.
- 画素
:ピクセル(2D)→ボクセル(3D).
- サイズ
:(sx,sy)→(sx,sy,st).
- 輝度値
:2次元配列→3次元配列.
- ループ
: 2重→3重.
- フレームレート
: 単位時間のフレーム(2D画像)
数、30 frame/sec.等.
…
動画像の基礎3
Shin Yoshizawa: [email protected]
複数2D画像ファイル⇔動画フォーマットの変換: - 符号化方式(ファイルフォーマット)を用いてデータの encode/decodeを行うコーデックが必要. - フリーのソフトを使うのが簡単で良い. - 例えばWinでは、 AVIMaker(bmp→avi)やAviUtl(bmp⇔avi): http://www.vector.co.jp/soft/dl/win95/art/se121264.html http://spring-fragrance.mints.ne.jp/aviutl - http://www.vector.co.jpに色々な動画⇔画像ソフトがあるので、 みんな独自のビデオを連番bmp画像にしてみましょう! - Linuxでは機能が多彩で難しい!画像・動画⇔動画: ffmpeg - 簡単!複数bmp⇔gifアニメ(Linux): convert - 動画へ「convert *.bmp 出力.gif」 - 画像へ「convert 入力.gif 出力.bmp」 番号を揃えたい場合はCのprintfの表記と同じに 「convert 入力.gif 出力%0桁数d.bmp」とする. 例えば3桁なら 「convert 入力.gif 出力%03d.bmp」
Shin Yoshizawa: [email protected]
動画像の配列表現
]; ][ ][ [ double ]; ][ ][ [ int sx sy st I sx sy st Ik
j
} } } ... ] ][ ][ [ ){ ; ; 0 ( ){ ; ; 0 ( ){ ; ; 0 ( k j i I k sx k k for j sy j j for i st i i for ) 0 , 0 , 1 (sx ) 0 , 1 , 1 (sx sy ) 0 , 1 , 0 ( sy 3D画像の配列表現i
) 1 , 1 , 1 (sx sy st ) 1 , 1 , 0 ( sy st ) 1 , 0 , 1 (sx st ) 1 , 0 , 0 ( st ) 0 , 0 , 0 (Shin Yoshizawa: [email protected]
動画像の数式表現
) , , (x y t I z zI(x), x(x,y,t)輝度値の数式表現:
高次元の高さ関数
又は カラー画像:z I(x,y,t)(R(x,y,t),G(x,y,t),B(x,y,t)) 又は zI(x)(R(x),G(x),B(x)), x(x,y,t)Shin Yoshizawa: [email protected]
Image3Dクラスの使い方
使い方は今まで使ってきたSimpleImage.hのImage
クラスとほぼ同じで、一次元増えただけ.
Image3D* 変数名 = new Image3D();
か
Image3D* 変数名 = new Image3D(サイズ);
例えば横500×縦256の画像が120枚あった場合に
3D画像を
Image3D *AAA = new Image3D(500,256,120);とし
for(int i=0;i<AAA->st;i++)
for(int j=0;j<AAA->sy;j++)
for(int k=0;k<AAA->sx;k++)AAA->img[i][j][k]で
輝度値を参照する. カラーの場合は三つのImage3D
使い終わったらdelete AAA;を忘れずに!
Shin Yoshizawa: [email protected]
復習
:Artistic Stylization
©J.Collomosse1 and J. Kyprianidis, EG’11.
アーティストの様式を疑似的に再現して実画像を
生成・編集する事: NPR/計算Photographyの分野.
Shin Yoshizawa: [email protected]
Artistic Video Stylization
2Dの基本フレームワークを3D化してみよう!
エッジ保存平滑化→エッジ抽出→ポスター化(多値化、量子化)→合成.
© New Line Productions, Inc. 動画像へ拡張
スタイル化
Shin Yoshizawa: [email protected]
2Dの基本フレームワーク
入力 平滑化画像 エッジ画像 出力Stylized画像 色相Hの多値化& 明度Vの強調 HSV量子化画像 RGB量子化画像 DoG Bilateral フィルタの 繰り返し RGB の多値化 ポスター化 エッジ抽出復習
:DoG
Shin Yoshizawa: [email protected]
©wikipedia
)
2
exp(
2
1
)
,
(
2 2 2 2
x
y
x
y
g
DoG
: Difference of Gaussian.
)
,
(
)
,
(
)
,
(
,x
y
g
x
y
g
x
y
DoG
K
KDoG2
Shin Yoshizawa: [email protected]
DoG
と入力画像の
畳み込みが負
の領域=エッジ:
, 5 . 0 K2 K3 K4 K5 , 0 . 1 K2 K3 K4 K5復習
:Bilateralフィルタとは?
Input Bilateral Filter Gaussian Filter ) ( ) ) ( ) ( ( ) , (xy g Ix I y g xy Z h , ) , ( / ) ( ) , ( ) ( new
xy y y xy y x Z I d Z d ISpatial-Tonal Normalized Convolution:
) ( ) , (xy g xy Z . ) ( 2 2 a r ar e g Intensity (Tonal)
Kernel Spatial Kernel
エッジ特徴を保存する!
Shin Yoshizawa: [email protected]
Bilateralフィルタの繰り返し適用
Shin Yoshizawa: [email protected]
入力 1回 2回 3回 1 . 0 , 0 . 25 h ×輝度値の標準偏差
エッジ保存平滑フィルタを繰り返し適用するとエッ
ジに沿った領域が断片化される(領域抽出効果):
) ( ) ) ( ) ( ( ) , (xy g IxIy g xy Z h () 2. 2 a r a r e g , ) , ( / ) ( ) , ( ) ( new
xy y y xy y x Z I d Z d IDoG+Bilateralフィルタ
Shin Yoshizawa: [email protected]
, 5 . 0 K2 K3 K4 K5
Bilateralフィルタを繰り返し適用後にDoGを適用:
上:入力画像にDoG: 下:Bilateralフィルタ3回適用後にDoG:DoG+Bilateralフィルタ
Shin Yoshizawa: [email protected]
, 5 . 0 K2 K3 K4 K5
Bilateralフィルタ後の画像と合成すると…
上:入力画像にDoG: 下:Bilateralフィルタ3回適用後にDoG:ポスター化
Shin Yoshizawa: [email protected]
多値化で量子化する事でポスター化:
- RGB毎に多値化すると色が混ざる.
- HSV空間の色相(H)で多値化し明度(V)を強調.
ポスター化2
Shin Yoshizawa: [email protected]
HSV空間の色相(H)で多値化し明度(V)を強調.
色相を16段階の値へ量子化+明度を強調.
ポスター化3
Shin Yoshizawa: [email protected]
HSV空間の色相(H)で多値化し明度(V)を強調.
色相を16段階の値へ量子化+明度を強調 +RGB毎に4段階に多値化. RGB毎の混 色で鏡面的 効果を演出.今週はVideoへのDoG拡張
Shin Yoshizawa: [email protected]
入力 平滑化画像 エッジ画像 出力Stylized画像 色相Hの多値化& 明度Vの強調 HSV量子化画像 RGB量子化画像 DoG Bilateral フィルタの 繰り返し RGB の多値化 ポスター化 エッジ抽出
今日
来週
最終的にEx15.zipの Style.cxxのビデオへ の拡張を作成.DoGの3D拡張
Shin Yoshizawa: [email protected]
)
2
2
exp(
2
1
2
1
)
,
,
(
2 2 22 22 ,h
t
y
x
h
t
y
x
g
h
そのままの拡張は時空間エッジになるので
Artistic Stylizationでは工夫が必要:
- 注意点:時間方向のパラメータhは空間と分けなけれ ばダメ、時間方向の畳み込み半径も同様.)
,
,
(
)
,
,
(
)
,
,
(
, , , ,x
y
t
g
x
y
t
g
x
y
t
DoG
Kh
h
KKhDoGの3D拡張2
Shin Yoshizawa: [email protected]
© New Line Productions, Inc.
DoGの3D拡張3
Shin Yoshizawa: [email protected]
© New Line Productions, Inc.
ストーリー展開 の描写はOKだ が単純に重ねる とあまり良くない.
DoGの3D拡張4
Shin Yoshizawa: [email protected]
2D空間DoGを時間方向に平滑化し、残像効果:
- 注意点:レポートでは講義で紹介した時間方向の拡張 の仕方以外でもデザインしてOK. ) 2 exp( 2 1 ) , ( 2 2 2 2 y x y x g ))
,
(
)
,
(
)(
(
)
,
,
(
, ,x
y
t
g
t
g
x
y
g
x
y
DoG
Kh
h
K 2 2 2 exp 2 1 ) ( h t h t gh DoGの3D拡張5
Shin Yoshizawa: [email protected]
© New Line Productions, Inc.
DoGの3D拡張6
Shin Yoshizawa: [email protected]
© New Line Productions, Inc.
DoGの3D拡張7
Shin Yoshizawa: [email protected]
© New Line Productions, Inc.
レポートでは時間方向拡張の仕方をデザインしてOK. ただし狙ったデザインの目的と使った数式を明記する事. パラメータの調節が必要.
Shin Yoshizawa: [email protected]
演習:DoG画像、DoGビデオ
www.riken.jp/brict/Yoshizawa/Lectures/index.html www.riken.jp/brict/Yoshizawa/Lectures/Lec23.pdfwww.riken.jp/brict/Yoshizawa/Lectures/Ex15.zip
1.Ex15内のプログラムを動かしてみる.
2.DoGビデオプログラムの作成.
Shin Yoshizawa: [email protected]
演習:Ex23-1
Ex15.zip内でmakeでコンパイルし、testVideoIO.cxx、 DoGEdge.cxx、DoGEdge2.cxx、Style.cxxを動かしてみる. 連番画像の入出力: VideoIO.h
void OpenVideo(char *入力フォルダー名, Image3D *R, Image3D *G, Image3D *B, int *sx, int *sy, int *st); void SaveVideo(char *出力フォルダー名, char * 出力 ファイル名, Image3D *R, Image3D *G, Image3D *B); DoGEdge.cxx: DoGによるエッジ画像の作成: 引数3. ./DoGEdge 畳み込み半径(int) DoG標準偏差(double) DoGバンド幅(double) 「./DoGEdge lena.bmp ex22_1_1.bmp 10 0.5 2」、 「./DoGEdge lena.bmp ex22_1_2.bmp 10 0.5 3」、 「./DoGEdge lena.bmp ex22_1_3.bmp 10 0.5 4」、
Shin Yoshizawa: [email protected]
演習:Ex23-1
DoGEdge2.cxx: DoGエッジと元画像の合成(引数3, DoGEdgeと同じ): DoGEdgeと同じパラメータで出力ファイ ル名を変えて実行してみましょう!
Style.cxx: Artistic Stylization画像の作成(引数11). ./Style 畳み込み半径(int) DoG標準偏差(double) DoGバンド幅(double) Bilateralフィ ルタ空間標準偏差(double) Bilateralフィルタ輝度標準偏差(double) Bilateralフィルタ 繰り返し回数(int) HSV量子化数(int) HSV量子化V強調パラメータ(double) RGB量子 化数(int)
「./Style lena.bmp ex22_st_1.bmp 0 0.5 3.0 25.0 0.1 3 16 0.7 4」と 「./Style lena.bmp ex22_st_1.bmp 10 0.5 5.0 25.0 0.1 3 16 0.7 4」で実行 してみましょう!
自分の画像でDoGEdge.cxxとStyle.cxxをパラメータを調 節してスタイリッシュな画像にしてみてください.
Shin Yoshizawa: [email protected]
演習:
Ex23-2
DoGVideoEdge.cxxとDoGVideoEdge2.cxxを編集し、連番 画像のDoGエッジ動画を作成するプログラムを完成せよ. ヒント:ファイル内のコメントとDoGEdge.cxxをよく見てみて ください. ) 2 exp( 2 1 ) , ( 2 2 2 2 xy x y g 2 2 2 exp 2 1 ) ( h t h t gh ))
,
(
)
,
(
)(
(
)
,
,
(
, ,x
y
t
g
t
g
x
y
g
x
y
DoG
Kh
h
K ↑と同じでもOK、自分独自の 拡張でもOK、ただし単純拡張 はダメ. ↑は⇒の様に残像だけなので、 評価時刻でのDoGエッジも出る ようにデザインすると高得点!Shin Yoshizawa: [email protected]
来週の予定
動画像処理その2(12/19).
Shin Yoshizawa: [email protected]
参考資料:
Image3Dクラス
Shin Yoshizawa: [email protected]
3D画像クラスの作成
www.riken.jp/brict/Yoshizawa/Lectures/Ex14.zip
3D画像クラス: Image3DクラスをSimpleImage3D.h
というヘッダーファイル名で作ってみる.
必要なクラスの
メンバー/メソッド
:
- 画像サイズ(int)で三つsx,sy,st. - 輝度値を格納するためのdoubleの3重ポインター. - コンストラクター二つ: - 引数無: サイズにゼロ、輝度値のポインターに NULLを代入する. - 引数画像サイズ: 輝度値の3重ポインターのメモ リを確保して3次元配列にする. - デストラクター:クラスがdeleteしたとき輝度値の3次元 配列をdeleteする.Shin Yoshizawa: [email protected]
C++クラスの基礎
class クラス名{
/* 設計図の様なものでクラス=新しい型 */public:
/* パブリックの場合は、クラスの外から参照可能 */メンバー変数
/* クラスが持っている変数、構造体、クラス内クラス */クラス名(){
/* コンストラクター:newされたときに呼ばれる. */}
クラス名(引数){}
/* コンストラクターは複数あってよい */~クラス名(){
/* デストラクター:delete されたときに呼ばれる. */}
戻り値 メソッド名(引数){}
/* メソッドを作れる= */private:
/* プライベートの場合は、クラスの外から参照不可 */};
Shin Yoshizawa: [email protected]
多重ポインターから多次元配列を作る方法
1重ポインターから1次元配列を作る方法:
double *A = new double[N];
これで、A[0], A[1], …A[N-1]まで配列として使える.
- 使い終わったらメモリの開放が必要:
delete [] AAA;
2重ポインターから2次元配列を作る方法:
double **A = new double *[N];
for(int i=0;i<N;i++)A[i] = new double[M];
これで、A[0][0], A[0][1], …A[0][M-1], A[1][0],
A[1][1],…A[N-1][M-1]まで配列として使える.
- 使い終わったらメモリの開放が必要:
for(int i=0;i<N;i++) delete [] A[i];
delete [] A;
Shin Yoshizawa: [email protected]
多重ポインターから多次元配列を作る方法2
3重ポインターから3次元配列を作る方法:
double ***A = new double **[st];
for(int i=0;i<st;i++){
A[i] = new double *[sy];
for(int j=0;j<sy;j++)A[i][j] = new double[sx];
}
これで、A[0][0][0], A[0][0][1], …A[0][0][sx-1], A[0][1][0], A[0][1][1], …A[0][sy-1][sx-1], A[1][0][0], A[1][0][1],…A[st-1][sy-1][sx-1]まで 配列として使える. 同様にメモリの開放は以下:
for(int i=0;i<st;i++){
for(int j=0;j<sy;j++) delete [] A[i][j]; delete [] A[i];
}
delete [] A;
連番画像の入出力へ向けて
Shin Yoshizawa: [email protected]
]; ][ ][ [ double ]; ][ ][ [ int sx sy st I sx sy st I
k
j
} ){ ; ; 0 (i isti for ) 0 , 0 , 1 (sx ) 0 , 1 , 1 (sx sy ) 0 , 1 , 0 ( sy 3D画像の配列表現i
) 1 , 1 , 1 (sx sy st ) 1 , 1 , 0 ( sy st ) 1 , 0 , 1 (sx st ) 1 , 0 , 0 ( st ) 0 , 0 , 0 (© New Line Productions, Inc.
1. BMPIOで一枚づつテンポ ラリーの 2D画像を開く. 2. 3D画像のi番目にコピー.
Shin Yoshizawa: [email protected]
連番画像名の取得方法
Ex14.zip内のImageSetIO.cxxを開いてください.入
力としてフォルダー名を与えて、その中のBMPファ
イルをファイル名順にソートしたファイル名のリスト
を得るプログラムです.
今回の演習でやる方法は、
ステップ1:Linux/UnixコマンドのlsとgrepをC/C++からシ ステムコール関数system()を使って、与えられたフォル ダー名内のBMP画像ファイル名(複数)をテンポラリーの ファイル(tmp_img_file_names.txt)に書き出す. - system()はstdlib.hが必要. - system(char*)で引数に書いたLinuxコマンドを実行 出来る. 例:system(“ls”);Shin Yoshizawa: [email protected]
連番画像名の取得方法2
今回は以下のコマンドを用いる: ”ls 入力フォルダー名 | grep .bmp > 出力ファイル名” ここで|と>はそれぞれ、パイプとリダイレクトと呼ばれてコ マンドの結合とファイルへの出力を行える: - 「ls AAA」 AAA内のファイル名・フォルダー名を出力 する.- 「grep AAA BBB」 BBBの中からAAAがある行を抜 き出す. - 「AAA | BBB」 AAAの結果をBBBに渡す. - 「AAA > BBB」 AAAの結果をBBBに書き出す. - sprintf(格納先,printfの表記,変数)でコマンド内にメ インの引数やテンポラリーファイル名をプリント. 与えられたフォルダー名内のlsの結果から.bmpが付いている ファイル名だけ抽出して出力ファイルに書き出すコマンド.
Shin Yoshizawa: [email protected]
連番画像名の取得方法3
ステップ2:テンポラリーのファイル (tmp_img_file_names.txt)を開いて、一行づつfscanf()で呼 び込み、vector<char *>へ格納する: - FILE *fp = fopen(ファイル名,”r”);で開いたファイル ポインターfpを使ってfscanf(fp,”%s”,格納先)の戻り 値がEOFでない間、繰り返しスキャンする. - vectorを使うには#include<vector>が必要. - vector<char *>へ代入するためにchar *をnewしてfscanf()の結果をコピーする.
- .push_back()メソッドを使ってvectorへ格納する. 格納後はvectorなので配列の様に使える. 例えば、vector <char *> AAA;ならAAA[0]に最初のファイル名がchar *で 入っており、以下AAA[1], AAA[2]と使える. サイズ(push_back した回数=ファイル名の数)は AAA.size()で得られる.
Shin Yoshizawa: [email protected]
連番画像名の取得方法4
ステップ3:std::sortを使ってvector<char *>に格納した ファイル名をソートする. 例えばvector <char *> AAA;な らstd::sort(AAA.begin(),AAA.end());でソートされる. - std::sortは#include<algorithm>が必要. ステップ4:ソート後は、vector<char *>を配列の様に使い ファイル名の操作を行い、実際の処理をする. - ImageSetIO.cxxは連番名の取得だけなので、実際 の処理は無いが、演習ではVideoIO.cxxでソート後 のファイル名を順番に開いて3D画像クラスに格納 する. BMPIO.hを使って2D毎に入出力をファイル名 の数だけ行う. ステップ5:new したchar *のメモリを解放する. 例えば、 for(i=0;i<AAA.size();i++)delete [] AAA[i];
Shin Yoshizawa: [email protected]