5.21. 拡大縮小、反転、切り抜き

これまでのサブセクションはすべて、ピクセルが最初に存在していた位置でそのまま処理を行うものでした。変換 ファミリーはそれを変えます。スケーリングは、すべての入力ピクセルを 異なる 出力位置へ送ります。場合によっては一度に複数の出力位置へ(拡大時)、あるいは他の複数の入力ピクセルと共有される位置へ(縮小時)送ります。反転と回転は異なるマッピングを通じて同じことを行います。切り抜きは入力ピクセルの長方形の部分集合を残し、残りを破棄します。

image モジュールは、引数のほとんどと挙動のほとんどを共有する 3 つのメソッドを通じてそのファミリーを公開します。

  • copy() -- 画像のコピーを生成します。必要に応じて拡大縮小、切り抜き、向きの変更を行います。

  • crop() -- copy と同じ操作ですが、アプリケーションがソースから部分長方形を取り出すことを想定しています。

  • scale() -- 同じく同じ操作ですが、アプリケーションが結果をリサイズすることを想定しています。

この 3 つは同じ引数と同じ変換機構を共有しており、違いはデフォルトで結果がどこに置かれるかです。copy() は新しい画像を生成しますが、crop()scale() はソースをその場で変更します。

5.21.1. 共有される引数

1 回の呼び出しで、アプリケーションが要求するスケーリング、切り抜き、向き、チャンネル抽出の任意の組み合わせをまとめて行います。

x_scaley_scale は、入力を水平軸と垂直軸に沿って独立に拡大縮小します。どちらもデフォルトは 1.0(スケーリングなし)です。それぞれに異なる値を指定すると非一様なスケーリングになります。たとえば、高さの 2 倍の幅に引き伸ばされたフレームなどです。

roi は入力をソース画像の長方形に制限し、それらのピクセルだけを残りの変換処理に通します。これが操作における「切り抜き」の部分です。roi を渡すと部分領域を抽出します。

hint は、補間方法と向きの反転を選択するフラグのビットフィールドです。複数のフラグはビット単位の OR で組み合わせます(hint=image.BILINEAR | image.HMIRROR)。フラグは 2 つのグループ、すなわち 補間 ファミリーと 向き ファミリーに分かれており、互いに無関係ですが同じビットフィールドを共有します。

rgb_channel は RGB565 ソースの単一チャンネルを選択します。0 は赤、1 は緑、2 は青を意味し、結果はそのチャンネルだけを含むグレースケール画像として出力されます。たとえば赤チャンネルだけでしきい値処理を行う場合に便利です。

color_palettealpha_palette は、変換メソッド to_rainbow() および to_ironbow() と同じ方法で、出力時にルックアップテーブルを通じてピクセル値を再マッピングします。

copy=Truecopy_to_fb=True は、他のすべての結果生成メソッドが使うのと同じ規約に従います。デフォルトではその場で処理し、copy=True は別個の結果を確保し、copy_to_fb=True は IDE プレビュー用に結果をフレームバッファに置きます。

5.21.2. 補間: AREA、BILINEAR、BICUBIC

スケーリングによって各出力ピクセルが単一の入力ピクセルとも一致しない位置に送られる場合、メソッドはどの値を書き込むかを選ばなければなりません。3 つのフラグがその方法を制御します。

image.BILINEAR は、最も近い 4 つの入力ピクセルの間を、出力位置からの距離で重み付けして補間します。結果は最近傍補間よりも滑らかで、斜めの線にジャギーが見えませんが、追加の演算は最近傍パスの約 4 倍のコストがかかります。ほとんどの拡大処理や、整数以外のスケール係数に対する適切な選択肢です。

image.BICUBIC は、最も近い 16 個の入力ピクセルの間を 3 次曲線を用いて補間し、さらに多くの演算と引き換えにさらに滑らかな結果を生成します。それを必要とするコスト重視のアプリケーションには最高品質ですが、IDE が表示するだけのライブフレームに対しては追加の計算に見合うことはまれです。

