• 検索結果がありません。

2 2.1 ( ) >> x=linspace(255,0,12) 2 x =

N/A
N/A
Protected

Academic year: 2021

シェア "2 2.1 ( ) >> x=linspace(255,0,12) 2 x ="

Copied!
15
0
0

読み込み中.... (全文を見る)

全文

(1)

2

簡単な画像処理

2.1

画 像 の 構 造

画像も音と同じようにコンピュータの中では数字の組で表現される。まず、 簡単な例として、白黒画像(グレイスケール画像)の例を見てみる。 実行例2.1 ✓ ✏ 1 >> x=linspace(255,0,12) 2 x = 3 1 列から 5 列 4 255.0000 231.8182 208.6364 185.4545 162.2727 5 6 列から 10 列 6 139.0909 115.9091 92.7273 69.5455 46.3636 7 11 列から 12 列 8 23.1818 0 9 >> x=uint8(x) 10 x = 11 1× 12 の uint8 行ベクトル 12 1 列から 9 列 13 255 232 209 185 162 139 116 93 70 14 10 列から 12 列 15 46 23 0 16 >> I=reshape(x,[3 4]) 17 I = 18 3× 4 の uint8 行列 19 255 185 116 46 20 232 162 93 23 21 209 139 70 0 22 >> imtool(I,’InitialMagnification’,’fit’) ✒ ✑

(2)

2.1 画 像 の 構 造 19 1行目のlinspaceは、起点と終点を指定して、その間に指定した個数の等 間隔の点からなる配列(ベクトル)を生成する。ここでは、255 から0 までの 12点を生成している。9行目では、元のfloat型の値を8ビットの符号なしの 整数(0から255)に変換している。16行目のreshapeは、配列の形状を変更 する関数である。それを用いて配列を3× 4の行列(2次元配列)に整形してい る。19行目の出力結果からわかるように、行列の成分表示と同じように整形さ れる。22行目で画像を表示している。 この画像は、12個の画素から構成される。実際の画素は非常に小さいので、 ディスプレイ上では、実寸で表示すると見えないくらい小さい。しかし、画像 を表示するアプリケーションimtoolでは、InitialMagnificationという パラメータをfitに設定すると、画像を表示用のウィンドウの大きさに拡大・ 縮小して表示する。この例の場合は、実際の画素よりはるかに大きく表示され る。実際には、左上隅の白い部分は画素一つ分であり、その座標は(1, 1)であ り、その右横のグレイの領域の座標は(2, 1) である。 imtoolでは、マウス位置の画素の座標とその値がウィンドウ下部に表示され る。この例の画像はグレイスケール画像と呼ばれ、画素の値が大きいほどその 画素は明るくなり、小さいほど暗くなる。MATLABの画像では、画素の座標 配置は行列の添字と同じで、左上が(1, 1)となり、その下は(2, 1),右は(1, 2) となる。 画像の大きさは、横方向の画素数を幅(width)とよび、縦方向の画素数を高 さ(height)とよぶ。この例では、幅が4で高さが3 である。

RGBとよばれるカラー画像では、画素は赤、緑、青(Red, Green, Blue,略

してRGB)の3つの値の組(ベクトル)で表現される。 プログラム2-1 (様々な色の生成) 1 >> bar1=uint8(255*ones(500,100)); 2 >> bar0=zeros(500,100); 3 >> Col(:,:,1)=repmat([repmat(bar1,1,2) repmat(bar0,1,2)],1,2); 4 >> Col(:,:,2)=[repmat(bar1,1,4) repmat(bar0,1,4)]; 5 >> Col(:,:,3)=repmat([bar1 bar0],1,4);

(3)

6 >> imtool(Col) 左から「白」「黄」「シアン」「緑」「マゼンタ」「赤」「青」「黒」の帯が生成さ れる。MATLABでは、Col(:,:,1) のように、3つの添字を持つ配列で3次 元配列をあらわす。この例の場合、Colは、500× 800の2次元配列3つから 構成される。それぞれの配列は、プレーン、バンドなどとよばれる。 MATLABでは、この例のように配列の要素を指定する部分に:を書いた場 合は全ての要素を表わす。Col(:,:,1)は、C(1:end,1:end,1)と同じで全て の要素を指定したことになる。MATLABでは、このように添字をベクトルや 行列にすることができる。RGB画像では、3次元配列の最初のバンドが赤、次 が緑、最後が青に対応する。そのことは、表示された画像の赤の部分でマウス ボタンを押しながら少し動かしてみて、画素の値を表示させると[255,0,0] と 表示されることでわかる。 1行目のones、2行目のzerosは配列を1や0で初期化するために使われ る。引数で作成する配列のサイズを指定する。 実行例2.2 ✓ ✏ >> zeros(2) ans = 0 0 0 0 >> ones(2,1) ans = 1 1 >> ones(1,2,3) ans(:,:,1) = 1 1 ans(:,:,2) = 1 1 ans(:,:,3) = 1 1 ✒ ✑ プログラム2-1の3行目のrepmatは、行列を繰り返して大きな行列を作成

