画像の拡大縮小・リサイズの原理、アルゴリズムによる違いを解説!

このページでは画像の拡大縮小はどのように行われているかについて説明していきたいと思います。

画像とは画素の集まり

こちらの記事の最初の方でも説明しましたが画像とは画素の集まりです。

画像データの構造・画素・RAWデータについて解説画像データの構造・画素・RAWデータについて解説

まずはRGBなどの輝度の話は置いといて、画素のみに注目して画像データを見てみると下図のようになります。 黒丸が画素で、これは4x4の画像の例です。

画像の縮小

画像の縮小とは、この画素と画素の間隔を広げる処理と言えます。

ここでは画像を縦サイズと横サイズそれぞれ 0.5 倍に縮小する実例を用いて処理の流れを説明します。

画像を 0.5 倍にするためには、画素と画素の間隔を 2 倍(0.5の逆数)にします。間隔を2倍にするので黒丸の画素のみを残し白丸の画素は不要になります。

ちょうど 1 画素ずつ飛ばす感じになりましたね。これにより画素数は縦横共に 1/2 になり、2x2の画像になります。このように画素を飛ばして不要な画素を削る処理を間引き処理と言ったりします。

0.5 倍にするにはこの間引き処理だけで処理完了です。

では次に 0.75 倍に縮小することを考えましょう。0.75 倍の場合、画素と画素の間隔を 0.75 の逆数の 1.33… 倍にする処理となります。縮小後の画素の間隔は下図のようになります。白色画素は削除され、代わりにピンク色の画素が必要になります。

画素の間隔が 1.33(本当は 1.333333… だけど簡単のため 1.33 と書きます)になったので画像サイズは 0.75 倍されたことは理解できると思います。画素数は3x3になっています。

ただ図を見て疑問に思いませんか?

元の画像に存在しない

ピンク色画素のところの

RGB輝度値は何にすれば良いの?

実はここが画像拡大縮小のポイントの一つです。もともとの画像に無かった位置の画素は周りの画素の輝度値から推測して求めてやる必要があります。この周りの画素の輝度値から推測してもともと無かった画素を挿入する処理を補間と呼びます。

この補間には様々なアルゴリズムが存在します。このアルゴリズムの違いにより拡大縮小後の画質や処理速度に差が出ることになります。

このWebサイトには比較的なシンプルなアルゴリズムである最近傍補間法と線形補間法を紹介していますのでこちらのページを読んで興味が湧いた人は拡大縮小処理を実装して見たい人は参考にしてください。

画素と画素の間隔を広げ必要な画素を補間するが画像の縮小処理になります。

スポンサーリンク

画像の拡大

画像の拡大とは、縮小とは逆に画素と画素の間隔を狭める処理と言えます。

例えば画像を縦横それぞれを2倍に拡大する実例を用いて処理の流れを説明します。

画像を2倍に拡大するので、画素を追加して画素と画素の間隔を1/2にします。

元の画像にない新たな画素がたくさん必要になりましたね。拡大においても縮小の時に説明した補間処理でこれらの画素を追加してやる必要があります。

画素と画素の間隔を狭め必要な画素を補間するのが画像の拡大処理になります。

拡大縮小前後の座標関係と補間が必要になる画素

ここまでは補間を中心に説明してきましたが、次は拡大縮小前後の画素の座標関係を説明していきたいと思います。

ここでは画像を縦方向に2倍、横方向にを2倍に拡大することを考えてみます。これにより画素数は縦方向・横方向ともに2倍になります。例えば元画像が2 x 2のサイズであれば、拡大後の画像のサイズは4 x 4となります。さらに、下の図のように、拡大後画像の色付きの画素は元画像の同じ色の画素の画素値と一致します。

つまり、元画像の画素の座標を(x, y)、拡大後画像の画素の座標を(X, Y)とすれば、これらは下の式の関係にあると言えます。

x = 1 / 2 × X

y = 1 / 2 × Y

では、拡大後画像の他の座標の画素はどうなるでしょうか。例えば下の図でピンク色の画素について考えてみます。

拡大後画像のピンク画素の座標は(1, 1)ですので、上の式に当てはめて考えると元画像上の対応する座標は(0.5, 0.5)となります。

