導入
Python 3.11以降と、NumPy、SciPy、Pillowが要ります。Releasesから最新のパッケージをダウンロードして解凍し、中のwheelを入れます。
python -m pip install ellipse_foreground-X.Y.Z-py3-none-any.whl
使い方
次のプログラムは、画像を読み、前景を囲む楕円を渡して、アルファマットを書き出します。同じAnalysisで楕円だけを変えてextractを呼ぶと、画像ごとに作った木を使い回します。
import numpy as np
from PIL import Image
from ellipse_foreground import Analysis, Ellipse, Mix
source = np.asarray(Image.open("input.png").convert("RGB"))
analysis = Analysis(source.astype(np.float32) / 255.0, source)
ellipse = Ellipse(center_x=640, center_y=330, radius_x=190, radius_y=300)
alpha = analysis.extract(ellipse, Mix.ADAPTIVE_COLOR)
Image.fromarray(np.rint(alpha * 255).astype(np.uint8)).save("alpha.png")
処理の流れ
- 画像を幅256画素(既定)に縮め、4近傍の画素の格子の上に、単連結法のデンドログラムを作ります。
- 楕円に由来する事前分布、画素ごとの手がかり、境界項の和を最大にする木の切断を選びます。最適解は、動的計画法で厳密に求めます。
- 手がかりは、色、テクスチャ、3×3パッチの最近傍の三つです。それぞれが楕円の内側と外側をどれだけ分けられるかに応じて、重みを決めます。
- 低解像度のマスクを、画像の解像度のアルファマットに仕上げます。ジョイントバイラテラルアップサンプリング、色のヒストグラムによる補正、ガイデッドフィルタを使います。
速度と制限
- NumPyとSciPyで書いた、CPU向けの実装です。1280×640画素の画像では、Core i7-1360Pで、
Analysisの構築に約0.3秒、1回のextractに約1秒かかります。 - 評価に使ったのは、キャラクターを背景に合成した画像です。写真の人物は評価しておらず、学習済みの分割モデルとの比較もしていません。論文にも、同じことを書いています。