
私の職場では、パスポートサイズの写真をまとめてスキャンし、個別の写真に切り分けて、固有のファイル番号を付けて保存しています。現在は、Paint.net を使用して、写真を手動で選択、切り取り、保存しています。
ソニーのサイバーショットカメラには顔検出機能があるのを知りました。Google でも顔検出を検索すると iphoto に関する情報が表示されます。Picasa にも顔検出機能があります。文書内の顔を自動検出する方法はありますか。そうすれば、個々の画像を切り分けるのに必要な時間が短縮され、職場での生産性が向上します。
スキャンした文書のサンプル(実際の文書には 5 行に 4 枚の画像が並んでおり、合計 20 枚あります): (出典:http://www.memorykeeperphoto.com/images/passport_photo.jpg、フェアユース)
たとえば、Picasa 3.8 では、[表示] > [人物] をクリックすると、すべての顔が表示され、名前を付けるように求められます。これらの個々の写真を、名前を付けて別の写真として自動的に保存できますか。
答え1
パスポート写真を自動的に切り取るのは、間違いなくできそうです。照明条件を固定し、常に正面を向き、画像フォーマットを一定に保つ...顔検出にとってこれ以上の好条件は望めないと思います。
使ってみた顔検出サンプル画像の結果を確認するには:
パスポートにはさまざまな形式とサイズがあるため、スキャナーのフラットベッドに不規則に詰め込まれますが、写真は常に垂直に配置するものと想定しています。facedetect
すべての顔の中心とサイズがわかります。特に、顔のサイズを使用して、その周囲の領域を比例して切り取ることができます。パスポートの写真は写真の固定領域をカバーする傾向があるため、これは比較的安全な仮定のようです。
画像のサブ領域を切り抜くのはとても簡単ですイメージマジックプロセスを自動化するために、小さな(そして大まかな)シェル スクリプトを作成しました。
#!/bin/sh
pc=60
files="P1Xb8.jpg"
fileno=1
for file in $files; do
n=1
facedetect $file | while read x y w h; do
border=$(($w * $pc / 100))
x=$(($x - $border))
y=$(($y - $border))
w=$(($w + $border * 2))
h=$(($h + $border * 2))
echo $x $y $w $h
convert "$file" -gravity NorthWest -crop "${w}x${h}+$x+$y" "${fileno}_$n.jpg"
n=$(($n + 1))
done
fileno=$(($fileno + 1))
done
私は、検出された顔の幅の 60% (スクリプトの 2 行目) の境界領域を経験的に定義しました。取得した 4 つの画像は次のとおりです。
これはすでにかなり良いです。上部には常にいくらかの空白が残りますが、呼び出し時に「-fuzz 10% -trim」を追加するだけで削除できましたconvert
。その後の最初の画像の結果は次のとおりです。
簡単なスクリプトとしては悪くない出来ですが、改善の余地は十分にあります。たとえば、ほとんどのパスポートは縦向きなので、垂直/水平係数が異なります (通常は 1.3)。また、顔はわずかに上方に移動する傾向があります (おそらく 1.3 程度)。これらを修正すると、切り抜きが改善され、上部の空白部分を完全にトリミングする必要がなくなります。
このスクリプトを実際の出力に対してテストするために、サンプルのフラットベッド スキャンを (非公開でも) 投稿していただければ幸いです。
もちろん、この提案には Linux のインストールが必要です。しかし、私の理解が正しければ、この面倒な作業を自動化するために専用のインストールや仮想マシンをセットアップすることは、まったく不合理ではありません。
プライバシーが問題にならないのであれば(私はそうは思いませんが)、私は実際に、切り取られた顔と引き換えに適切なソリューションの作成を手伝い、顔検出モデルの改善に役立てることに興味があります。