Processing 画像処理演習

講義科目「画像工学」では画像処理の演習課題として、プログラミング言語 Processing を用いてプログラムの作成を行います。ここでは、参考となる基礎的な画像処理プログラムを記載します。

このプログラムについて

Processing version 3.3 で動作確認している。画像ファイルは自分で用意せよ。
プログラムの解説は講義の配付テキストを参照せよ。

変数宣言,型変換,文字出力

解説
整数型変数の宣言には int、実数型変数の宣言には float を使う。整数を実数型(float型)変数に代入することはできるが、実数を整数型(int型)変数に代入することはできない(この点がC言語などと異なるので注意せよ)。ただし、小数点以下を切り捨てて整数値に変換する int( ) 関数を用いれば整数型変数に代入できる(10行目)。
コンソールへの文字出力には println( ) 関数を用いる。出力したい数値、変数、文字列を「,」で区切って並べる(C言語のように書式を記述する必要はない)。文字列を出力する場合は文字列全体を「”」で括る。
コンソールに値や文字を表示する。

画像ファイルの読み込みと表示

解説
画像オブジェクトの宣言には PImage クラスを使う。このプログラムでは、画像オブジェクト名を f としている。
画像ファイルの読み込みは loadImage( ) 関数を使う。画像ファイルは、ソースコードが保存されているフォルダの中の data フォルダの中に格納しておかなければならない。Processing のメニューの「スケッチ → ファイルを追加…」で data フォルダの作成とファイルのコピーが行えるので利用するとよい。
画像のサイズは、PImage のメンバ変数 width で横幅、height で縦幅が得られる。実行画面のサイズは size( ) 関数で設定する。このプログラムでは、実行画面のサイズを読み込んだ画像のサイズと同じにしている。実行画面に画像を貼りつけるには image( ) 関数を使う。
画像ファイルを読み込み、ウィンドウに表示する。

画像の濃淡変換

解説
このプログラムは、読み込んだカラー画像の全画素の画素値に 100 を加算して、画像を明るくする変換を行う。
1画素ずつ順に全画素を走査するために for 文で2重ループを構成している。画素の座標は (x, y) となる。
座標 (x, y) の画素値(color型)を得るには、PImage のメンバ関数 get( ) を用いる。color型で表されている画素値から3原色(赤、緑、青)の各成分の輝度を得るには red( )、green( )、blue( ) の各関数を使う。輝度は 0~255 の範囲の実数で表される
3原色の輝度を color型の画素値に変換するには color( ) 関数を使う。もし、輝度に 0~255の範囲外の値を指定した場合は、上限値 255 もしくは 下限値 0 に自動的に変換される
座標 (x, y) に画素値(color型)を設定するには PImage のメンバ関数 set( ) を使う。
画像をファイルに保存するには PImage のメンバ関数 save( ) を用いる。
画素値を変えて画像を明るくする。

平均値フィルタ

解説
このプログラムは、読み込んだ画像をグレイスケール画像に変換してから平均値フィルタを用いて画像の平滑化を行う。原画像をオブジェクト f、変換後画像をオブジェクト g としている。また、この二つの画像を横に並べて表示するために、実行画面の横幅のサイズを原画像の横幅の2倍に設定している。
無地の画像を作るには createImage( ) 関数を使う。引数に画像の横幅、縦幅を指定する。
画像をグレイスケール画像に変換するには、PImage のメンバ関数 filter( ) に引数 GRAY を指定して実行する。グレイスケール画像では、3原色(赤、緑、青)の各輝度は同じ値になっている。そこでこのプログラムでは、グレイスケール画像の画素値の計算には、画素値(color型)から赤の輝度のみを取り出して計算に使用している。
グレイスケール画像の画素値(color型)を設定するときは、color( ) 関数の引数に輝度を一つだけ指定すれば良い(22行目)。
左:原画像,右:平均値フィルタを掛けた画像

1次微分フィルタ