(4)

2.1 画 像 の 構 造 21 する関数である。 実行例2.3 ✓ ✏ 1 >> x1=[1;2] 2 x1 = 3 1 4 2 5 >> size(x1) 6 ans = 7 2 1 8 >> repmat(x1,1,2) 9 ans = 10 1 1 11 2 2 12 >> repmat(x1,2,1) 13 ans = 14 1 15 2 16 1 17 2 18 >> repmat(x1,2,2) 19 ans = 20 1 1 21 2 2 22 1 1 23 2 2 ✒ ✑ 1行目で作成しているx1は2行1列の行列である。repmatは行列を第1引 数に指定し、その行列を縦(行方向)に第2引数の回数、横(列方向)に第3引 数の回数だけ繰り返した行列を作成する。8行目ではx1を行方向に1回、列 方向に2回、つまり列方向に2回繰り返している。 プログラム2-1の3行目では、[]を用いて行列を列方向に並べている。

(5)

実行例2.4 ✓ ✏ 1 >> x2=[1 2; 3 4] 2 x2 = 3 1 2 4 3 4 5 >> [x2 x2] 6 ans = 7 1 2 1 2 8 3 4 3 4 9 >> [x2; x2] 10 ans = 11 1 2 12 3 4 13 1 2 14 3 4 ✒ ✑ []は、9行目のように、;と併用すると行方向に並べることもできる。

2.2

画像・ビデオの読込

MATLABでは、次のようにして画像を読み込む。 実行例2.5 ✓ ✏ >> I=imread(’peppers.png’); >> imtool(I,’InitialMagnification’,’fit’) ✒ ✑ この画像の大きさは、size関数で調べられる。 実行例2.6 ✓ ✏ >> sz=size(I) sz = 384 512 3 ✒ ✑ size関数は多次元の場合、行方向、列方向、次の次元· · · の順にそれぞれの 次元の大きさを並べた配列を返却する。この出力から、高さが384、幅が512、 バンド数が3 であることがわかる。

(6)

2.2 画像・ビデオの読込 23 MATLABでは、画像の一部を切り出す方法はいくつかある。一番簡単なの は、imtoolで対話的に切り出す方法である。 実行例2.7 ✓ ✏ 1 >> I=imread(’peppers.png’); 2 >> hI=imtool(I,’InitialMagnification’,’fit’); 3 >> [CI,rect]=imcrop(hI); 4 >> imtool(CI,’InitialMagnification’,’fit’); 5 >> rect rect = 181.5100 73.5100 84.9800 62.9800 6 >> CI2=imcrop(I,rect); 7 >> imwrite(CI,’cropped_image.png’); ✒ ✑ 3行目を実行すると、マウスポインタが十字になる。この状態で切り出した い長方形の左上の位置にポインタを置き、左クリックしてドラッグしながら領 域を指定する。領域を指定したら、右クリックするとポップアップメニューが 表示される。メニューから「イメージのトリミング」を選択すると3行目の切 り出し処理が終了する。4行目で切り出された画像が確認できる。5行目では、 切り出した領域の情報を確認している。切り出す長方形の座標がわかっている 場合には、imcropを用いて切り出せる。6行目がその例である。CI2はCIと 同じ画像になる。7行目では、切り出した画像をファイルに保存している。パ スを指定しない場合は、MATLABの「現在のフォルダ」で表示されているフォ ルダに保存される。 同じサイズの画像であれば簡単に足し合わせることができる。

(7)

実行例2.8 ✓ ✏ 1 >> C1=imread(’greens.jpg’); 2 >> sz1=size(C1) sz1 = 300 500 3 3 >> C2=imread(’football.jpg’); 4 >> sz2=size(C2) sz2 = 256 320 3 5 >> C1c=imcrop(C1,[1 1 319 255]); 6 >> Cm=uint8(0.5*C1c+0.5*C2); 7 >> imtool(Cm) ✒ ✑ 5行目はimcropの別の用法である。helpなどで確認すること。ここでは、 小さい画像C2に大きさをあわせるように切り出している。6行目で混合比 0.5 ずつで足し合わしている。混合された画像が確認できる。 ビデオファイルも読み込むことができる。ビデオファイルはフレームとよば れる画像データが連続して構成される。例えば、テレビであれば、1秒分が30 フレームで構成される。

