Post date: May 19, 2013 8:39:53 AM
やっとマルチマーカーの処理ができたのでメモ。
諸事情により、Processingのヴァージョンは1.5.1、カメラのキャプチャにはGSVideoを使用している。
以下がマルチマーカーのプログラムである。NyIdマーカー0と1を用意し、どちらかが写っていればマーカー0の座標に直してくれるプログラムである。
マーカー間の変換行列は毎回計算している。もし、マーカー同士の位置関係が変わらないのならば、ここは定数としたほうが精度が上がると思われる。
import codeanticode.gsvideo.*;
import jp.nyatla.nyar4psg.*;
GSCapture cam;
MultiMarker nya;
PMatrix3D trans[]=new PMatrix3D[2];
void setup() {
size(640, 480, P3D);
colorMode(RGB, 100);
println(MultiMarker.VERSION);
cam=new GSCapture(this, 640, 480);
nya=new MultiMarker(this, width, height, "camera_para.dat", NyAR4PsgConfig.CONFIG_PSG);
nya.addNyIdMarker(0, 40);
nya.addNyIdMarker(1, 40);
cam.start();
trans[0]=new PMatrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);//単位行列~
}
void draw()
{
if (cam.available() !=true) {
return;
}
cam.read();
nya.detect(cam);
background(0);
nya.drawBackground(cam);//frustumを考慮した背景描画
if (nya.isExistMarker(0)&&nya.isExistMarker(1)) {
nya.beginTransform(0);
fill(255, 0, 0);
translate(0, 0, 20);
box(40);
matrixload();
nya.endTransform();
}
else {
for (int i=0;i<2;i++) {
if (!nya.isExistMarker(i))continue;
nya.beginTransform(i);
PMatrix3D A=nya.getMarkerMatrix(i);
PMatrix3D B=new PMatrix3D(trans[i]);
A.apply(B);
setMatrix(A);
fill(255, 0, 0);
translate(0, 0, 20);
box(40);
nya.endTransform();
}
}
}
void matrixload() {
//1のマーカーから0のマーカーに移動
trans[1]=nya.getMarkerMatrix(1);
trans[1].invert();
PMatrix3D trans2=nya.getMarkerMatrix(0);
trans[1].apply(trans2);
}
配列transのn番目の要素にマーカー0とマーカーnとの相対座標関係を保管している。
つまり、trans[0]はマーカー0からマーカー0までの相対座標関係を保管するため、これは単位行列となる。
関数matrixload()で、マーカー1からマーカー0への相対座標を求めている。→マーカー相対座標 Processing
実際にtransで座標移動しているのはこの部分である。
PMatrix3D A=nya.getMarkerMatrix(i);
PMatrix3D B=new PMatrix3D(trans[i]);
A.apply(B);
setMatrix(A);
マーカーAからマーカーBに移動する行列TはT=A^-1 Bであるので、
ATで元の行列変換Bを再現できるというわけである。