しかし、この座標は元画像上にはありません。特にプログラムで扱うようなデジタルな画像には整数の座標しか存在しませんので、こういった小数点以下の座標の画素は存在しないのです。存在しない画素はどうすれば良いでしょうか?

ここで出てくるのが前に説明した補間です。補間を行うことにより存在しない画素を追加して考えて処理を行うのです。つまり、「拡大縮小後の画素値を求める際に必要な座標の画素」が元画像上に存在しない場合は補間処理を行う必要があるのです。

今回は2倍に拡大した場合で説明しましたが、横方向にH倍、縦方向にV倍拡大縮小する場合は、拡大縮小後の座標(X, Y)と元画像の座標(x, y)の関係は下記式で表すことができます。

x = 1 / H × X

y = 1 / V × Y

行列を用いた表現

上式を行列で表現すれば下記のように表すことが可能です。

$$ \left ( \begin{array}{c} x \\ y \end{array} \right ) = \left ( \begin{array}{cc} 1/H & 0 \\ 0 & 1/V \end{array} \right ) \left ( \begin{array}{c} X \\ Y \end{array} \right ) $$

スポンサーリンク

画像の拡大縮小処理まとめ

ここまでの流れをまとめると、

・縮小処理

画素と画素の間隔を広げ必要な画素を補間する

・拡大処理

画素と画素の間隔を狭め必要な画素を補間する

この二つの処理の違いは間隔を広げるか狭めるかの点だけであり、これらは間隔を何倍するかの違い(1より大きい数、1より小さい数)なので同じプログラムで実現可能です。

つまり、画像の拡大縮小処理とは画像中の画素と画素の間隔を変化させ足りない画素を補間する処理です。

下記の式で求まる(x, y)座標の画素が元画像上に存在しない場合、その画素が足りない画素となり補間対象となります。

x = 1 / H × X

y = 1 / V × Y

補間アルゴリズム

画像の拡大縮小については少しずつイメージ湧いてきたでしょうか?本サイトではC言語で画像の拡大縮小をプログラミングした時の解説やソースコードを載せたページも用意していますので、具体的な処理を見たい場合は是非参考にしていただければと思います。

・最近傍補間(ニアレストネイバー)法を用いた拡大縮小

補間する画素に一番近い画素の輝度値を用いる方法です

C言語で画像の拡大縮小(最近傍補間編)

・線形補間法(バイリニア)を用いた拡大縮小

補間する画素の周りの画素の輝度値に基づいて輝度値を計算する方法です。輝度値を補間画素からの距離に応じて周辺画素の輝度値を重み付けし、値を計算します。

C言語で画像の拡大縮小(線形補間編)

最近傍補間(ニアレストネイバー)と線形補間(バイリニア)の画質の違い

最後に補間のアルゴリズムによってどのような違いが出るかの紹介をしたいと思います。

写真などの自然画(縦横10倍に拡大)

・入力画像

・最近傍補間

・線形補間

違いわかりますか?最近傍だと観覧車の車輪あたりの線がギザギザしている感じがありますが、線形補間だと滑らかになっています。

さらに一部分を拡大してみるとその傾向がさらにわかりやすいと思います。どちらかというと線形補間の方が綺麗に見えると思います。

・最近傍補間(一部分拡大)

・線形補間(一部分拡大)

パワポなどで作成したデジタル画(10倍に拡大)

・入力画像

・最近傍補間

・線形補間

こちらも違いは自然画の時と同じです。

・最近傍補間

・線形補間

こちらはどちらかというと最近傍補間の方がきれいに見えると思います。線形補間は周辺画素の平均を求めるような処理であり、若干ぼやけます。写真などの場合はそのぼやけにより綺麗に見えますが、パワポなどで作成したようなデジタルな絵では、線形補間だとぼやけるので最近傍補間の方が綺麗に見える人も多いと思います。

このように補間のアルゴリズムにより画質が異なります。自信が求める画質に合わせてアルゴリズムを選択しましょう。

スポンサーリンク

まとめ

今回は拡大縮小がどのような処理であるかを解説しました。要は拡大縮小というのは画素間の距離を変化させることです。そしてその距離の変化を行うために必要になる追加の点を推測するのが補間になります。

かなりプログラミング寄りの考え方ですが、この2つを理解しておくと画像処理プログラミングがやりやすくなりますのでぜひ覚えて帰ってください!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です