OpenCVをExtendscriptで利用するなんとか…

水もぬるみ始め、そろそろお花見の予定を考えないと行けない時期となりました。皆様に於かれましてはご清祥の事とお慶び申し上げますです、はい。
そんなこんななのですが、日曜日の昼下がりはうちの子がピアノを練習してたりするのです。このところメヌエットとかやってて、なまじ知っている曲ということで今このテキスト入力中にも頭の中を回り続けている次第です。しょうがないので他の曲聞いたりしているのですが止めるとまた例の曲が戻ってきて……なんだかこのループは当分続きそうです。今週は違う曲やってたから止まるかなって思ったのですが相変わらずわたしの頭の中はアレがエンドレスでりぴーとしているというw
話は全く関連しませんが、今回お届けするのはおなじみの顔認識なのです。今回はMac版のライブラリを更新します。OpenCVのバージョンは2.4.5です。

さて、先ずはライブラリから。こちらはFrameworkになっていますから/Library/Frameworksフォルダに投入します。haarcascadesフォルダは起動ディスクの第一階層にコピーしておきましょう。いずれもdmgファイルを開くとエイリアスを用意してあります。

OpenCV.Framework(ver.2.4.5)+haarcascadeFiles
https://goo.gl/Pi5agd

そしてExtendscript用のエクスターナル・オブジェクトはこちら
https://goo.gl/v7GLxK

利用例です。Indesign上で顔を適切な状態で配置するスクリプトです。どんな画像サイズ、位置であっても顔を検出して適切に調整してくれる優れものです。

if (ExternalObject.AdobeXMPScript == undefined) {
 ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');
 }
var cascade = "/haarcascades/haarcascade_frontalface_alt2.xml";
var i;
var f = File.openDialog ("select a file...");
var tgtFile = f.fsName;
var b = [];
var xmp = new XMPFile( tgtFile, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_READ);
var obj = xmp.getXMP();
b[0] = Number(obj.getProperty(XMPConst.NS_EXIF,"PixelXDimension"));
b[1] = Number(obj.getProperty(XMPConst.NS_EXIF,"PixelYDimension"));
if (isNaN(b[0])){
 b = getDimension(f);
 }
var tgt = app.activeDocument.selection[0];
var bx = tgt.geometricBounds;
var bxw = bx[3] - bx[1];
var bxh = bx[2] - bx[0];
tgt.place(f);

var extObj = new ExternalObject("lib:/faceDetecter64-1.0.2.framework");
 var pos = extObj.trackFace(tgtFile, cascade,1.11, 4, 50);
 $.writeln(pos);
 if (pos.length>0){
 try{
 while (pos.length>4){
 if (pos[pos.length-1]>pos[3])
 for (i=0;i<4;i++) pos.shift();
 else
 for (i=0;i<4;i++) pos.pop();
 }
 var visibleWidth = pos[2] * 1.4; //px
 var visibleHeight = pos[3] * 2; //px;
 var scale = bxw / visibleWidth;
 var imgWidth = b[0] * scale;
 var imgHeight = b[1] * scale;
 var xofst = bx[1] + pos[2] * scale * 0.2 - pos[0] * scale;
 var yofst = bx[0] + pos[3] * scale * 0.4 - pos[1] * scale;
 if (!isNaN(xofst)){
 tgt.graphics[0].geometricBounds = [
 yofst, xofst,
 imgHeight + yofst, imgWidth + xofst];
 }
 extObj.unload();
 }catch(o_O){
 alert(o_O);
 }
 }
 else {
 tgt.fit (FitOptions.proportionally);
 tgt.fit (FitOptions.centerContent);
 }


function getDimension(f){
 f.encoding = 'BINARY';
 var str = "";
 var bds = [];
 if (f.open("r")){
 while(!f.eof){
 var d = readByte(f);
 if (d==0xff){
 d = readByte(f);
 if (d==0xc0){
 bds = getValue(f);
 }
 }
 if (f.tell()>32000) break;
 }
 f.close();
 }
 return bds;
 }

function getValue(f){
 readUShort(f);
 readByte(f);
 var ht = readUShort(f);
 var wd = readUShort (f);
 return [wd, ht];
 }

function readByte(targetFile){
 return targetFile.readch().charCodeAt(0);;
 }

function readUShort(targetFile){
 var result = targetFile.readch().charCodeAt(0) * 256;
 result += targetFile.readch().charCodeAt(0);
 return result;
 }

テスト…

maia-2-1436576

こちらのお嬢さんMaiaちゃんです。
FreeImages.comよりの引用です。
http://www.freeimages.com/photo/maia-2-1436576

こちらをFaceDetectorに通すと

facedetector245_0

こんな具合に顔のエリアサイズとTop-Leftの位置が返ります。

maia-2-1436576detect

こちらはこのエリアを可視化したものです。この情報を基に画像をInDesignに配置したものがこちらです。

facedetector245_1

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中