(8)

2.2 画像・ビデオの読込 25 実行例2.9 ✓ ✏ 1 >> v=VideoReader(’636795321.m4v’) 2 v = 3 VideoReader のプロパティ: 4 一般的なプロパティ: 5 Name: ’636795321.m4v’ 6 Path: (保存したフォルダによって変わる) 7 Duration: 60.0400 8 CurrentTime: 0 9 Tag: ’’ 10 UserData: [] 11 ビデオ プロパティ: 12 Width: 640 13 Height: 360 14 FrameRate: 25 15 BitsPerPixel: 24 16 VideoFormat: ’RGB24’ 17 >> h=v.Height; 18 >> w=v.Width; 19 >> s=struct(’cdata’,zeros(h,w,3,’uint8’),’colormap’,[]); 20 >> k=1; 21 >> while hasFrame(v) 22 s(k).cdata=readFrame(v); 23 k=k+1; 24 end 25 >> implay(s) 26 >> imtool(s(1).cdata,’InitialMagnification’,’fit’) 27 >> imtool(s(37).cdata,’InitialMagnification’,’fit’) ✒ ✑ まずビデオファイルを読込むのに必要なVideoReaderオブジェクトを作成 する(1行目)。オブジェクトとは、関連したデータや関数をまとめられるよう な機構である。オブジェクトは関連したデータをプロパティと呼ばれる機構で 格納する。例えば、FrameRateというプロパティは1秒間あたり何フレームな のかを示している。プロパティは、2行目のように.によってアクセスできる。 sは、関連するデータをグループとしてまとめられる構造体とよばれるデータ構 造である。h,wはそれぞれビデオの画像の高さと幅である。sはMATLAB内で 特別にビデオデータ用に用意されたムービー構造体であり、cdataとcolormap というフィールドを持つ。フィールドも.でアクセスできる。cdataは、高さ

(9)

h、幅wのRGB画像用のフィールドである。colormapは、RGB画像の場合 指定する必要はない。readFrameは、VideoReaderから1フレームずつ読み 込む関数である。hasFrameはフレームが読み込める間は1を返す関数である。 implayはビデオを再生する関数である。それぞれのフレームは画像を含んで おり、26行目は1番目、27行目は 37番目のフレームの画像を表示している。 似た画像の異なる点を簡単に調べる方法に画像どうしの差分を計算する方法 がある。二つの画像の画素値をI, Jとすると、 |I − J| (2.1) を計算すればよい。ただし、uint8では、減算が通常の(符号あり)整数とは異 なるので注意しないといけない。 実行例2.10 ✓ ✏ >> a=uint8(10); >> b=uint8(16); >> a-b ans = uint8 0 ✒ ✑ このようにuint8では負の数が全て0となる。したがって、 |I − J| = (I − J) + (JーI) (2.2) と計算しなければならない。

2.3

領 域 の 抽 出

長方形などの形で切り出すのではなく、画像の中から必要な部分(領域)を抜 き出すことを考えてみる。

(10)

2.3 領 域 の 抽 出 27 実行例2.11 ✓ ✏ >> I=imread(’eight.tif’); >> imtool(I,’InitialMagnification’,’fit’) ✒ ✑ このようなグレイスケール画像の場合、明るさに着目して領域を指定できる場 合がある。マウスを使って画素の値を確認すると、背景部分は220以上の値で あると推測できる。 画像を0 と1 の二つの値しか持たない画像に変換することを2値化とよぶ。 2値化した画像の0の画素を抽出したくない画素とし、その部分を隠すように して領域を指定するものをバイナリマスクと呼ぶ。MATLABでは、画像と同 じ大きさの2次元配列を用意し、抽出したい画素を1、抽出したくない画素を 0 とするバイナリマスクが使いやすい。コインの部分を抽出するプログラムを 次に示す。 プログラム2-2 1 >> BW=zeros(size(I)); 2 >> BW(I<220)=1; 3 >> C=I; 4 >> C(BW==0)=0; 5 >> imtool(C,’InitialMagnification’,’fit’) 1行目で対象となる画像と同じサイズの2次元配列を 全ての要素が0 になる ように作成している。2行目は MATLABの「論理インデクス」という行列の 要素へのアクセス方法を利用している。 論理インデクスについて説明する。

(11)

