« 画像の拡大「Lanczos法」 | トップページ | 虹 »

画像の拡大-距離計算に関する考察


リンク
画像の変換(目次ページ)
『拡大・縮小』関連
画像の縮小
画像の拡大「Nearest Neighbor法」
画像の拡大「Bilinear法」
画像の拡大「Bicubic法」
画像の拡大「Lanczos法」
・画像の拡大-距離計算に関する考察
超解像
ここまで、Bilinear法、Bicubic法、Lanczos法、すべて
「X方向の距離とY方向の距離を求め、それぞれのウェイト計算をし、
 X方向のウェイトとY方向のウェイトを掛ける。」
という手法をとってきました。


しかし、距離と言えば、X方向やY方向ではなく直線距離のはず。
つまり、デジカメであれば、カメラを傾ける事でX軸Y軸は傾くし、
スキャナーだって対象の角度を変えれば傾く。

X軸やY軸の方向は、人間が処理の都合で後から付けたもの。

画像の拡大にとって、
「そのような後付けの軸方向に左右されるべきものなのだろうか。」


「直線距離で計算するのが正しいのでは?」


そんな素朴な疑問がわいてきました。

では、実際に試して確認してみましょう。

用いたのは3つのテストデータ。
テストデータ1
(弱エッジ)
緩やかに変化するグラデーションデータ
テストデータ2
(強エッジ)
白黒パターン
テストデータ3
(ワイングラス)
実写データ


テストデータ1
(弱エッジ)
128x128 → 240x320

まず最初に用いたのはこの同心円状のデータ。
何かのテストチャート、という訳ではなく、
私が適当に作ったデータです。

左下を中心にして、白黒レベルが波のようになっています。
右上部の波が密になった場所で灰色の楕円が幾つか見えますが、
これは、各ピクセルの形が四角形なため、副二次的に発生したモアレです。
左上隅と右下隅にも同様の傾向が見られます。

Nearest Neighbor
『Nearest Neighbor法』は「ウェイト」という考え方はありません。
ここでは、比較のために載せています。

Bilinear
weight = weight_x * weight_y
weight_x = bilinear_weight( dx )
weight_y = bilinear_weight( dy )
Bilinear
weight = bilinear_weight( d )
d = √( dx2 + dy2 )
左側(←)は、X方向、Y方向それぞれのウェイトを掛ける従来の方法。
右側(→)は、直線距離でウェイトを求める方法です。
「Bilinear法」は参照ピクセルが 2x2 ピクセルなので、
その程度では、ほとんど差が出ません。

Bicubic
weight = weight_x * weight_y
weight_x = bicubic_weight( dx )
weight_y = bicubic_weight( dy )
Bicubic
weight = bicubic_weight( d )
d = √( dx2 + dy2 )
左側に比べ、右側がくっきりしている事がわかります。
「シャープネス・フィルタがより強く掛かっている」という認識で良いと思います。
しかし、右側の画像のグラデーション部分(左下4分の1の領域)を見ると
四角いブロック状のノイズ(モザイク・ノイズ)が出ている事が分かります。

その点に注意して左側の同じ位置を(じっくり)見ると、
うっすらとですが、ブロック状のノイズが出ている事が分かります。

Lanczos2
weight = weight_x * weight_y
weight_x = lanczos_weight( dx, 2 )
weight_y = lanczos_weight( dy, 2 )
Lanczos2
weight = lanczos_weight( d, 2 )
d = √( dx2 + dy2 )
右側の画像の中央部分のシマシマを見ると、左側よりもくっきりしているようです。
Lanczos2 に関しては、直線距離で行った方がシャープネス・フィルタが掛かる
と言ってよいでしょう。

Lanczos3
weight = weight_x * weight_y
weight_x = lanczos_weight( dx, 3 )
weight_y = lanczos_weight( dy, 3 )
Lanczos3
weight = lanczos_weight( d, 3 )
d = √( dx2 + dy2 )
中央部分のシマシマを見ると、左側よりも右側の方がくっきりしています。
同じく中央部分の、同心円のカーブの滑らか具合を Lanczos2、Lanczos3 で比較
すると、Lanczos3 の方が優れているようです。



次に、別のパターンで拡大方法の違いを見てみましょう。
テストデータ2
(強エッジ)
64x32 → 180x120

このパターンはエッジが強い画像(輝度が白→黒とレベル差が大きい画像)です。

Nearest Neighbor
「Nearest Neighbor 法」はエッジのレベル差は維持されているものの、
中央部分の細いシマシマを見ると、線の幅が不正確である事がわかります。

