応用プログラミング及び実習 2017年度 第3回 おまけ課題

課題S(おまけ課題) 締切:次回実習終了まで

課題Dのプログラムに,画像を縮小する機能を追加しよう. 縮小機能は関数として実装すること.ただし,関数の仕様(関数名,引数,戻り値など)については自分で工夫したらよい.

画像縮小のアルゴリズムについては,以下で解説する.

step0 準備

幅 W 高さ H の画像を幅 w 高さ h の画像に縮小するとする. 縦横の縮小率は別個に定められるようにするべきであるが,ここでは話を簡単にするために同じ縮小率とする. 作成するプログラムも縦横同一の縮小率としてよい.

縮小率を \( \alpha \) で表すことにする.すなわち,

\[ \left\{ \begin{array}{l} w = \frac{W}{\alpha} \\ h = \frac{H}{\alpha} \end{array} \right. \]

である(除算は小数点以下切り捨て). \( \alpha = 2 \) ならば画像サイズを縦横半分にすることになる.

step1 \( \alpha \) が自然数の場合その1

\( \alpha \) が自然数の場合,もっとも単純な方法は,画素を「間引く」方法である(サンプリングする,標本化する,という). 簡単のために1次元で考えると,元画像の画素値のならびが

座標    [0] [1] [2] [3] [4] [5] [6] ... 
画素値   10  15  17  16  19  20  18 ...

であり,\( \alpha = 3 \) だったとすると,縮小後の画素のならびを

座標    [0] [1] [2] ... 
画素値   10  16  18 ...

とする,というものである.

for(x = 0; x < w; x++){
   X = x * alpha;
   img[x] = IMG[X];
}

step2 \( \alpha \) が自然数の場合その2

実は,step1のように単純にサンプリングする方法は,「エイリアシング」という現象を起こすことがあるため,あまりよい方法ではない. 以下のサンプル画像を縮小してみるとわかるかもしれない. \( \alpha = 3 \) で縮小してみよう.

縮小画像の質を改善する,いいかげんだけど最も簡便な方法は,間引くかわりに平均をとる,というものである. step1と同様に1次元で説明する. 元画像の画素値のならびが

座標    [0] [1] [2] [3] [4] [5] [6] ... 
画素値   10  15  17  16  19  20  18 ...

であり,\( \alpha = 3 \) だったとすると,縮小後の画素のならびは

座標    [0] [1] ... 
画素値   14  18    

とする,というものである.ただし,(10+15+17)/3 = 14, (16+19+20)/3 = 18 である.

課題T(おまけ課題)締切:高橋担当の実習最終回まで

\( \alpha \) が正の実数の場合

\( \alpha \) として任意の正の実数をとれるようにしたい場合,困った問題が発生します. 例えば,\( \alpha = 1.5 \) として step1 の方法を適用しようとしてみるとわかりますが,縮小後の画像の [1] の位置は,元の画像の [1.5] の位置に対応することになります. しかし,元画像の座標は [0], [1], ... と整数値をとっているので,[1.5] なんて位置の画素値は得られません.

これを解決するには,何らかの方法で画素値を「補間」(「数値計算法」で学んだかも)する必要があります.中でも単純でよく用いられるのは,「バイリニア法(双線形補間法)」と呼ばれるものです.

というわけで,この方法について調べて,任意の縮小率を実現できるようにしてみよう. また,縮小ができたらちょっと手を加えるだけで拡大もできるはずです. 任意の拡大率での拡大もできるようにしてみよう.


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-09-29 (金) 11:29:19