実行例2.12 ✓ ✏ 1 >> A=1:5 2 A = 3 1 2 3 4 5 4 >> I=mod(A,2)==1 5 I = 6 1× 5 の logical 配列 7 1 0 1 0 1 8 >> A(I) 9 ans = 10 1 3 5 11 >> A(I)=0 12 A = 13 0 2 0 4 0 ✒ ✑ まず、1行目で配列Aを作成している。MATLABでは、配列に対し、何らか の判断をするとその判断結果の配列を得られる。4行目では、2で割った余りが 1になる、つまり奇数であるかどうかを判断している。その結果、奇数である 要素が1 (真, true)であり、残りは0 (偽, false)である配列Iが得られる。8 行目のように、このIをインデクスとして用いると真の部分の値、つまり奇数 だけを取り出せる。また、この記法は、11行目のように式の左辺にも使うこと ができる。式の左辺に使った場合には、真の要素にだけ代入される。 つまり、プログラム2-2の4行目では、IをコピーしたCという画像に対し、 バイナリマスクBWの値が 0である画素に0を代入している。これにより、抽 出したくない部分(背景)を黒くしてコインの領域を抽出している。この抽出の 判断に用いた値をしきい値とよぶ。このしきい値では、コインのまわりの影の 部分も抽出されてしまっている。一方、コインの模様が光っている部分が背景 に誤ってしまっていることもわかる。 色に関するしきい値による抽出例を示す。 プログラム2-3 >> I=imread(’football.jpg’); >> imtool(I,’InitialMagnification’,’fit’) >> BW=ones(size(I,1),size(I,2)); >> BW(I(:,:,1)>11&I(:,:,1)<60& I(:,:,2)>11&I(:,:,2)<140& ...

(12)

2.3 領 域 の 抽 出 29 I(:,:,3)>15&I(:,:,3)<154)=0; >> M=repmat(BW,[1 1 3]); >> C=I; >> C(M==0)=0; >> imtool(C,’InitialMagnification’,’fit’) このプログラムでは、ボールを抽出している。4行目で抽出する条件を判断 している。この画像の場合、背景の方が条件を指定しやすそうなので、背景の 青い部分に関する条件で判断している。ここでは、ある画素の値を(r, g, b)と したときに、次式を同時に満たした場合は背景である(背景の青色である)とい う条件を判断している。 11 < r < 60, 11 < g < 140, 15 < b < 154 (2.3) 結果を見ると、ボールがおおむね上手く抽出できていることがわかる。 6行目はマスクを多次元配列に対応できるようにコピーしている。関数repmat は、第1引数で指定した行列をコピーして繰り返す関数である。第2引数でどの ように繰り返すかを指定する。第2引数の配列は、配列の次元に対応する。つま り、最初が行方向、2つ目が列方向、というようになる。この例では、[1 1 3] なので、2次元配列のBWを3 回繰り返して3次元配列にしている。 MATLABでも、一連の処理は関数としてまとめると便利である。プログラ ム2-2のグレイスケール画像の明るさの範囲を指定してその領域に関するマス クを返す関数を書いてみる。 MATLABで自作の関数を作成するには、「ファイル」タブから「新規作成」 のプルダウンメニューから「関数」を選択してエディタを起動する。関数のテ ンプレートが表示されるので、次のように編集する。 プログラム2-4 (マスク生成関数) 1 function M = createGrayMask( I, R ) 2 %createRGBMask RGB の範囲指定によるマスク作成

3 % M = createGrayMask(I, [min max]), RGB画像

4 % I に関して、明るさの範囲を指定して、それを満たす画素を 1 と

5 % するマスクを M に生成する。

(13)

7 M=zeros(size(I,1),size(I,2)); 8 M(I(:,:,1)>R(1)&I(:,:,1)<R(2))=1; 9 end 1行目が関数名や引数の定義である。この例のMやRのように、行列や配列 をそのまま引数や返り値に指定できる。2行目 から5行目は、コメントである。 この部分にコメントを書くと、help関数を用いて表示できる。7行目のように 関数の本体で返り値に代入することで、返り値を生成できる。 画素はたくさんあるため調べるのに手間がかかる。手間を省く方法としては、 同じ色の領域を指定して、その領域の画素の値の範囲を調べる方法がある。領 域を長方形に切り出すのであれば、実行例2.7のようにimcropを用いるのが 簡単である。 実行例2.7と同じように長方形の領域CI切り出したとする。MATLABには 配列の最大値を求める関数maxと最小値を求める関数minがある。 実行例2.13 ✓ ✏ >> A=randi(10,[1 5]) A = 6 10 1 5 2 >> v=max(A) v = 10 ✒ ✑ randiは整数の乱数を生成する関数である。この例の場合は、10以下の整数 の乱数からなる1× 5行列を生成している。(乱数なので、試すたびに値は変わ ることに注意) maxは多次元配列にも対応している。2次元配列の最大値を求めるには次の ようにする。