Bilinear
weight = weight_x * weight_y
weight_x = bilinear_weight( dx )
weight_y = bilinear_weight( dy )
Bilinear
weight = bilinear_weight( d )
d = √( dx2 + dy2 )
「Bilinear 法」は左側、右側、あまり差が無く、
どちらもボケている事が分かります。
(よくよく見ると、右側にノイズが出ています。)

Bicubic
weight = weight_x * weight_y
weight_x = bicubic_weight( dx )
weight_y = bicubic_weight( dy )
Bicubic
weight = bicubic_weight( d )
d = √( dx2 + dy2 )
「Bicubic 法」は左側よりも右側の方がくっきりしています。
しかし、白の四隅、黒の四隅で形が崩れている事がわかります。

Lanczos2
weight = weight_x * weight_y
weight_x = lanczos_weight( dx, 2 )
weight_y = lanczos_weight( dy, 2 )
Lanczos2
weight = lanczos_weight( d, 2 )
d = √( dx2 + dy2 )
「Lanczos2」は左側より右側がくっきりしています。

Lanczos3
weight = weight_x * weight_y
weight_x = lanczos_weight( dx, 3 )
weight_y = lanczos_weight( dy, 3 )
Lanczos3
weight = lanczos_weight( d, 3 )
d = √( dx2 + dy2 )
「Lanczos3」の右側はエッジの反射(折り返し)がノイズとなって出ています。
それを踏まえて左側を見ると、同じ位置にうっすらとノイズが分かります。



次に実写で違いを見てみましょう。
テストデータ3
(ワイングラス)
160x120 → 384x256 (下記の拡大結果は一部を切り出し)

Nearest Neighbor
「Nearest Neighbor」はブロック状(モザイク状)になります。

Bilinear
weight = weight_x * weight_y
weight_x = bilinear_weight( dx )
weight_y = bilinear_weight( dy )
Bilinear
weight = bilinear_weight( d )
d = √( dx2 + dy2 )
「Bilinear」では、左側、右側で大した違いはありません。

Bicubic
weight = weight_x * weight_y
weight_x = bicubic_weight( dx )
weight_y = bicubic_weight( dy )
Bicubic
weight = bicubic_weight( d )
d = √( dx2 + dy2 )
「Bicubic」では右側がくっきりしています。
しかし、グラスにうつった照明の反射(水面と縁の間)を見ると、
グラデーション部分にブロックノイズが出ている事が分かります。
シャープネス・フィルタ特性が強すぎるのではないかと思います。

Lanczos2
weight = weight_x * weight_y
weight_x = lanczos_weight( dx, 2 )
weight_y = lanczos_weight( dy, 2 )
Lanczos2
weight = lanczos_weight( d, 2 )
d = √( dx2 + dy2 )
「Lanczos2」右側の方がくっきりしています。

Lanczos3
weight = weight_x * weight_y
weight_x = lanczos_weight( dx, 3 )
weight_y = lanczos_weight( dy, 3 )
Lanczos3
weight = lanczos_weight( d, 3 )
d = √( dx2 + dy2 )
「Lanczos3」右側の方がくっきりしています。


このワイングラス、グラスの側面にブドウの模様がほどこされています。
拡大後、この模様がちゃんと出ているのは Bicubic, Lanczos2, Lanczos3 の右側
でしょう。

総合的に判断すると、
画質という意味では Lanczos2 の右側(直線距離で計算)が最もバランスが
とれているように思います。

ただし、Lanczos2 を直線距離で処理すると、
出力側の各ピクセルに対して 16 ピクセルを参照するため、
1ピクセルあたり、平方根(√)の計算が 16 回発生する事になり、
計算量がとんでもない事になります。


【まとめ】
  ( X方向ウェイト)*( Y方向ウェイト) (直線距離ウェイト)
Bilinear ぼける ←と大差なし
ぼける
Bicubic ぼける 画質は改善
×グラデーションにブロックノイズ
×処理が重い
(√計算 16回 / pixel)
Lanczos2 ぼける 画質は改善
(バランスがとれている)
×処理が重い
(√計算 16回 / pixel)
Lanczos3 ぼける 画質は改善
×エッジ部分で折り返し
×処理が重い
(√計算 36回 / pixel)

|

« 画像の拡大「Lanczos法」 | トップページ | 虹 »

画像フォーマット」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: 画像の拡大-距離計算に関する考察:

« 画像の拡大「Lanczos法」 | トップページ | 虹 »