image.AREA は、出力ピクセルの範囲内に入るすべての入力ピクセルを平均します。これが 縮小 のための適切なアルゴリズムです。バイリニアとバイキュービックは補間器であり、ソースピクセルの の値を推定します。これは拡大が必要とするものですが、縮小時には各出力ピクセルが多数のソースピクセルをカバーし、補間器は最も近いいくつかのピクセルしか読みません。スキップされた詳細はエイリアシングとして戻ってきます。image.AREA は代わりにカバーされたすべてのピクセルを平均に折り込みます。

ヒントを何も指定しない場合のデフォルトのスケーリングアルゴリズムは最近傍補間で、これは最も安価であり、ソースがすでに出力先のピクセル解像度になっている場合には正解です。

5.21.3. 向き: 反転と回転

向きのフラグは、互いに、また補間フラグとも自由に組み合わせられる小さなブール変換の集合です。

  • image.VFLIP は画像を垂直方向に反転します(上が下になる)。

  • image.HMIRROR は画像を水平方向に反転します(左が右になる)。

  • image.TRANSPOSE は x 軸と y 軸を入れ替えます(行が列になる)。

ほとんどの回転はこれら 3 つを組み合わせて作られます。このモジュールは名前付きのショートカットも公開しています。

  • image.ROTATE_90(= VFLIP | TRANSPOSE

  • image.ROTATE_180(= HMIRROR | VFLIP

  • image.ROTATE_270(= HMIRROR | TRANSPOSE

コードでは:

img.copy(hint=image.ROTATE_90, copy_to_fb=True)

5.21.4. アスペクト比の扱い

ソースのアスペクト比が描画先の長方形と一致しない場合、3 つのフラグがその不一致をどう扱うかを決めます。

image.SCALE_ASPECT_KEEP はソースのアスペクト比を保持し、結果を レターボックス します。ソースは出力先の内側に収まるまで拡大縮小され、残りの出力先は空(ゼロ)のピクセルで埋められます。出力全体を埋めることよりもソースを歪ませないことが重要な場合の適切な選択肢です。

image.SCALE_ASPECT_EXPAND はソースのアスペクト比を保持し、それを 切り抜き ます。ソースは出力先を埋めるまで拡大縮小され、出力先からはみ出す部分は切り落とされます。ソースのすべての部分を見ることよりも出力全体を埋めることが重要な場合の適切な選択肢です。

image.SCALE_ASPECT_IGNORE はアスペクト比を無視し、ソースを引き伸ばして出力先を埋め、それによって生じるあらゆる歪みを受け入れます。アプリケーションがすでに歪みを考慮済みの場合、たとえば出力先の寸法が実際には同じシーンの長方形ではない場合などの適切な選択肢です。

デフォルト(アスペクトフラグを設定しない場合)は SCALE_ASPECT_IGNORE と同じで、引き伸ばして埋めます。アスペクト比を重視するアプリケーションは、3 つのうち 1 つを明示的に指定します。

5.21.5. どれをいつ使うか

ほとんどのリサイズは、x_scale / y_scale のペアと補間ヒントを指定した scale() を使います。

img.scale(x_scale=0.5, y_scale=0.5, hint=image.AREA)

ほとんどの回転は、hint=image.ROTATE_90 などを指定した同じ呼び出しを使います。

切り抜きは、デフォルト以外の roi を指定した crop() を使います。

img.crop(roi=(40, 30, 200, 150))

ソースが操作を生き残らなければならない場合、たとえば基準フレームを取得する、破壊的に処理しようとしているフレームのサムネイルを取る場合などには、copy() が結果を新しい画像として生成し、ソースには手を付けません。

thumbnail = img.copy(x_scale=0.25, y_scale=0.25, hint=image.AREA)

そのデフォルトこそが 3 つの名前の背後にある本当の違いです。scalecrop はその場で変換し、copy は新たに確保します。結果配置のキーワードがそのギャップを埋めます。scalecropcopy=True を指定すると、ソースを上書きする代わりに結果を別個のヒープバッファとして確保し、3 つのいずれかに copy_to_fb=True を指定すると、IDE プレビュー用に結果をフレームバッファに置きます。