(14)

章 末 問 題 31 実行例2.14 ✓ ✏ 1 >> A=randi(10,[3 4]) 2 A = 3 10 9 4 5 4 1 9 3 10 5 8 1 9 2 6 >> max(A) 7 ans = 8 10 9 9 10 9 >> max(max(A)) 10 ans = 11 10 ✒ ✑ 6行目の例でわかるように2次元配列に対しては、ある次元の方向について の最大値を返す。次元を指定しない場合は、第1次元は行の方向なので、列ご との最大値からなる1次元配列が返されている。9行目では、その1次元配列 の最大値、つまり、2次元配列Aの最大要素が返される。

章 末 問 題

【1】 高さ、幅が100となる黒い正方形のグレイスケール画像を生成せよ。 【2】 高さ、幅が100となる赤い正方形のカラー画像を生成せよ。 【3】 二色の正方形を交互に配置した模様を市松模様とよぶ。縦、横に5つずつの正 方形からなる白黒の市松模様をグレイスケール画像として生成せよ。市松模様 のサイズは、高さ、幅が250となるようにせよ。 図 2.1 市松模様 【4】 【3】と同じサイズの青と赤の市松模様をカラー画像として生成せよ。 【5】 【3】と同じサイズのシアンとマゼンタの市松模様をカラー画像として生成せよ。 【6】 自分の好みの色の適当な模様を生成せよ。 【7】 適当な画像を混合比(0.2, 0.8), (0.5, 0.5), (0.7, 0.3)で混合した画像を作成せよ。

(15)

【8】 同じフレームレート、同じサイズのビデオV1,V2をなめらかにつなぐ方法を考 える。例えば342960254.m4vと343025947.m4vは同じフレームレート、同 じサイズである。V1,V2は ムービー構造体配列だとする。フレームレートを fpsだとする。 ここでは、V1の最後のNフレームの画像とV2の最初のNフレームの画像 を徐々に混合比を変化させて混合することでなめらかにつないだムービー構造 体配列を VMixとする。プログラム 2-5をもとにこのようなプログラムを作 成せよ。 プログラム2-5 (ビデオの接続) VMix=V1(1:end-N); VMix(length(V1)+1:length(V1)+length(V2)-N)=V2(N+1:end); for k=1:N VMix(length(V1)-N+k).cdata=uint8(V1(length(V1)-N+k).cdata ... * _______ + V2(_______).cdata*____________); end implay(VMix,fps); 【9】 人間の顔が写っている適当な画像を探し、肌色の領域を抽出せよ。 【10】 固定カメラで撮影したビデオは、近傍の2フレームの差分を用いてバイナリマ スクを作成することで変化する領域(移動する物体)を抽出することができる。 連続するフレームを利用する場合を考える。k番目のフレームの画像に対する バイナリマスクは、k番目のフレームの画像とk− 1番目のフレームの画像の 差分を用いて推定されるバイナリマスクとk番目のフレームの画像とk + 1番 目のフレームの画像の差分を用いて推定されるバイナリマスクの画素ごとの論 理積で推定できる。 viptraffic.aviからフレームごとにバイナリマスクを推定し、そのマスク を用いて抽出した領域からなるビデオを作成せよ。

参照

関連したドキュメント

7   European Consortium of Earthquake Shaking Tables, Innovative Seismic Design Concepts f or New and Existing Structures; ”Seismic Actions”, Report No.. Newmark, &#34;Current Trend

More general problem of evaluation of higher derivatives of Bessel and Macdonald functions of arbitrary order has been solved by Brychkov in [7].. However, much more

Remarkably, one ends up with a (not necessarily periodic) 1D potential of the form v(x) = W (x) 2 + W 0 (x) in several different fields of Physics, as in supersymmetric

the log scheme obtained by equipping the diagonal divisor X ⊆ X 2 (which is the restriction of the (1-)morphism M g,[r]+1 → M g,[r]+2 obtained by gluing the tautological family

Keywords Catalyst, reactant, measure-valued branching, interactive branching, state-dependent branch- ing, two-dimensional process, absolute continuity, self-similarity,

In Subsection 5.1 we show the continuity of the Dirichlet heat kernel associated with the killed LBM on a bounded open set by using its eigenfunction expansion, and in Subsection 5.2

Taking care of all above mentioned dates we want to create a discrete model of the evolution in time of the forest.. We denote by x 0 1 , x 0 2 and x 0 3 the initial number of

F rom the point of view of analysis of turbulent kineti energy models the result.. presented in this paper an be onsidered as a natural ontinuation of