切り抜きたい(再利用 Ver.)


東です。

切り抜きたい(再発明 Ver.)の続きです。
マスク処理
「手元にある大量の画像をマスク処理する」という要求に対して、OpenCVのライブラリを使ってC++で実装しましたが、画像処理のコマンドが多く用意されているImageMagickを使えばもっと簡単にできるんじゃないの?というお話です。

お題

素材画像(カラー)、マスク画像(グレースケール)を与えると、素材画像のうちマスク画像の黒色の部分が透過した画像を出力せよ。
ただし、素材画像の大きさは統一されていない。
ただし、素材画像の大きさがマスク画像の大きさを超えることはない。
ただし、ImageMagickのコマンドを使って実現せよ。

どうやるの?

ImageMagickのページには各種多様なコマンドの説明が書いてあります。
マスク処理はCopyOpacityオペレーターを使えば良さそうです。
Duff-PorterオペレーターのDstInメソッドを使っても同じことができそうですが、こちらだとあらかじめアルファチャンネルを画像に付与する必要があるようです。
CopyOpacityの方がコマンド数が少なくできそうですので、今回はこちらを使います。

実装

#!/bin/bash

input=$1  # 素材画像
mask=$2   # マスク画像
output=$3 # 加工後の画像

convert ${input} ${mask} -gravity Center -alpha Off -compose CopyOpacity -composite ${output}

処理の流れを簡単に図で説明するとこんな感じです。
処理の流れ

終わりに

確かにImageMagickを使えば、コマンド一発でマスク処理が可能...なんですが、コマンドの文法がややこしかったり、マスク処理に複数のやり方があったりと、いろいろ面倒でした。複数の処理をひとつのコマンドで実行することもできて、分かってしまえば便利に使えるんですが、そこに到達するまでがなかなか大変でした。
最初に出来あがったものは、途中結果を中間ファイルに書き出しつつコマンドを4回ほど実行するものでしたが、「複数回プロセス起動すると実行速度遅くなるよね」「美しくない!」「絶対一発で書けるはず!」と思って試行錯誤した結果、なんとかコマンド1個にすることができました。
実行速度とか美しさとか考えなければ、もうちょっと楽に早くできたのにな、と(ほんの少しながら)反省しています。


This entry was posted in 技術. Bookmark the permalink.