5.21. 拡大縮小、反転、切り抜き¶
これまでのサブセクションはすべて、ピクセルが最初に存在していた位置でそのまま処理を行うものでした。変換 ファミリーはそれを変えます。スケーリングは、すべての入力ピクセルを 異なる 出力位置へ送ります。場合によっては一度に複数の出力位置へ(拡大時)、あるいは他の複数の入力ピクセルと共有される位置へ(縮小時)送ります。反転と回転は異なるマッピングを通じて同じことを行います。切り抜きは入力ピクセルの長方形の部分集合を残し、残りを破棄します。
image モジュールは、引数のほとんどと挙動のほとんどを共有する 3 つのメソッドを通じてそのファミリーを公開します。
copy()-- 画像のコピーを生成します。必要に応じて拡大縮小、切り抜き、向きの変更を行います。crop()--copyと同じ操作ですが、アプリケーションがソースから部分長方形を取り出すことを想定しています。scale()-- 同じく同じ操作ですが、アプリケーションが結果をリサイズすることを想定しています。
この 3 つは同じ引数と同じ変換機構を共有しており、違いはデフォルトで結果がどこに置かれるかです。copy() は新しい画像を生成しますが、crop() と scale() はソースをその場で変更します。
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 つの名前の背後にある本当の違いです。scale と crop はその場で変換し、copy は新たに確保します。結果配置のキーワードがそのギャップを埋めます。scale や crop に copy=True を指定すると、ソースを上書きする代わりに結果を別個のヒープバッファとして確保し、3 つのいずれかに copy_to_fb=True を指定すると、IDE プレビュー用に結果をフレームバッファに置きます。