解説
このプログラムは、読み込んだ画像をグレイスケール画像に変換してから1次微分フィルタを用いて画像の輪郭抽出を行う。原画像をオブジェクト f、変換後画像をオブジェクト g1、g2、g3 としている。画像 g1 は横方向の微分画像、画像 g2 は縦方向の微分画像、画像 g3 は横方向と縦方向を合わせた結果(エッジ強度)の画像である。
横方向の微分の値、縦方向の微分の値を求め、それぞれ、dx、dy に代入する。エッジ強度は (dx, dy) のノルムを計算して求める。平方根の計算には sqrt( ) 関数を用いる。微分の値を画素値にして画像化するとき、abs( ) 関数で絶対値に変換している。
実行結果を見ると、横方向の微分では、カップの模様の縦線などが抽出されているとことがわかる。また、縦方向の微分では、カップの縁の横線などが抽出されていることがわかる。
左上:原画像,右上:横方向の1次微分画像,左下:縦方向の1次微分画像,右下:エッジ強度画像

2次微分フィルタ(ラプラシアンフィルタ)

解説
このプログラムは、読み込んだ画像をグレイスケール画像に変換してからラプラシアンフィルタを用いて画像の輪郭抽出を行う。
微分の値を画素値にして画像化するとき、abs( ) 関数で絶対値に変換している。
左:原画像,右:ラプラシアンフィルタを掛けた画像

画像の平行移動

解説
このプログラムは、読み込んだ画像をグレイスケール画像に変換してから、x 軸方向に 80 画素、y 軸方向に 30 画素の平行移動を行う。
(x, y) は変換後の画像 g における座標であり、(X, Y) は変換前の画像 f における座標である。画像の幾何学変換では、まず、逆変換式を用いて変換後画像 g の座標 (x, y) から 変換前画像 f の座標 (X, Y) を求め、次に、変換前画像 f の座標 (X, Y) の画素値を取り出して変換後画像 g の座標 (x, y) に設定する。
get( ) 関数の引数に画像の外側の座標を与えた場合は画素値 0(黒)が返される。Processing 以外のプログラミング言語では画像の外側の座標の画素値にアクセスしようとするとメモリアクセス違反のエラーが起こることがあるので注意が必要である。
左:原画像,右:平行移動した画像

画像の拡大縮小(最近傍内挿)

解説
このプログラムは、読み込んだ画像をグレイスケール画像に変換してから、原点を中心にして x 軸方向に 1.5 倍、y 軸方向に 0.8 倍の拡大縮小を行う。画素値の内挿計算には最近隣内挿法を用いる。(x, y) は変換後の座標であり、(Xf, Yf) は逆変換によって求められる変換前の実数座標である
最近隣内挿法では変換前座標 (Xf, Yf) の小数点以下を四捨五入して整数座標に変換する。四捨五入の計算は、値に 0.5 を加算してから int( ) 関数で小数点以下切り捨てを行うことで実現できる。
実行結果を見ると、最近隣内挿法ではジャギーが目立つことがわかる。特に猫のひげの部分に注目すると、縮小によって線が途切れ途切れになってしまっていることがわかる。
左:原画像,右:拡大縮小した画像(最近傍内挿法を使用)

画像の拡大縮小(バイリニア補間)

解説
このプログラムは、読み込んだ画像をグレイスケール画像に変換してから、原点を中心にして x 軸方向に 1.5 倍、y 軸方向に 0.8 倍の拡大縮小を行う。画素値の内挿計算にはバイリニア補間を用いる。
バイリニア補間では、実数座標 (Xf, Yf) の小数部を取り出してこれを内分比として使用する。s を Xf の小数部、t を Yf の小数部として、実数値から小数点以下切り捨てをした値を引くことで求める。
実行結果を見ると、最近隣内挿法より滑らかな画像が得られている。猫のひげの部分に注目すると、最近隣内挿法では線が途切れ途切れになっていたが、バイリニア補間では線が切れずに補間できていることがわかる。
左:原画像,右:拡大縮小した画像(バイリニア補間を使用)

画像の回転

左:原画像,右:回転を施した画像

2値図形の面積

左:原画像,右:2値化した画像画像の面積と、対象物(白画素)の面積

相違度SSD(差分2乗和)の計算

左:原画像,右:原画像を劣化させた画像相違度SSDの値

SSDによるテンプレートマッチング

左:探索対象画像,左:テンプレート画像,赤枠:テンプレートマッチングによって検出された位置

3DCGにおけるシェーディング

鏡面反射を用いた3DCGの作成

3DCGにおけるテクスチャマッピング

立方体CGへの画像のマッピング