この関数は、Mark Ransomによって記述された逆ブレンドを実装して、小さいながらも目に見える改善を追加します。
reverseBlend[img_Image, alpha_Image, bgcolor_] :=
With[
{c = ImageData[img],
a = ImageData[alpha] + 0.0001, (* this is to minimize ComplexInfinitys and considerably improve performance *)
bc = bgcolor},
ImageClip@
Image[Quiet[(c - bc (1 - a))/a, {Power::infy,
Infinity::indet}] /. {ComplexInfinity -> 0, Indeterminate -> 0}]
]
これがバックグラウンド除去機能です。このthreshold
パラメータは、画像の最初の2値化に使用されます。これはminSizeCorrection
、2値化後に削除される小さなジャンクコンポーネントのサイズ制限を微調整するためのものです。
removeWhiteBackground[img_, threshold_: 0.05, minSizeCorrection_: 1] :=
Module[
{dim, bigmask, mask, edgemask, alpha},
dim = ImageDimensions[img];
bigmask =
DeleteSmallComponents[
ColorNegate@
MorphologicalBinarize[ColorNegate@ImageResize[img, 4 dim], threshold],
Round[minSizeCorrection Times @@ dim/5]];
mask = ColorNegate@
ImageResize[ColorConvert[bigmask, "GrayScale"], dim];
edgemask =
ImageResize[
ImageAdjust@DistanceTransform@Dilation[EdgeDetect[bigmask, 2], 6],
dim];
alpha =
ImageAdd[
ImageSubtract[
ImageMultiply[ColorNegate@ColorConvert[img, "GrayScale"],
edgemask], ImageMultiply[mask, edgemask]], mask];
SetAlphaChannel[reverseBlend[img, alpha, 1], alpha]
]
機能のテスト:
img = Import["http://i.stack.imgur.com/k7E1F.png"];
background =
ImageCrop[
Import["http://cdn.zmescience.com/wp-content/uploads/2011/06/\
forest2.jpg"], ImageDimensions[img]];
result = removeWhiteBackground[img]
ImageCompose[background, result]
Rasterize[result, Background -> Red]
Rasterize[result, Background -> Black]
それがどのように機能するかの簡単な説明:
比較的正確な鋭いエッジを生成するお気に入りの二元化方法を選択してください
拡大した画像に適用し、取得mask
した画像を元のサイズに縮小します。これにより、アンチエイリアスが実行されます。ほとんどの作業は完了しています。
少し改善するには、ネガの明るさをアルファとして使用して画像を背景にブレンドし、取得した画像を元の画像のエッジの周りの薄い領域(edgemask
)でブレンドして、エッジの白いピクセルの視認性を下げます。これらの操作に対応するアルファチャネルが計算されます(やや不可解なImageMultiply/Add
表現)。
これでアルファチャネルの推定値が得られたので、リバースブレンドを実行できます。
手順3と4はそれほど改善されませんが、違いは明らかです。