NyARToolKit has been moved to github.
NyARToolkit本体は、カメラ歪み計算の事前マップ化と、主成分積クラス化による高速化がメインです。
sandboxには、9割以上を固定小数点計算化し、誤差補正計算を省略したPDA向けのクラス群があります。
joglのサンプルのSimpleLite等に使われるGLNyARParamクラスは廃止され、ユーティリティクラスNyARGLUtilへ関数を統合しています。
●箇条書
+sandboxに固定小数点計算版クラス群を追加
+GLNyARParamの削除と、関数群のNyARGLUtilへの統合
+カメラ歪みクラスの事前計算化と、マップクラスの追加
+主成分分析クラス(PCA)のpca2dパッケージへの分離
+他、雑多な修正
Index: trunk/test/jp/nyatla/nyartoolkit/dev/LabelingCamera.java
===================================================================
--- trunk/test/jp/nyatla/nyartoolkit/dev/LabelingCamera.java (revision 162)
+++ trunk/test/jp/nyatla/nyartoolkit/dev/LabelingCamera.java (revision 199)
@@ -12,128 +12,940 @@
import jp.nyatla.nyartoolkit.NyARException;
import jp.nyatla.nyartoolkit.jmf.utils.*;
+import jp.nyatla.nyartoolkit.core.*;
+
import java.awt.*;
-
+import jp.nyatla.nyartoolkit.core.INyARSquareDetector;
import jp.nyatla.nyartoolkit.core.labeling.*;
+import jp.nyatla.nyartoolkit.core.match.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.pca2d.INyARPca2d;
+import jp.nyatla.nyartoolkit.core.pca2d.NyARPca2d_MatrixPCA_O2;
+import jp.nyatla.nyartoolkit.core.pickup.*;
import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;
import jp.nyatla.nyartoolkit.core.rasterfilter.*;
import jp.nyatla.nyartoolkit.core2.rasteranalyzer.*;
import jp.nyatla.nyartoolkit.core2.rasteranalyzer.threshold.*;
import jp.nyatla.nyartoolkit.core2.rasterfilter.gs2bin.*;
import jp.nyatla.nyartoolkit.core2.rasterfilter.rgb2gs.NyARRasterFilter_RgbAve;
+import jp.nyatla.utils.NyObjectStack;
import jp.nyatla.utils.j2se.LabelingBufferdImage;
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;
+import jp.nyatla.nyartoolkit.core.transmat.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;
-public class LabelingCamera extends Frame implements JmfCaptureListener {
- private JmfNyARRaster_RGB _raster;
- private JmfCameraCapture capture;
+///**
+// * QRコードのシンボルを結びつける偉いクラス
+// *
+// */
+//class NyQrCodeSymbolBinder
+//{
+// LabelingBufferdImage bimg;
+//
+// NyARIntPoint[][] _sqare;
+// /**
+// * 最小の三角形を構成する頂点セットを得る
+// * @param i_s0
+// * @param i_s1
+// * @param i_s2
+// * @param o_vertex
+// */
+// public static void getMinimumTriangleVertex(NyARSquare[] i_sqare,int[] o_vertex_id)
+// {
+// //辺の長さが最小になる頂点の組合せを探す
+// int d;
+// int x,y;
+// int dmax=0x7fffffff;
+// final NyARIntPoint[] vertex0=i_sqare[0].imvertex;
+// final NyARIntPoint[] vertex1=i_sqare[1].imvertex;
+// final NyARIntPoint[] vertex2=i_sqare[2].imvertex;
+// for(int i=0;i<4;i++)
+// {
+// for(int i2=0;i2<4;i2++)
+// {
+// for(int i3=0;i3<4;i3++){
+// x=vertex0[i].x-vertex2[i3].x;
+// y=vertex0[i].y-vertex2[i3].y;
+// d=x*x+y*y;
+// x=vertex1[i2].x-vertex2[i3].x;
+// y=vertex1[i2].y-vertex2[i3].y;
+// d+=x*x+y*y;
+// x=vertex1[i2].x-vertex0[i].x;
+// y=vertex1[i2].y-vertex0[i].y;
+// d+=x*x+y*y;
+// if(d<dmax){
+// dmax=d;
+// o_vertex_id[0]=i;
+// o_vertex_id[1]=i2;
+// o_vertex_id[2]=i3;
+// }
+// }
+// }
+// }
+// return;
+// }
+// /**
+// * 2矩形の頂点距離が最低の組合せを探す
+// * @param i_sqare
+// * @param o_vertex_id
+// */
+// public static void getMinimumLineVertex(NyARIntPoint[] i_sqare0,NyARIntPoint[] i_sqare1,int[] o_vertex_id)
+// {
+// //辺の長さが最小になる頂点の組合せを探す
+// int d;
+// int x,y;
+// int dmax=0x7fffffff;
+// for(int i=0;i<4;i++)
+// {
+// for(int i2=0;i2<4;i2++)
+// {
+// x=i_sqare1[i2].x-i_sqare0[i].x;
+// y=i_sqare1[i2].y-i_sqare0[i].y;
+// d=x*x+y*y;
+// if(d<dmax){
+// dmax=d;
+// o_vertex_id[0]=i;
+// o_vertex_id[1]=i2;
+// }
+// }
+// }
+// return;
+// }
+//
+// /**
+// * キーシンボルのインデックスを得る
+// * @param i_sqare
+// * @param i_vertex_id
+// * 最小三角形の頂点IDセット
+// * @return
+// */
+// public static int getKeySymble(NyARSquare[] i_sqare,int[] i_vertex_id)
+// {
+// //シンボルグループの重心を計算
+// int cx,cy;
+// cx=cy=0;
+// for(int i=0;i<3;i++)
+// {
+// final NyARIntPoint[] sq_ptr=i_sqare[i].imvertex;
+// cx+=sq_ptr[0].x;
+// cx+=sq_ptr[1].x;
+// cx+=sq_ptr[2].x;
+// cx+=sq_ptr[3].x;
+// cy+=sq_ptr[0].y;
+// cy+=sq_ptr[1].y;
+// cy+=sq_ptr[2].y;
+// cy+=sq_ptr[3].y;
+// }
+// cx/=12;
+// cy/=12;
+// //前段で探した頂点候補のうち、最も重心に近いものが中心シンボルの内対角点
+// int key_symble_idx=0;
+// int x=i_sqare[0].imvertex[i_vertex_id[0]].x-cx;
+// int y=i_sqare[0].imvertex[i_vertex_id[0]].y-cy;
+// int dmax=x*x+y*y;
+// for(int i=1;i<3;i++){
+// x=i_sqare[i].imvertex[i_vertex_id[i]].x-cx;
+// y=i_sqare[i].imvertex[i_vertex_id[i]].y-cy;
+// final int d=x*x+y*y;
+// if(d<dmax){
+// dmax=d;
+// key_symble_idx=i;
+// }
+// }
+// return key_symble_idx;
+// }
+// public void bindSquare(NyARSquare i_sq1,int i_lv1,NyARSquare i_sq2,int i_lv2)
+// {
+// NyARSquare new_square=new NyARSquare();
+// //4辺の式を計算
+// new_square.line[0].copyFrom(i_sq1.line[(i_lv1)%4]);
+// new_square.line[1].copyFrom(i_sq1.line[(i_lv1+3)%4]);
+// new_square.line[2].copyFrom(i_sq2.line[(i_lv2)%4]);
+// new_square.line[3].copyFrom(i_sq2.line[(i_lv2+3)%4]);
+// //歪み無しの座標系を計算
+// final NyARDoublePoint2d[] l_sqvertex = new_square.sqvertex;
+// final NyARLinear[] l_line = new_square.line;
+// for (int i = 0; i < 4; i++) {
+// final NyARLinear l_line_i = l_line[i];
+// final NyARLinear l_line_2 = l_line[(i + 3) % 4];
+// final double w1 = l_line_2.run * l_line_i.rise - l_line_i.run * l_line_2.rise;
+// if (w1 == 0.0) {
+// return;
+// }
+// l_sqvertex[i].x = (l_line_2.rise * l_line_i.intercept - l_line_i.rise * l_line_2.intercept) / w1;
+// l_sqvertex[i].y = (l_line_i.run * l_line_2.intercept - l_line_2.run * l_line_i.intercept) / w1;
+//// // 頂点インデクスから頂点座標を得て保存
+//// l_imvertex[i].x = i_xcoord[i_mkvertex[i]];
+//// l_imvertex[i].y = i_ycoord[i_mkvertex[i]];
+// }
+// Graphics g=this.bimg.getGraphics();
+// g.setColor(Color.red);
+// int[] x=new int[4];
+// int[] y=new int[4];
+// for(int i=0;i<4;i++){
+// x[i]=(int)l_sqvertex[i].x;
+// y[i]=(int)l_sqvertex[i].y;
+// }
+// g.drawPolygon(x,y,4);
+// //基準点はVertexをそのまま採用
+// //2個の想定点は座標を逆変換して設定
+// }
+// /**
+// *
+// * @param i_sq
+// * @param o_sq
+// * @return
+// */
+// public boolean margeEdge(NyARSquare[] i_sq,NyARSquare o_sq)
+// {
+// int[] minimum_triangle_vertex=new int[3];
+// int[] minimum_line_vertex=new int[2];
+//
+// //辺の長さが最小になる頂点の組合せを探す
+// getMinimumTriangleVertex(i_sq,minimum_triangle_vertex);
+//
+// //キーシンボルのインデクス番号を得る
+// int key_simble_idx=getKeySymble(i_sq,minimum_triangle_vertex);
+//
+// //エッジシンボルのインデックス番号を決める
+// int symbol_e1_idx=(key_simble_idx+1)%3;
+// int symbol_e2_idx=(key_simble_idx+2)%3;
+//
+// //エッジシンボル間で最短距離を取る頂点ペアを取る
+// //(角度を低くするとエラーが出やすい。対角線との類似性を確認する方法のほうがいい。多分)
+// getMinimumLineVertex(i_sq[symbol_e1_idx].imvertex,i_sq[symbol_e2_idx].imvertex,minimum_line_vertex);
+//
+// //内対角を外対角に変換
+// int lv1=(minimum_line_vertex[0]+2)%4;
+// int lv2=(minimum_line_vertex[1]+2)%4;
+// int kv =(minimum_triangle_vertex[key_simble_idx]+2)%4;
+// //矩形のバインド
+// bindSquare(i_sq[symbol_e1_idx],lv1,i_sq[symbol_e2_idx],lv2);
+//
+//
+// Graphics g=this.bimg.getGraphics();
+// //内対角に緑の点を打つ
+// g.setColor(Color.green);
+// g.fillRect(i_sq[symbol_e1_idx].imvertex[lv1].x-2,i_sq[symbol_e1_idx].imvertex[lv1].y-2,4,4);
+// g.fillRect(i_sq[symbol_e2_idx].imvertex[lv2].x-2,i_sq[symbol_e2_idx].imvertex[lv2].y-2,4,4);
+//// g.fillRect(i_sq[symbol_e2_idx][minimum_line_vertex[1]].x-2,i_sq[symbol_e2_idx][minimum_line_vertex[1]].y-2,4,4);
+//
+//
+// //中央の中心エッジから最も遠い点が
+// //両端のエッジも探す
+//
+//
+//
+//
+//// this.bimg.getGraphics().fillRect(i_sq[edge1_id][vid1_id].x,i_sq[edge1_id][vid1_id].y,5,5);
+//
+// for (int i = 0; i <3; i++) {
+// int[] xp=new int[4];
+// int[] yp=new int[4];
+// for(int i2=0;i2<4;i2++){
+// xp[i2]=i_sq[i].imvertex[i2].x;
+// yp[i2]=i_sq[i].imvertex[i2].y;
+// }
+// this.bimg.getGraphics().setColor(Color.RED);
+// this.bimg.getGraphics().drawPolygon(xp, yp,4);
+// }
+//
+//
+// return false;
+//
+//
+//
+//
+//
+//
+// }
+//
+//
+//
+//
+//}
- public LabelingCamera() throws NyARException, NyARException
- {
- setBounds(0, 0, 640 + 64, 720 + 64);
- // キャプチャの準備
- capture = new JmfCameraCapture(320, 240, 30f,
- JmfCameraCapture.PIXEL_FORMAT_RGB);
- capture.setCaptureListener(this);
- // キャプチャイメージ用のラスタを準備
- this._raster = new JmfNyARRaster_RGB(320, 240);
- }
-
- private NyARBinRaster _binraster1=new NyARBinRaster(320,240);
- private NyARGlayscaleRaster _gsraster1=new NyARGlayscaleRaster(320,240);
- private NyARLabelingImage _limage=new NyARLabelingImage(320, 240);
- private LabelingBufferdImage _bimg=new LabelingBufferdImage(320, 240,LabelingBufferdImage.COLOR_256_MONO);
- private LabelingBufferdImage _bimg2=new LabelingBufferdImage(320, 240,LabelingBufferdImage.COLOR_256_MONO);
+/**
+ * 矩形座標をPCAではなく、頂点座標そのものからSquare位置を計算するクラス
+ *
+ */
+class NyARQRCodeDetector implements INyARSquareDetector
+{
+ LabelingBufferdImage bimg;
+ private static final double VERTEX_FACTOR = 2.0;// 線検出のファクタ
- public void onUpdateBuffer(Buffer i_buffer)
- {
- try {
- // キャプチャしたバッファをラスタにセット
- _raster.setBuffer(i_buffer);
-
- Graphics g = getGraphics();
- //キャプチャ画像
- BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());
- Image img = b2i.createImage(i_buffer);
- this.getGraphics().drawImage(img, 32, 32, this);
-
- INyARRasterFilter_GsToBin filter_gs2bin;
- //画像1
- INyARRasterFilter_RgbToGs filter_rgb2gs=new NyARRasterFilter_RgbAve();
- filter_rgb2gs.doFilter(_raster, _gsraster1);
- this._bimg2.drawImage(this._gsraster1);
- this.getGraphics().drawImage(this._bimg2, 32+320, 32,320+320+32,240+32,0,240,320,0, this);
+ private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000
- //画像2
- filter_gs2bin=new NyARRasterFilter_ARToolKitThreshold(128);
- filter_gs2bin.doFilter(_gsraster1, _binraster1);
- this._bimg.drawImage(_binraster1);
- this.getGraphics().drawImage(this._bimg, 32, 32+240,320+32,240+32+240,0,240,320,0, this);
- //画像3
- //threshold.debugDrawHistgramMap(_workraster, _workraster2);
- //this._bimg2.setImage(this._workraster2);
- //this.getGraphics().drawImage(this._bimg2, 32+320, 32+240,320+32+320,240+32+240,0,240,320,0, this);
+ private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70
- //画像4
- NyARRasterThresholdAnalyzer_SlidePTile threshold=new NyARRasterThresholdAnalyzer_SlidePTile(15);
- threshold.analyzeRaster(_gsraster1);
- filter_gs2bin=new NyARRasterFilter_AreaAverage();
- filter_gs2bin.doFilter(_gsraster1, _binraster1);
- this._bimg.drawImage(_binraster1);
-
- NyARRasterDetector_QrCodeEdge detector=new NyARRasterDetector_QrCodeEdge(10000);
- detector.analyzeRaster(_binraster1);
-
- this._bimg.overlayData(detector.geResult());
-
- this.getGraphics().drawImage(this._bimg, 32, 32+480,320+32,480+32+240,0,240,320,0, this);
- //画像5
-
-
-/* threshold2.debugDrawHistgramMap(_workraster, _workraster2);
- this._bimg2.drawImage(this._workraster2);
- this.getGraphics().drawImage(this._bimg2, 32+320, 32+480,320+32+320,480+32+240,0,240,320,0, this);
-*/
-
- // this.getGraphics().drawImage(this._bimg, 32, 32, this);
+ private final int _width;
+ private final int _height;
- } catch (Exception e) {
- e.printStackTrace();
+ private final NyARLabeling_ARToolKit _labeling;
+
+ private final NyARLabelingImage _limage;
+
+ private final NyARCameraDistortionFactor _dist_factor_ref;
+
+ /**
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。
+ *
+ * @param i_param
+ */
+ public NyARQRCodeDetector(NyARCameraDistortionFactor i_dist_factor_ref, NyARIntSize i_size) throws NyARException
+ {
+ this._width = i_size.w;
+ this._height = i_size.h;
+ this._dist_factor_ref = i_dist_factor_ref;
+ this._labeling = new NyARLabeling_ARToolKit();
+ this._limage = new NyARLabelingImage(this._width, this._height);
+ this._labeling.attachDestination(this._limage);
+
+ // 輪郭の最大長は画面に映りうる最大の長方形サイズ。
+ int number_of_coord = (this._width + this._height) * 2;
+
+ // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。
+ this._max_coord = number_of_coord;
+ this._xcoord = new int[number_of_coord * 2];
+ this._ycoord = new int[number_of_coord * 2];
}
- }
- private INyARLabeling labelingFactory(int i_idx)
- {
- switch(i_idx){
- case 0:{NyARLabeling_ARToolKit l=new NyARLabeling_ARToolKit();l.setThresh(4);return l;}
- case 1:{return new NyLineLabeling();}
+ private final int _max_coord;
+
+ private final int[] _xcoord;
+
+ private final int[] _ycoord;
+
+ private void normalizeCoord(int[] i_coord_x, int[] i_coord_y, int i_index, int i_coord_num)
+ {
+ // vertex1を境界にして、後方に配列を連結
+ System.arraycopy(i_coord_x, 1, i_coord_x, i_coord_num, i_index);
+ System.arraycopy(i_coord_y, 1, i_coord_y, i_coord_num, i_index);
}
- return null;
+
+ private final int[] __detectMarker_mkvertex = new int[5];
+
+ /**
+ * ARMarkerInfo2 *arDetectMarker2( ARInt16 *limage, int label_num, int *label_ref,int *warea, double *wpos, int *wclip,int area_max, int area_min, double
+ * factor, int *marker_num ) 関数の代替品 ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。 関数はo_marker_listに重なりを除外したマーカーリストを作成します。
+ *
+ * @param i_raster
+ * 解析する2値ラスタイメージを指定します。
+ * @param o_square_stack
+ * 抽出した正方形候補を格納するリスト
+ * @throws NyARException
+ */
+ public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException
+ {
+ final INyARLabeling labeling_proc = this._labeling;
+ final NyARLabelingImage limage = this._limage;
+
+ // 初期化
+
+ // マーカーホルダをリセット
+ o_square_stack.clear();
+
+ // ラベリング
+ labeling_proc.labeling(i_raster);
+
+ // ラベル数が0ならここまで
+ final int label_num = limage.getLabelStack().getLength();
+ if (label_num < 1) {
+ return;
+ }
+
+ final NyARLabelingLabelStack stack = limage.getLabelStack();
+ final NyARLabelingLabel[] labels = (NyARLabelingLabel[]) stack.getArray();
+
+ // ラベルを大きい順に整列
+ stack.sortByArea();
+
+ // デカいラベルを読み飛ばし
+ int i;
+ for (i = 0; i < label_num; i++) {
+ // 検査対象内のラベルサイズになるまで無視
+ if (labels[i].area <= AR_AREA_MAX) {
+ break;
+ }
+ }
+
+ final int xsize = this._width;
+ final int ysize = this._height;
+ final int[] xcoord = this._xcoord;
+ final int[] ycoord = this._ycoord;
+ final int coord_max = this._max_coord;
+ final int[] mkvertex = this.__detectMarker_mkvertex;
+ final int[][] buf = (int[][]) limage.getBufferReader().getBuffer();
+ final int[] indextable = limage.getIndexArray();
+ int coord_num;
+ int label_area;
+ NyARLabelingLabel label_pt;
+ NyARSquareStack wk_stack=new NyARSquareStack(100);
+
+ for (; i < label_num; i++) {
+ label_pt = labels[i];
+ label_area = label_pt.area;
+ // 検査対象サイズよりも小さくなったら終了
+ if (label_area < AR_AREA_MIN) {
+ break;
+ }
+ // クリップ領域が画面の枠に接していれば除外
+ if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){
+ continue;
+ }
+ if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){
+ continue;
+ }
+ // 特徴点候補であるかを確認する。
+ if (!hasQrEdgeFeature(buf, indextable, label_pt)) {
+ continue;
+ }
+
+ // 輪郭を取得
+ coord_num = limage.getContour(i, coord_max, xcoord, ycoord);
+ if (coord_num == coord_max) {
+ // 輪郭が大きすぎる。
+ continue;
+ }
+ // 頂点候補のインデクスを取得
+ final int vertex1 = scanVertex(xcoord, ycoord, coord_num);
+
+ // 頂点候補(vertex1)を先頭に並べなおした配列を作成する。
+ normalizeCoord(xcoord, ycoord, vertex1, coord_num);
+
+ // 頂点情報を取得
+ if (!getSquareVertex(xcoord, ycoord, vertex1, coord_num, label_area, mkvertex)) {
+ continue;
+ }
+ NyARSquare square=(NyARSquare)wk_stack.prePush();
+ if(!getSquareLine(mkvertex,xcoord,ycoord,square)){
+ wk_stack.pop();
+ continue;
+ }
+ }
+ bindQrcodeEdge(wk_stack);
+ //エッジ同士の相関関係をしらべる。
+
+ return;
+ }
+ /**
+ *
+ * @param i_sq
+ * @param o_sq
+ * @return
+ */
+ public boolean margeEdge(NyARSquare[] i_sq,NyARSquare o_sq)
+ {
+ NyQrCodeSymbolBinder binder=new NyQrCodeSymbolBinder();
+ binder.bimg=this.bimg;
+ binder.(i_sq, o_sq);
+
+ return false;
+
+
+
+
+ }
+ /**
+ * QRコードのエッジペアを作る
+ * @param i_square_stack
+ */
+ public void bindQrcodeEdge(NyARSquareStack i_square_stack)
+ {
+
+ NyARSquare sq_ptr1,sq_ptr2,sq_ptr3;
+ int number_of_edge=i_square_stack.getLength();
+ if(number_of_edge<3){
+ return;
+ }
+ NyARSquare[] sa=(NyARSquare[])i_square_stack.getArray();
+ for(int i=0;i<number_of_edge;i++)
+ {
+ for(int i2=i+1;i2<number_of_edge;i2++)
+ {
+ sq_ptr2=sa[i2];
+ for(int i3=i2+1;i3<number_of_edge;i3++){
+ sq_ptr3=sa[i3];
+ //3個のエッジの関連性を確認する。
+ margeEdge(sa,null);
+ }
+ //
+ }
+ }
+ }
+ /**
+ * 2つの頂点座標を結ぶ直線から、NyARLinearを計算する。
+ *
+ * @param i_v1
+ * @param i_v2
+ * @param o_line
+ */
+ final private void getLine(NyARDoublePoint2d i_v1, NyARDoublePoint2d i_v2, NyARLinear o_line)
+ {
+ final double x = i_v1.x - i_v2.x;
+ final double y = i_v1.y - i_v2.y;
+ final double x2 = x * x;
+ final double y2 = y * y;
+ final double rise_ = Math.sqrt(x2 / (x2 + y2));
+ o_line.rise = rise_;
+ o_line.run = Math.sqrt(y2 / (x2 + y2));
+ if (x < 0) {
+ if (y < 0) {
+ o_line.rise = -o_line.rise;
+ } else {
+ o_line.rise = -o_line.rise;
+ o_line.run = -o_line.run;
+ }
+ } else {
+ if (y < 0) {
+ o_line.rise = -o_line.rise;
+ o_line.run = -o_line.run;
+ } else {
+ o_line.rise = -o_line.rise;
+ }
+ }
+ o_line.intercept = (i_v1.y + (o_line.run / o_line.rise) * (i_v1.x)) * rise_;
+
+ }
+ private final INyARPca2d _pca=new NyARPca2d_MatrixPCA_O2(100);
+ private final NyARDoubleMatrix22 __getSquareLine_evec=new NyARDoubleMatrix22();
+ private final NyARDoublePoint2d __getSquareLine_mean=new NyARDoublePoint2d();
+ private final NyARDoublePoint2d __getSquareLine_ev=new NyARDoublePoint2d();
+ /**
+ * arGetLine(int x_coord[], int y_coord[], int coord_num,int vertex[], double line[4][3], double v[4][2]) arGetLine2(int x_coord[], int y_coord[], int
+ * coord_num,int vertex[], double line[4][3], double v[4][2], double *dist_factor) の2関数の合成品です。 マーカーのvertex,lineを計算して、結果をo_squareに保管します。
+ * Optimize:STEP[424->391]
+ *
+ * @param i_cparam
+ * @return
+ * @throws NyARException
+ */
+ private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square) throws NyARException
+ {
+ final NyARLinear[] l_line = o_square.line;
+ final NyARCameraDistortionFactor dist_factor=this._dist_factor_ref;
+ final NyARDoubleMatrix22 evec=this.__getSquareLine_evec;
+ final NyARDoublePoint2d mean=this.__getSquareLine_mean;
+ final NyARDoublePoint2d ev=this.__getSquareLine_ev;
-
- }
+
+ for (int i = 0; i < 4; i++) {
+ final double w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;
+ final int st = (int) (i_mkvertex[i] + w1);
+ final int ed = (int) (i_mkvertex[i + 1] - w1);
+ final int n = ed - st + 1;
+ if (n < 2) {
+ // nが2以下でmatrix.PCAを計算することはできないので、エラー
+ return false;
+ }
+ //主成分分析する。
+ this._pca.pcaWithDistortionFactor(i_xcoord, i_ycoord, st, n,dist_factor, evec, ev,mean);
+ final NyARLinear l_line_i = l_line[i];
+ l_line_i.run = evec.m01;// line[i][0] = evec->m[1];
+ l_line_i.rise = -evec.m00;// line[i][1] = -evec->m[0];
+ l_line_i.intercept = -(l_line_i.run * mean.x + l_line_i.rise * mean.y);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);
+ }
- private void startCapture()
- {
- try {
- capture.start();
- } catch (Exception e) {
- e.printStackTrace();
+ final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;
+ final NyARIntPoint[] l_imvertex = o_square.imvertex;
+ for (int i = 0; i < 4; i++) {
+ final NyARLinear l_line_i = l_line[i];
+ final NyARLinear l_line_2 = l_line[(i + 3) % 4];
+ final double w1 = l_line_2.run * l_line_i.rise - l_line_i.run * l_line_2.rise;
+ if (w1 == 0.0) {
+ return false;
+ }
+ l_sqvertex[i].x = (l_line_2.rise * l_line_i.intercept - l_line_i.rise * l_line_2.intercept) / w1;
+ l_sqvertex[i].y = (l_line_i.run * l_line_2.intercept - l_line_2.run * l_line_i.intercept) / w1;
+ // 頂点インデクスから頂点座標を得て保存
+ l_imvertex[i].x = i_xcoord[i_mkvertex[i]];
+ l_imvertex[i].y = i_ycoord[i_mkvertex[i]];
+ }
+ return true;
}
- }
+ /**
+ * 辺からの対角線が最長になる点を対角線候補として返す。
+ *
+ * @param i_xcoord
+ * @param i_ycoord
+ * @param i_coord_num
+ * @return
+ */
+ private int scanVertex(int[] i_xcoord, int[] i_ycoord, int i_coord_num)
+ {
+ final int sx = i_xcoord[0];
+ final int sy = i_ycoord[0];
+ int d = 0;
+ int w, x, y;
+ int ret = 0;
+ for (int i = 1; i < i_coord_num; i++) {
+ x = i_xcoord[i] - sx;
+ y = i_ycoord[i] - sy;
+ w = x * x + y * y;
+ if (w > d) {
+ d = w;
+ ret = i;
+ }
+ // ここでうまく終了条件入れられないかな。
+ }
+ return ret;
+ }
- public static void main(String[] args) {
- try {
- LabelingCamera mainwin = new LabelingCamera();
- mainwin.setVisible(true);
- mainwin.startCapture();
- } catch (Exception e) {
- e.printStackTrace();
+ private final NyARVertexCounter __getSquareVertex_wv1 = new NyARVertexCounter();
+
+ private final NyARVertexCounter __getSquareVertex_wv2 = new NyARVertexCounter();
+
+ /**
+ * static int arDetectMarker2_check_square( int area, ARMarkerInfo2 *marker_info2, double factor ) 関数の代替関数 OPTIMIZED STEP [450->415] o_squareに頂点情報をセットします。
+ *
+ * @param i_x_coord
+ * @param i_y_coord
+ * @param i_vertex1_index
+ * @param i_coord_num
+ * @param i_area
+ * @param o_vertex
+ * 要素数はint[4]である事
+ * @return
+ */
+ private boolean getSquareVertex(int[] i_x_coord, int[] i_y_coord, int i_vertex1_index, int i_coord_num, int i_area, int[] o_vertex)
+ {
+ final NyARVertexCounter wv1 = this.__getSquareVertex_wv1;
+ final NyARVertexCounter wv2 = this.__getSquareVertex_wv2;
+ final int end_of_coord = i_vertex1_index + i_coord_num - 1;
+ final int sx = i_x_coord[i_vertex1_index];// sx = marker_info2->x_coord[0];
+ final int sy = i_y_coord[i_vertex1_index];// sy = marker_info2->y_coord[0];
+ int dmax = 0;
+ int v1 = i_vertex1_index;
+ for (int i = 1 + i_vertex1_index; i < end_of_coord; i++) {// for(i=1;i<marker_info2->coord_num-1;i++)
+ // {
+ final int d = (i_x_coord[i] - sx) * (i_x_coord[i] - sx) + (i_y_coord[i] - sy) * (i_y_coord[i] - sy);
+ if (d > dmax) {
+ dmax = d;
+ v1 = i;
+ }
+ }
+ final double thresh = (i_area / 0.75) * 0.01 * VERTEX_FACTOR;
+
+ o_vertex[0] = i_vertex1_index;
+
+ if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v1, thresh)) { // if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,0,v1,thresh,wv1,&wvnum1)<
+ // 0 ) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v1, end_of_coord, thresh)) {// if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,v1,marker_info2->coord_num-1,thresh,wv2,&wvnum2)
+ // < 0) {
+ return false;
+ }
+
+ int v2;
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {// if(wvnum1 == 1 && wvnum2== 1) {
+ o_vertex[1] = wv1.vertex[0];
+ o_vertex[2] = v1;
+ o_vertex[3] = wv2.vertex[0];
+ } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {// }else if( wvnum1 > 1 && wvnum2== 0) {
+ // 頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。
+ v2 = (v1 - i_vertex1_index) / 2 + i_vertex1_index;
+ if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v2, thresh)) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v2, v1, thresh)) {
+ return false;
+ }
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+ o_vertex[1] = wv1.vertex[0];
+ o_vertex[2] = wv2.vertex[0];
+ o_vertex[3] = v1;
+ } else {
+ return false;
+ }
+ } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) {
+ // v2 = (v1-i_vertex1_index+ end_of_coord-i_vertex1_index) / 2+i_vertex1_index;
+ v2 = (v1 + end_of_coord) / 2;
+
+ if (!wv1.getVertex(i_x_coord, i_y_coord, v1, v2, thresh)) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v2, end_of_coord, thresh)) {
+ return false;
+ }
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+ o_vertex[1] = v1;
+ o_vertex[2] = wv1.vertex[0];
+ o_vertex[3] = wv2.vertex[0];
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ o_vertex[4] = end_of_coord;
+ return true;
}
+ /**
+ * QRコードのエッジ特徴を持つラベルであるかを調べる
+ * @param buf
+ * @param index_table
+ * @param i_label
+ * @return
+ */
+ private boolean hasQrEdgeFeature(int buf[][], int[] index_table, NyARLabelingLabel i_label)
+ {
+ int tx, bx;
+ int w;
+ int i_label_id = i_label.id;
+ int[] limage_j;
+ final int clip_l = i_label.clip_l;
+ final int clip_b = i_label.clip_b;
+ final int clip_r = i_label.clip_r;
+ final int clip_t = i_label.clip_t;
- }
+ tx = bx = 0;
+ // 上接点(→)
+ limage_j = buf[clip_t];
+ for (int i = clip_l; i <= clip_r; i++) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {
+ w = limage_j[i];
+ if (w > 0 && index_table[w - 1] == i_label_id) {
+ tx = i;
+ break;
+ }
+ }
+ // 下接点(←)
+ limage_j = buf[clip_b];
+ for (int i = clip_r; i >= clip_l; i--) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {
+ w = limage_j[i];
+ if (w > 0 && index_table[w - 1] == i_label_id) {
+ bx = i;
+ break;
+ }
+ }
+ final int cx = (clip_l + clip_r) / 2;
+ final int cy = (clip_t + clip_b) / 2;
+ // 横断チェック(中心から線を引いて、101になるかしらべる)
+ if (!checkDiagonalLine(buf, cx, cy, bx, clip_b)) {
+ return false;
+ }
+ if (!checkDiagonalLine(buf, tx, clip_t, cx, cy)) {
+ return false;
+ }
+ return true;
+ }
+ /**
+ * 対角線のパターンを調べる。
+ *
+ * @param buf
+ * @param i_px1
+ * @param i_py1
+ * @param i_px2
+ * @param i_py2
+ * @return
+ */
+ private boolean checkDiagonalLine(int[][] buf, int i_px1, int i_py1, int i_px2, int i_py2)
+ {
+ int sub_y = i_py2 - i_py1;
+ int sub_x = i_px2 - i_px1;
+ // 黒
+ int i = 0;
+ for (; i < sub_y; i++) {
+ int yp = i_py1 + i;
+ int xp = i_px1 + i * sub_x / sub_y;
+ if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) {
+ break;
+ }
+
+ }
+ if (i == sub_y) {
+ return false;
+ }
+ // 白
+ for (; i < sub_y; i++) {
+ int yp = i_py1 + i;
+ int xp = i_px1 + i * sub_x / sub_y;
+ if (buf[yp][xp] != 0 && buf[yp][xp-1] != 0 && buf[yp][xp+1] != 0) {
+ break;
+ }
+
+ }
+ if (i == sub_y) {
+ return false;
+ }
+ // 黒
+ for (; i < sub_y; i++) {
+ int yp = i_py1 + i;
+ int xp = i_px1 + i * sub_x / sub_y;
+ if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) {
+ break;
+ }
+
+ }
+ if (i != sub_y) {
+ return false;
+ }
+ // 端まで到達したらOK
+ return true;
+ }
+
}
+
+
+public class LabelingCamera extends Frame implements JmfCaptureListener
+{
+ private final String camera_file = "../Data/camera_para.dat";
+
+ private JmfNyARRaster_RGB _raster;
+
+ private JmfCameraCapture capture;
+ private NyARParam ap;
+ public LabelingCamera() throws NyARException, NyARException
+ {
+ setBounds(0, 0, 640 + 64, 720 + 64);
+ // キャプチャの準備
+ capture = new JmfCameraCapture(320, 240, 30f, JmfCameraCapture.PIXEL_FORMAT_RGB);
+ capture.setCaptureListener(this);
+
+ // キャプチャイメージ用のラスタを準備
+ this._raster = new JmfNyARRaster_RGB(320, 240);
+
+ // AR用カメラパラメタファイルをロード
+ ap = new NyARParam();
+ ap.loadARParamFromFile(camera_file);
+ ap.changeScreenSize(320, 240);
+
+
+ }
+
+ // そのラベルが特徴点候補か返す。
+
+ private NyARBinRaster _binraster1 = new NyARBinRaster(320, 240);
+
+ private NyARGrayscaleRaster _gsraster1 = new NyARGrayscaleRaster(320, 240);
+
+ private NyARLabelingImage _limage = new NyARLabelingImage(320, 240);
+
+ private LabelingBufferdImage _bimg = new LabelingBufferdImage(320, 240);
+
+ private NyARRasterFilter_ARToolkitThreshold filter_gs2bin;
+
+ public void onUpdateBuffer(Buffer i_buffer)
+ {
+ NyARRasterFilter_AreaAverage gs2bin=new NyARRasterFilter_AreaAverage();
+
+ try {
+ // キャプチャしたバッファをラスタにセット
+ _raster.setBuffer(i_buffer);
+
+ Graphics g = getGraphics();
+ // キャプチャ画像
+ BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());
+ Image img = b2i.createImage(i_buffer);
+ this.getGraphics().drawImage(img, 32, 32, this);
+
+ // 画像1
+ INyARRasterFilter_RgbToGs filter_rgb2gs = new NyARRasterFilter_RgbAve();
+ filter_rgb2gs.doFilter(_raster, _gsraster1);
+ this._bimg.drawImage(this._gsraster1);
+ this.getGraphics().drawImage(this._bimg, 32 + 320, 32, 320 + 320 + 32, 240 + 32, 0, 240, 320, 0, this);
+
+
+ // 画像2
+ gs2bin.doFilter(_gsraster1, _binraster1);
+ this._bimg.drawImage(_binraster1);
+ this.getGraphics().drawImage(this._bimg, 32, 32 + 240, 320 + 32, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+ // 画像3
+ NyARLabelingImage limage = new NyARLabelingImage(320, 240);
+ NyARLabeling_ARToolKit labeling = new NyARLabeling_ARToolKit();
+ labeling.attachDestination(limage);
+ labeling.labeling(_binraster1);
+ this._bimg.drawImage(this._gsraster1);
+ NyARLabelingLabel[] labels = (NyARLabelingLabel[]) limage.getLabelStack().getArray();
+
+ NyARSquareStack stack = new NyARSquareStack(100);
+ NyARQRCodeDetector detect = new NyARQRCodeDetector(ap.getDistortionFactor(), new NyARIntSize(320,240));
+ detect.bimg=this._bimg;
+
+ detect.detectMarker(_binraster1, stack);
+ for (int i = 0; i < stack.getLength(); i++) {
+ NyARSquare[] square_ptr = (NyARSquare[]) stack.getArray();
+ int[] xp=new int[4];
+ int[] yp=new int[4];
+ for(int i2=0;i2<4;i2++){
+ xp[i2]=square_ptr[i].imvertex[i2].x;
+ yp[i2]=square_ptr[i].imvertex[i2].y;
+ }
+ this._bimg.getGraphics().setColor(Color.RED);
+ this._bimg.getGraphics().drawPolygon(xp, yp,2);
+ }
+ this.getGraphics().drawImage(this._bimg, 32 + 320, 32 + 240, 320 + 32 + 320, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+ // 画像3
+ // threshold.debugDrawHistgramMap(_workraster, _workraster2);
+ // this._bimg2.setImage(this._workraster2);
+ // this.getGraphics().drawImage(this._bimg2, 32+320, 32+240,320+32+320,240+32+240,0,240,320,0, this);
+
+ // 画像4
+ // NyARRasterThresholdAnalyzer_SlidePTile threshold=new NyARRasterThresholdAnalyzer_SlidePTile(15);
+ // threshold.analyzeRaster(_gsraster1);
+ // filter_gs2bin=new NyARRasterFilter_AreaAverage();
+ // filter_gs2bin.doFilter(_gsraster1, _binraster1);
+ // this._bimg.drawImage(_binraster1);
+
+ // NyARRasterDetector_QrCodeEdge detector=new NyARRasterDetector_QrCodeEdge(10000);
+ // detector.analyzeRaster(_binraster1);
+
+ // this._bimg.overlayData(detector.geResult());
+
+ // this.getGraphics().drawImage(this._bimg, 32, 32+480,320+32,480+32+240,0,240,320,0, this);
+ // 画像5
+
+ /*
+ * threshold2.debugDrawHistgramMap(_workraster, _workraster2); this._bimg2.drawImage(this._workraster2); this.getGraphics().drawImage(this._bimg2,
+ * 32+320, 32+480,320+32+320,480+32+240,0,240,320,0, this);
+ */
+
+ // this.getGraphics().drawImage(this._bimg, 32, 32, this);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ private INyARLabeling labelingFactory(int i_idx)
+ {
+ // switch(i_idx){
+ // case 0:{NyARLabeling_ARToolKit l=new NyARLabeling_ARToolKit();l.setThresh(4);return l;}
+ // case 1:{return new NyLineLabeling();}
+ // }
+ return null;
+
+ }
+
+ private void startCapture()
+ {
+ try {
+ capture.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ try {
+ LabelingCamera mainwin = new LabelingCamera();
+ mainwin.setVisible(true);
+ mainwin.startCapture();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
Index: trunk/sample/jogl/.classpath
===================================================================
--- trunk/sample/jogl/.classpath (revision 162)
+++ trunk/sample/jogl/.classpath (revision 199)
@@ -3,10 +3,10 @@
<classpathentry path="" kind="src"/>
<classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/>
<classpathentry path="C:/Program Files/JMF2.1.1e/lib/jmf.jar" kind="lib"/>
- <classpathentry path="C:/Program Files/Java/jogl/lib/gluegen-rt.jar" kind="lib"/>
- <classpathentry path="C:/Program Files/Java/jogl/lib/jogl.jar" kind="lib"/>
<classpathentry path="/NyARToolKit" combineaccessrules="false" kind="src"/>
<classpathentry path="/NyARToolkit.utils.jmf" combineaccessrules="false" kind="src"/>
<classpathentry path="/NyARToolkit.utils.jogl" combineaccessrules="false" kind="src"/>
+ <classpathentry path="C:/Program Files/Java/jre1.6.0_03/lib/gluegen-rt.jar" kind="lib"/>
+ <classpathentry path="C:/Program Files/Java/jre1.6.0_03/lib/jogl.jar" kind="lib"/>
<classpathentry path="" kind="output"/>
</classpath>
Index: trunk/sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/JavaSimpleLite.java
===================================================================
--- trunk/sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/JavaSimpleLite.java (revision 162)
+++ trunk/sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/JavaSimpleLite.java (revision 199)
@@ -26,23 +26,16 @@
*/
package jp.nyatla.nyartoolkit.jogl.sample;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
+import java.awt.event.*;
import java.awt.*;
-
import javax.media.Buffer;
-
-import javax.media.opengl.GL;
-import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLCanvas;
-
-import com.sun.opengl.util.Animator;
-
-import jp.nyatla.nyartoolkit.core.NyARCode;
-
-import jp.nyatla.nyartoolkit.jmf.utils.JmfCameraCapture;
-import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureListener;
+import javax.media.opengl.*;
+import com.sun.opengl.util.*;
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.transmat.*;
+import jp.nyatla.nyartoolkit.detector.*;
+import jp.nyatla.nyartoolkit.jmf.utils.*;
import jp.nyatla.nyartoolkit.jogl.utils.*;
/**
* simpleLiteと同じようなテストプログラム
@@ -67,14 +60,14 @@
private JmfCameraCapture _capture;
private GL _gl;
-
private NyARGLUtil _glnya;
//NyARToolkit関係
- private GLNyARSingleDetectMarker _nya;
+ private NyARSingleDetectMarker _nya;
+ private NyARParam _ar_param;
- private GLNyARParam _ar_param;
-
+ private double[] _camera_projection=new double[16];
+
/**
* 立方体を書く
*
@@ -150,11 +143,11 @@
_capture = new JmfCameraCapture(SCREEN_X, SCREEN_Y, 15f, JmfCameraCapture.PIXEL_FORMAT_RGB);
_capture.setCaptureListener(this);
//NyARToolkitの準備
- _ar_param = new GLNyARParam();
+ _ar_param = new NyARParam();
NyARCode ar_code = new NyARCode(16, 16);
_ar_param.loadARParamFromFile(PARAM_FILE);
_ar_param.changeScreenSize(SCREEN_X, SCREEN_Y);
- _nya = new GLNyARSingleDetectMarker(_ar_param, ar_code, 80.0);
+ _nya = new NyARSingleDetectMarker(_ar_param, ar_code, 80.0);
_nya.setContinueMode(false);//ここをtrueにすると、transMatContinueモード(History計算)になります。
ar_code.loadARPattFromFile(CARCODE_FILE);
//NyARToolkit用の支援クラス
@@ -166,10 +159,12 @@
} catch (Exception e) {
e.printStackTrace();
}
+ //カメラパラメータの計算
+ _glnya.toCameraFrustumRH(_ar_param,_camera_projection);
+
_animator = new Animator(drawable);
-
_animator.start();
-
+ return;
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
@@ -184,10 +179,12 @@
_gl.glMatrixMode(GL.GL_MODELVIEW);
_gl.glLoadIdentity();
}
-
+ private NyARTransMatResult __display_transmat_result=new NyARTransMatResult();
+ private double[] __display_wk=new double[16];
+
public void display(GLAutoDrawable drawable)
{
-
+ NyARTransMatResult transmat_result=__display_transmat_result;
try {
if (!_cap_image.hasData()) {
return;
@@ -200,16 +197,20 @@
//背景を書く
_glnya.drawBackGround(_cap_image, 1.0);
}
- //あったら立方体を書く
+ //マーカーがあれば、立方体を描画
if (is_marker_exist) {
//マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。
// Projection transformation.
_gl.glMatrixMode(GL.GL_PROJECTION);
- _gl.glLoadMatrixd(_ar_param.getCameraFrustumRH(), 0);
+ _gl.glLoadMatrixd(_camera_projection, 0);
_gl.glMatrixMode(GL.GL_MODELVIEW);
// Viewing transformation.
_gl.glLoadIdentity();
- _gl.glLoadMatrixd(_nya.getCameraViewRH(), 0);
+ //変換行列を取得
+ _nya.getTransmationMatrix(transmat_result);
+ //変換行列をOpenGL形式に変換
+ _glnya.toCameraViewRH(transmat_result, __display_wk);
+ _gl.glLoadMatrixd(__display_wk, 0);
// All other lighting and geometry goes here.
drawCube();
Index: trunk/sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/JavaSimpleLite2.java
===================================================================
--- trunk/sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/JavaSimpleLite2.java (revision 162)
+++ trunk/sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/JavaSimpleLite2.java (revision 199)
@@ -27,23 +27,16 @@
package jp.nyatla.nyartoolkit.jogl.sample;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
+import java.awt.event.*;
import java.awt.*;
-
-import javax.media.Buffer;
-
-import javax.media.opengl.GL;
-import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLCanvas;
-
+import javax.media.*;
+import javax.media.opengl.*;
import com.sun.opengl.util.Animator;
-
-import jp.nyatla.nyartoolkit.core.NyARCode;
-
-import jp.nyatla.nyartoolkit.jmf.utils.JmfCameraCapture;
-import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureListener;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.detector.*;
+import jp.nyatla.nyartoolkit.jmf.utils.*;
import jp.nyatla.nyartoolkit.jogl.utils.*;
/**
* simpleLiteの複数マーカー同時認識バージョン
@@ -73,10 +66,10 @@
private NyARGLUtil _glnya;
//NyARToolkit関係
- private GLNyARDetectMarker _nya;
+ private NyARDetectMarker _nya;
- private GLNyARParam _ar_param;
-
+ private NyARParam _ar_param;
+ private double[] _camera_projection=new double[16];
/**
* 立方体を書く
*
@@ -152,7 +145,7 @@
_capture = new JmfCameraCapture(SCREEN_X, SCREEN_Y, 15f, JmfCameraCapture.PIXEL_FORMAT_RGB);
_capture.setCaptureListener(this);
//NyARToolkitの準備
- _ar_param = new GLNyARParam();
+ _ar_param = new NyARParam();
_ar_param.loadARParamFromFile(PARAM_FILE);
_ar_param.changeScreenSize(SCREEN_X, SCREEN_Y);
@@ -163,7 +156,7 @@
ar_codes[0].loadARPattFromFile(CARCODE_FILE1);
ar_codes[1] = new NyARCode(16, 16);
ar_codes[1].loadARPattFromFile(CARCODE_FILE2);
- _nya = new GLNyARDetectMarker(_ar_param, ar_codes, width, 2);
+ _nya = new NyARDetectMarker(_ar_param, ar_codes, width, 2);
_nya.setContinueMode(false);//ここをtrueにすると、transMatContinueモード(History計算)になります。
//NyARToolkit用の支援クラス
_glnya = new NyARGLUtil(_gl);
@@ -174,8 +167,10 @@
} catch (Exception e) {
e.printStackTrace();
}
+ //カメラパラメータの計算
+ _glnya.toCameraFrustumRH(_ar_param,_camera_projection);
+
_animator = new Animator(drawable);
-
_animator.start();
}
@@ -192,9 +187,12 @@
_gl.glMatrixMode(GL.GL_MODELVIEW);
_gl.glLoadIdentity();
}
-
+ private NyARTransMatResult __display_transmat_result=new NyARTransMatResult();
+ private double[] __display_wk=new double[16];
+
public void display(GLAutoDrawable drawable)
{
+ NyARTransMatResult transmat_result=__display_transmat_result;
try {
if (!_cap_image.hasData()) {
@@ -209,7 +207,6 @@
_glnya.drawBackGround(_cap_image, 1.0);
}
//あったら立方体を書く
- double[] matrix = new double[16];
for (int i = 0; i < found_markers; i++) {
//1番のマーカーでなければ表示しない。
if (_nya.getARCodeIndex(i) != 0) {
@@ -218,12 +215,15 @@
//マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。
// Projection transformation.
_gl.glMatrixMode(GL.GL_PROJECTION);
- _gl.glLoadMatrixd(_ar_param.getCameraFrustumRH(), 0);
+ _gl.glLoadMatrixd(_camera_projection, 0);
_gl.glMatrixMode(GL.GL_MODELVIEW);
// Viewing transformation.
_gl.glLoadIdentity();
- _nya.getCameraViewRH(i, matrix);
- _gl.glLoadMatrixd(matrix, 0);
+ //変換行列を取得
+ _nya.getTransmationMatrix(i,transmat_result);
+ //変換行列をOpenGL形式に変換
+ _glnya.toCameraViewRH(transmat_result, __display_wk);
+ _gl.glLoadMatrixd(__display_wk, 0);
// All other lighting and geometry goes here.
drawCube();
@@ -232,6 +232,7 @@
} catch (Exception e) {
e.printStackTrace();
}
+ return;
}
public void onUpdateBuffer(Buffer i_buffer)
Index: trunk/sample/sandbox/.classpath
===================================================================
--- trunk/sample/sandbox/.classpath (revision 0)
+++ trunk/sample/sandbox/.classpath (revision 199)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry path="" kind="src"/>
+ <classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/>
+ <classpathentry path="/NyARToolKit" combineaccessrules="false" kind="src"/>
+ <classpathentry path="/NyARToolkit.utils.jmf" combineaccessrules="false" kind="src"/>
+ <classpathentry path="/NyARToolkit.utils.jogl" combineaccessrules="false" kind="src"/>
+ <classpathentry path="C:/Program Files/JMF2.1.1e/lib/jmf.jar" kind="lib"/>
+ <classpathentry path="C:/Program Files/Java/jre1.6.0_03/lib/jogl.jar" kind="lib"/>
+ <classpathentry path="bin" kind="output"/>
+</classpath>
Index: trunk/sample/sandbox/.project
===================================================================
--- trunk/sample/sandbox/.project (revision 0)
+++ trunk/sample/sandbox/.project (revision 199)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>NyARToolkit.sandbox</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/quadx2/NyARSingleDetectMarker_Quad.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/quadx2/NyARSingleDetectMarker_Quad.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/quadx2/NyARSingleDetectMarker_Quad.java (revision 199)
@@ -0,0 +1,230 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.quadx2;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.core.match.*;
+import jp.nyatla.nyartoolkit.core.param.NyARParam;
+import jp.nyatla.nyartoolkit.core.pickup.*;
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.transmat.*;
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;
+
+import jp.nyatla.nyartoolkit.sandbox.x2.NyARTransMat_X2;
+
+
+/**
+ * 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。
+ *
+ */
+public class NyARSingleDetectMarker_Quad
+{
+ private static final int AR_SQUARE_MAX = 100;
+
+ private boolean _is_continue = false;
+ private NyARMatchPatt_Color_WITHOUT_PCA _match_patt;
+ private INyARSquareDetector _square_detect;
+
+ private final NyARSquareStack _square_list = new NyARSquareStack(AR_SQUARE_MAX);
+
+ private NyARCode _code;
+
+ protected INyARTransMat _transmat;
+
+ private double _marker_width;
+
+ // 検出結果の保存用
+ private int _detected_direction;
+
+ private double _detected_confidence;
+
+ private NyARSquare _detected_square;
+
+ private INyARColorPatt _patt;
+
+ /**
+ * 検出するARCodeとカメラパラメータから、1個のARCodeを検出するNyARSingleDetectMarkerインスタンスを作ります。
+ *
+ * @param i_param
+ * カメラパラメータを指定します。
+ * @param i_code
+ * 検出するARCodeを指定します。
+ * @param i_marker_width
+ * ARコードの物理サイズを、ミリメートルで指定します。
+ * @throws NyARException
+ */
+ public NyARSingleDetectMarker_Quad(NyARParam i_param, NyARCode i_code, double i_marker_width) throws NyARException
+ {
+ final NyARIntSize scr_size=i_param.getScreenSize();
+ // 解析オブジェクトを作る
+ this._square_detect = new NyARSquareDetector_Quad(i_param.getDistortionFactor(),scr_size);
+ this._transmat = new NyARTransMat_X2(i_param);
+ // 比較コードを保存
+ this._code = i_code;
+ this._marker_width = i_marker_width;
+ // 評価パターンのホルダを作る
+ this._patt = new NyARColorPatt_O3(_code.getWidth(), _code.getHeight());
+ // 評価器を作る。
+ this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA();
+ //2値画像バッファを作る
+ this._bin_raster=new NyARBinRaster(scr_size.w/2,scr_size.h/2);
+ return;
+ }
+
+ private NyARBinRaster _bin_raster;
+// private NyARRasterFilter_ARToolkitThreshold _tobin_filter=new NyARRasterFilter_ARToolkitThreshold(100);
+ private NyARRasterFilter_ARTTh_Quad _tobin_filter=new NyARRasterFilter_ARTTh_Quad(100);
+
+ /**
+ * i_imageにマーカー検出処理を実行し、結果を記録します。
+ *
+ * @param i_raster
+ * マーカーを検出するイメージを指定します。イメージサイズは、カメラパラメータ
+ * と一致していなければなりません。
+ * @return マーカーが検出できたかを真偽値で返します。
+ * @throws NyARException
+ */
+ public boolean detectMarkerLite(INyARRgbRaster i_raster,int i_threshold) throws NyARException
+ {
+ //サイズチェック
+ if(!this._bin_raster.getSize().isEqualSize(i_raster.getSize().w/2,i_raster.getSize().h/2)){
+ throw new NyARException();
+ }
+
+ //ラスタを(1/4の画像の)2値イメージに変換する.
+ this._tobin_filter.setThreshold(i_threshold);
+ this._tobin_filter.doFilter(i_raster,this._bin_raster);
+
+
+ this._detected_square = null;
+ NyARSquareStack l_square_list = this._square_list;
+ // スクエアコードを探す
+ this._square_detect.detectMarker(this._bin_raster, l_square_list);
+
+
+ int number_of_square = l_square_list.getLength();
+ // コードは見つかった?
+ if (number_of_square < 1) {
+ return false;
+ }
+
+ // 評価基準になるパターンをイメージから切り出す
+ if (!this._patt.pickFromRaster(i_raster, (NyARSquare)l_square_list.getItem(0))) {
+ // パターンの切り出しに失敗
+ return false;
+ }
+ // パターンを評価器にセット
+ if (!this._match_patt.setPatt(this._patt)) {
+ // 計算に失敗した。
+ throw new NyARException();
+ }
+ // コードと比較する
+ this._match_patt.evaluate(this._code);
+ int square_index = 0;
+ int direction = this._match_patt.getDirection();
+ double confidence = this._match_patt.getConfidence();
+ for (int i = 1; i < number_of_square; i++) {
+ // 次のパターンを取得
+ this._patt.pickFromRaster(i_raster, (NyARSquare)l_square_list.getItem(i));
+ // 評価器にセットする。
+ this._match_patt.setPatt(this._patt);
+ // コードと比較する
+ this._match_patt.evaluate(this._code);
+ double c2 = this._match_patt.getConfidence();
+ if (confidence > c2) {
+ continue;
+ }
+ // もっと一致するマーカーがあったぽい
+ square_index = i;
+ direction = this._match_patt.getDirection();
+ confidence = c2;
+ }
+ // マーカー情報を保存
+ this._detected_square = (NyARSquare)l_square_list.getItem(square_index);
+ this._detected_direction = direction;
+ this._detected_confidence = confidence;
+ return true;
+ }
+
+ /**
+ * 検出したマーカーの変換行列を計算して、o_resultへ値を返します。
+ * 直前に実行したdetectMarkerLiteが成功していないと使えません。
+ *
+ * @param o_result
+ * 変換行列を受け取るオブジェクトを指定します。
+ * @throws NyARException
+ */
+ public void getTransmationMatrix(NyARTransMatResult o_result) throws NyARException
+ {
+ // 一番一致したマーカーの位置とかその辺を計算
+ if (this._is_continue) {
+ this._transmat.transMatContinue(this._detected_square,this._detected_direction,this._marker_width, o_result);
+ } else {
+ this._transmat.transMat(this._detected_square,this._detected_direction,this._marker_width, o_result);
+ }
+ return;
+ }
+
+ /**
+ * 検出したマーカーの一致度を返します。
+ *
+ * @return マーカーの一致度を返します。0~1までの値をとります。 一致度が低い場合には、誤認識の可能性が高くなります。
+ * @throws NyARException
+ */
+ public double getConfidence()
+ {
+ return this._detected_confidence;
+ }
+
+ /**
+ * 検出したマーカーの方位を返します。
+ *
+ * @return 0,1,2,3の何れかを返します。
+ */
+ public int getDirection()
+ {
+ return this._detected_direction;
+ }
+
+ /**
+ * getTransmationMatrixの計算モードを設定します。 初期値はTRUEです。
+ *
+ * @param i_is_continue
+ * TRUEなら、transMatCont互換の計算をします。 FALSEなら、transMat互換の計算をします。
+ */
+ public void setContinueMode(boolean i_is_continue)
+ {
+ this._is_continue = i_is_continue;
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/quadx2/JavaSimpleLite_Quad.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/quadx2/JavaSimpleLite_Quad.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/quadx2/JavaSimpleLite_Quad.java (revision 199)
@@ -0,0 +1,251 @@
+/*
+ * PROJECT: NyARToolkit JOGL sample program.
+ * --------------------------------------------------------------------------------
+ * The MIT License
+ * Copyright (c) 2008 nyatla
+ * airmail(at)ebony.plala.or.jp
+ * http://nyatla.jp/nyartoolkit/
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.quadx2;
+
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.*;
+
+import javax.media.Buffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLCanvas;
+
+import com.sun.opengl.util.Animator;
+
+import jp.nyatla.nyartoolkit.core.NyARCode;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;
+import jp.nyatla.nyartoolkit.jmf.utils.JmfCameraCapture;
+import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureListener;
+import jp.nyatla.nyartoolkit.jogl.utils.*;
+/**
+ * simpleLiteと同じようなテストプログラム
+ * 出来る限りARToolKitのサンプルと似せて作ってあります。
+ * 最も一致する"Hiro"マーカーを一つ選択して、その上に立方体を表示します。
+ *
+ */
+public class JavaSimpleLite_Quad implements GLEventListener, JmfCaptureListener
+{
+ private final String CARCODE_FILE = "../../Data/patt.hiro";
+
+ private final String PARAM_FILE = "../../Data/camera_para.dat";
+
+ private final static int SCREEN_X = 320;
+
+ private final static int SCREEN_Y = 240;
+
+ private Animator _animator;
+
+ private GLNyARRaster_RGB _cap_image;
+
+ private JmfCameraCapture _capture;
+
+ private GL _gl;
+
+ private NyARGLUtil _glnya;
+
+ //NyARToolkit関係
+ private NyARSingleDetectMarker_Quad _nya;
+
+ private NyARParam _ar_param;
+
+ /**
+ * 立方体を書く
+ *
+ */
+ void drawCube()
+ {
+ // Colour cube data.
+ int polyList = 0;
+ float fSize = 0.5f;//マーカーサイズに対して0.5倍なので、4cmの立方体
+ int f, i;
+ float[][] cube_vertices = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f } };
+ float[][] cube_vertex_colors = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };
+ int cube_num_faces = 6;
+ short[][] cube_faces = new short[][] { { 3, 2, 1, 0 }, { 2, 3, 7, 6 }, { 0, 1, 5, 4 }, { 3, 0, 4, 7 }, { 1, 2, 6, 5 }, { 4, 5, 6, 7 } };
+
+ if (polyList == 0) {
+ polyList = _gl.glGenLists(1);
+ _gl.glNewList(polyList, GL.GL_COMPILE);
+ _gl.glBegin(GL.GL_QUADS);
+ for (f = 0; f < cube_num_faces; f++)
+ for (i = 0; i < 4; i++) {
+ _gl.glColor3f(cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]);
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);
+ }
+ _gl.glEnd();
+ _gl.glColor3f(0.0f, 0.0f, 0.0f);
+ for (f = 0; f < cube_num_faces; f++) {
+ _gl.glBegin(GL.GL_LINE_LOOP);
+ for (i = 0; i < 4; i++)
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);
+ _gl.glEnd();
+ }
+ _gl.glEndList();
+ }
+
+ _gl.glPushMatrix(); // Save world coordinate system.
+ _gl.glTranslatef(0.0f, 0.0f, 0.5f); // Place base of cube on marker surface.
+ _gl.glRotatef(0.0f, 0.0f, 0.0f, 1.0f); // Rotate about z axis.
+ _gl.glDisable(GL.GL_LIGHTING); // Just use colours.
+ _gl.glCallList(polyList); // Draw the cube.
+ _gl.glPopMatrix(); // Restore world coordinate system.
+
+ }
+
+ public JavaSimpleLite_Quad()
+ {
+ Frame frame = new Frame("Java simpleLite with NyARToolkit");
+
+ // 3Dを描画するコンポーネント
+ GLCanvas canvas = new GLCanvas();
+ frame.add(canvas);
+ canvas.addGLEventListener(this);
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e)
+ {
+ System.exit(0);
+ }
+ });
+
+ frame.setVisible(true);
+ Insets ins = frame.getInsets();
+ frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);
+ canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);
+ }
+
+ public void init(GLAutoDrawable drawable)
+ {
+ _gl = drawable.getGL();
+ _gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ //NyARToolkitの準備
+ try {
+ //キャプチャの準備
+ _capture = new JmfCameraCapture(SCREEN_X, SCREEN_Y, 15f, JmfCameraCapture.PIXEL_FORMAT_RGB);
+ _capture.setCaptureListener(this);
+ //NyARToolkitの準備
+ _ar_param = new NyARParam();
+ NyARCode ar_code = new NyARCode(16, 16);
+ _ar_param.loadARParamFromFile(PARAM_FILE);
+ _ar_param.changeScreenSize(SCREEN_X, SCREEN_Y);
+ _nya = new NyARSingleDetectMarker_Quad(_ar_param, ar_code, 80.0);
+ _nya.setContinueMode(false);//ここをtrueにすると、transMatContinueモード(History計算)になります。
+ ar_code.loadARPattFromFile(CARCODE_FILE);
+ //NyARToolkit用の支援クラス
+ _glnya = new NyARGLUtil(_gl);
+ //GL対応のRGBラスタオブジェクト
+ _cap_image = new GLNyARRaster_RGB(_ar_param);
+ //キャプチャ開始
+ _capture.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ //カメラパラメータの計算
+ _glnya.toCameraFrustumRH(_ar_param,_camera_projection);
+ _animator = new Animator(drawable);
+
+ _animator.start();
+
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
+ {
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ _gl.glViewport(0, 0, width, height);
+
+ //視体積の設定
+ _gl.glMatrixMode(GL.GL_PROJECTION);
+ _gl.glLoadIdentity();
+ //見る位置
+ _gl.glMatrixMode(GL.GL_MODELVIEW);
+ _gl.glLoadIdentity();
+ }
+ private double[] _camera_projection=new double[16];
+ private NyARTransMatResult __display_transmat_result=new NyARTransMatResult();
+ private double[] __display_wk=new double[16];
+ public void display(GLAutoDrawable drawable)
+ {
+ NyARTransMatResult transmat_result=__display_transmat_result;
+ try {
+ if (!_cap_image.hasData()) {
+ return;
+ }
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.
+ //画像チェックしてマーカー探して、背景を書く
+ boolean is_marker_exist;
+ synchronized (_cap_image) {
+ is_marker_exist = _nya.detectMarkerLite(_cap_image, 110);
+ //背景を書く
+ _glnya.drawBackGround(_cap_image, 1.0);
+ }
+ //マーカーがあれば、立方体を描画
+ if (is_marker_exist) {
+ //マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。
+ // Projection transformation.
+ _gl.glMatrixMode(GL.GL_PROJECTION);
+ _gl.glLoadMatrixd(_camera_projection, 0);
+ _gl.glMatrixMode(GL.GL_MODELVIEW);
+ // Viewing transformation.
+ _gl.glLoadIdentity();
+ //変換行列を取得
+ _nya.getTransmationMatrix(transmat_result);
+ //変換行列をOpenGL形式に変換
+ _glnya.toCameraViewRH(transmat_result, __display_wk);
+ _gl.glLoadMatrixd(__display_wk, 0);
+
+ // All other lighting and geometry goes here.
+ drawCube();
+ }
+ Thread.sleep(1);//タスク実行権限を一旦渡す
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+ public void onUpdateBuffer(Buffer i_buffer)
+ {
+ try {
+ synchronized (_cap_image) {
+ _cap_image.setBuffer(i_buffer, true);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)
+ {
+ }
+
+ public static void main(String[] args)
+ {
+ new JavaSimpleLite_Quad();
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/quadx2/NyARRasterFilter_ARTTh_Quad.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/quadx2/NyARRasterFilter_ARTTh_Quad.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/quadx2/NyARRasterFilter_ARTTh_Quad.java (revision 199)
@@ -0,0 +1,194 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.quadx2;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;
+
+/**
+ * 1/4のサイズの画像に変換しながら閾値判定する関数
+ *
+ */
+public class NyARRasterFilter_ARTTh_Quad implements INyARRasterFilter_RgbToBin
+{
+ private int _threshold;
+
+ public NyARRasterFilter_ARTTh_Quad(int i_threshold)
+ {
+ this._threshold = i_threshold;
+ }
+ public void setThreshold(int i_threshold)
+ {
+ this._threshold = i_threshold;
+ }
+
+ public void doFilter(INyARRgbRaster i_input, NyARBinRaster i_output) throws NyARException
+ {
+ INyARBufferReader in_buffer_reader=i_input.getBufferReader();
+ INyARBufferReader out_buffer_reader=i_output.getBufferReader();
+ int in_buf_type=in_buffer_reader.getBufferType();
+
+ NyARIntSize size = i_output.getSize();
+ assert (out_buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT2D_BIN_8));
+ assert (checkInputType(in_buf_type)==true);
+ assert (i_input.getSize().isEqualSize(size.w*2,size.h*2) == true);
+
+ int[][] out_buf = (int[][]) out_buffer_reader.getBuffer();
+ byte[] in_buf = (byte[]) in_buffer_reader.getBuffer();
+
+ switch (in_buffer_reader.getBufferType()) {
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:
+ convert24BitRgb(in_buf, out_buf, size);
+ break;
+// case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8X8_32:
+// convert32BitRgbx(in_buf, out_buf, size);
+// break;
+ default:
+ throw new NyARException();
+ }
+ return;
+ }
+
+ private void convert24BitRgb(byte[] i_in, int[][] i_out, NyARIntSize i_size)
+ {
+ final int size_w=i_size.w*2;
+ final int x_mod_end= size_w-(size_w%8);
+ final int th=this._threshold*3;
+ int bp =(size_w*i_size.h*2-1)*3;
+ int w;
+ int x;
+ for (int y =i_size.h-1; y>=0 ; y--){
+ //端数分
+ final int[] row_ptr=i_out[y];
+ for (x = i_size.w-1;x>=x_mod_end;x--) {
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x]=w<=th?0:1;
+ bp -= 6;
+ }
+ //タイリング
+ for (;x>=0;x-=8) {
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x]=w<=th?0:1;
+ bp -= 6;
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x-1]=w<=th?0:1;
+ bp -= 6;
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x-2]=w<=th?0:1;
+ bp -= 6;
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x-3]=w<=th?0:1;
+ bp -= 6;
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x-4]=w<=th?0:1;
+ bp -= 6;
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x-5]=w<=th?0:1;
+ bp -= 6;
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x-6]=w<=th?0:1;
+ bp -= 6;
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x-7]=w<=th?0:1;
+ bp -= 6;
+ }
+ //1行飛ばし
+ bp-=size_w*3;
+ }
+ return;
+ }
+ private void convert32BitRgbx(byte[] i_in, int[][] i_out, NyARIntSize i_size)
+ {
+ final int size_w=i_size.w;
+ final int x_mod_end= size_w-(size_w%8);
+ final int th=this._threshold*3;
+ int bp =(size_w*i_size.h-1)*4;
+ int w;
+ int x;
+ for (int y =i_size.h-1; y>=0 ; y--){
+ final int[] row_ptr=i_out[y];
+
+ //端数分
+ for (x = size_w-1;x>=x_mod_end;x--) {
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x]=w<=th?0:1;
+ bp -= 4;
+ }
+ //タイリング
+ for (;x>=0;x-=8) {
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x]=w<=th?0:1;
+ bp -= 4;
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x-1]=w<=th?0:1;
+ bp -= 4;
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x-2]=w<=th?0:1;
+ bp -= 4;
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x-3]=w<=th?0:1;
+ bp -= 4;
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x-4]=w<=th?0:1;
+ bp -= 4;
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x-5]=w<=th?0:1;
+ bp -= 4;
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x-6]=w<=th?0:1;
+ bp -= 4;
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
+ row_ptr[x-7]=w<=th?0:1;
+ bp -= 4;
+ }
+ }
+ return;
+ }
+
+ private boolean checkInputType(int i_input_type) throws NyARException
+ {
+ switch(i_input_type){
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:
+// case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8X8_32:
+// case INyARBufferReader.BUFFERFORMAT_BYTE1D_R5G6B5_16LE:
+ return true;
+ default:
+ return false;
+ }
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/quadx2/NyARSquareDetector_Quad.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/quadx2/NyARSquareDetector_Quad.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/quadx2/NyARSquareDetector_Quad.java (revision 199)
@@ -0,0 +1,512 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.quadx2;
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.labeling.*;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+
+
+import jp.nyatla.nyartoolkit.core2.types.NyARI64Linear;
+import jp.nyatla.nyartoolkit.core2.types.NyARI64Point2d;
+import jp.nyatla.nyartoolkit.core2.types.matrix.NyARI64Matrix22;
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.sandbox.x2.*;
+
+
+/**
+ * 1/4に解像度を落して解析するNyARSquareDetector_X2
+ * 与えるBinRasterが既に1/4のサイズになっていないといけないことに注意
+ */
+public class NyARSquareDetector_Quad implements INyARSquareDetector
+{
+ private static int PCA_LENGTH = 20;
+ private static double VERTEX_FACTOR = 1.0;// 線検出のファクタ
+
+ private static int AR_AREA_MAX = 25000;// #define AR_AREA_MAX 100000
+
+ private static int AR_AREA_MIN = 20;// #define AR_AREA_MIN 70
+ private int _width;
+ private int _height;
+
+ private INyARLabeling _labeling;
+
+ private NyARLabelingImage _limage;
+
+ private OverlapChecker _overlap_checker = new OverlapChecker();
+ private NyARFixedFloatObserv2IdealMap _dist_factor;
+ /**
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。
+ *
+ * @param i_param
+ */
+ public NyARSquareDetector_Quad(NyARCameraDistortionFactor i_dist_factor_ref, NyARIntSize i_size) throws NyARException
+ {
+ this._width = i_size.w / 2;
+ this._height = i_size.h / 2;
+ this._labeling = new NyARLabeling_ARToolKit_X2();
+ this._limage = new NyARLabelingImage(this._width, this._height);
+ this._labeling.attachDestination(this._limage);
+
+ // 輪郭の最大長は画面に映りうる最大の長方形サイズ。
+ int number_of_coord = (this._width + this._height) * 2;
+
+ // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。
+ this._max_coord = number_of_coord;
+ this._xcoord = new int[number_of_coord * 2];
+ this._ycoord = new int[number_of_coord * 2];
+
+ //1/4サイズの歪みマップを作る
+ NyARCameraDistortionFactor quadfactor = new NyARCameraDistortionFactor();
+ quadfactor.copyFrom(i_dist_factor_ref);
+ quadfactor.changeScale(0.5);
+ this._dist_factor = new NyARFixedFloatObserv2IdealMap(quadfactor, i_size);
+ //PCA
+ this._pca = new NyARFixedFloatPca2d();
+ this._xpos = new int[PCA_LENGTH];//最大辺長はthis._width+this._height
+ this._ypos = new int[PCA_LENGTH];//最大辺長はthis._width+this._height
+
+ }
+
+ private int _max_coord;
+ private int[] _xcoord;
+ private int[] _ycoord;
+
+ private void normalizeCoord(int[] i_coord_x, int[] i_coord_y, int i_index, int i_coord_num)
+ {
+ // vertex1を境界にして、後方に配列を連結
+ System.arraycopy(i_coord_x, 1, i_coord_x, i_coord_num, i_index);
+ System.arraycopy(i_coord_y, 1, i_coord_y, i_coord_num, i_index);
+ }
+
+ private int[] __detectMarker_mkvertex = new int[5];
+
+ /**
+ * arDetectMarker2を基にした関数
+ * この関数はNyARSquare要素のうち、directionを除くパラメータを取得して返します。
+ * directionの確定は行いません。
+ * @param i_raster
+ * 解析する2値ラスタイメージを指定します。
+ * @param o_square_stack
+ * 抽出した正方形候補を格納するリスト
+ * @throws NyARException
+ */
+ public void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException
+ {
+ INyARLabeling labeling_proc = this._labeling;
+ NyARLabelingImage limage = this._limage;
+
+ // 初期化
+
+ // マーカーホルダをリセット
+ o_square_stack.clear();
+
+ // ラベリング
+ labeling_proc.labeling(i_raster);
+
+ // ラベル数が0ならここまで
+ int label_num = limage.getLabelStack().getLength();
+ if (label_num < 1)
+ {
+ return;
+ }
+
+ NyARLabelingLabelStack stack = limage.getLabelStack();
+ NyARLabelingLabel[] labels = (NyARLabelingLabel[])stack.getArray();
+
+
+ // ラベルを大きい順に整列
+ stack.sortByArea();
+
+ // デカいラベルを読み飛ばし
+ int i;
+ for (i = 0; i < label_num; i++)
+ {
+ // 検査対象内のラベルサイズになるまで無視
+ if (labels[i].area <= AR_AREA_MAX)
+ {
+ break;
+ }
+ }
+
+ int xsize = this._width;
+ int ysize = this._height;
+ int[] xcoord = this._xcoord;
+ int[] ycoord = this._ycoord;
+ int coord_max = this._max_coord;
+ int[] mkvertex = this.__detectMarker_mkvertex;
+ OverlapChecker overlap = this._overlap_checker;
+ int coord_num;
+ int label_area;
+ NyARLabelingLabel label_pt;
+
+ //重なりチェッカの最大数を設定
+ overlap.reset(label_num);
+
+ for (; i < label_num; i++)
+ {
+ label_pt = labels[i];
+ label_area = label_pt.area;
+ // 検査対象サイズよりも小さくなったら終了
+ if (label_area < AR_AREA_MIN)
+ {
+ break;
+ }
+ // クリップ領域が画面の枠に接していれば除外
+ if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2)
+ {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){
+ continue;
+ }
+ if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2)
+ {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){
+ continue;
+ }
+ // 既に検出された矩形との重なりを確認
+ if (!overlap.check(label_pt))
+ {
+ // 重なっているようだ。
+ continue;
+ }
+
+ // 輪郭を取得
+ coord_num = limage.getContour(i, coord_max, xcoord, ycoord);
+ if (coord_num == coord_max)
+ {
+ // 輪郭が大きすぎる。
+ continue;
+ }
+ //頂点候補のインデクスを取得
+ int vertex1 = scanVertex(xcoord, ycoord, coord_num);
+
+ // 頂点候補(vertex1)を先頭に並べなおした配列を作成する。
+ normalizeCoord(xcoord, ycoord, vertex1, coord_num);
+
+ // 領域を準備する。
+ NyARSquare square_ptr = (NyARSquare)o_square_stack.prePush();
+
+ // 頂点情報を取得
+ if (!getSquareVertex(xcoord, ycoord, vertex1, coord_num, label_area, mkvertex))
+ {
+ o_square_stack.pop();// 頂点の取得が出来なかったので破棄
+ continue;
+ }
+ // マーカーを検出
+ if (!getSquareLine(mkvertex, xcoord, ycoord, square_ptr))
+ {
+ // 矩形が成立しなかった。
+ o_square_stack.pop();
+ continue;
+ }
+ // 検出済の矩形の属したラベルを重なりチェックに追加する。
+ overlap.push(label_pt);
+ }
+ return;
+ }
+
+ /**
+ * 辺からの対角線が最長になる点を対角線候補として返す。
+ *
+ * @param i_xcoord
+ * @param i_ycoord
+ * @param i_coord_num
+ * @return
+ */
+ private int scanVertex(int[] i_xcoord, int[] i_ycoord, int i_coord_num)
+ {
+ int sx = i_xcoord[0];
+ int sy = i_ycoord[0];
+ int d = 0;
+ int w, x, y;
+ int ret = 0;
+ for (int i = 1; i < i_coord_num; i++)
+ {
+ x = i_xcoord[i] - sx;
+ y = i_ycoord[i] - sy;
+ w = x * x + y * y;
+ if (w > d)
+ {
+ d = w;
+ ret = i;
+ }
+ // ここでうまく終了条件入れられないかな。
+ }
+ return ret;
+ }
+
+ private NyARVertexCounter __getSquareVertex_wv1 = new NyARVertexCounter();
+
+ private NyARVertexCounter __getSquareVertex_wv2 = new NyARVertexCounter();
+
+ /**
+ * static int arDetectMarker2_check_square( int area, ARMarkerInfo2 *marker_info2, double factor ) 関数の代替関数 OPTIMIZED STEP [450->415] o_squareに頂点情報をセットします。
+ *
+ * @param i_x_coord
+ * @param i_y_coord
+ * @param i_vertex1_index
+ * @param i_coord_num
+ * @param i_area
+ * @param o_vertex
+ * 要素数はint[4]である事
+ * @return
+ */
+ private boolean getSquareVertex(int[] i_x_coord, int[] i_y_coord, int i_vertex1_index, int i_coord_num, int i_area, int[] o_vertex)
+ {
+ NyARVertexCounter wv1 = this.__getSquareVertex_wv1;
+ NyARVertexCounter wv2 = this.__getSquareVertex_wv2;
+ int end_of_coord = i_vertex1_index + i_coord_num - 1;
+ int sx = i_x_coord[i_vertex1_index];// sx = marker_info2->x_coord[0];
+ int sy = i_y_coord[i_vertex1_index];// sy = marker_info2->y_coord[0];
+ int dmax = 0;
+ int v1 = i_vertex1_index;
+ for (int i = 1 + i_vertex1_index; i < end_of_coord; i++)
+ {// for(i=1;i<marker_info2->coord_num-1;i++)
+ // {
+ int d = (i_x_coord[i] - sx) * (i_x_coord[i] - sx) + (i_y_coord[i] - sy) * (i_y_coord[i] - sy);
+ if (d > dmax)
+ {
+ dmax = d;
+ v1 = i;
+ }
+ }
+ double thresh = (i_area / 0.75) * 0.01 * VERTEX_FACTOR;
+
+ o_vertex[0] = i_vertex1_index;
+
+ if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v1, thresh))
+ { // if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,0,v1,thresh,wv1,&wvnum1)<
+ // 0 ) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v1, end_of_coord, thresh))
+ {// if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,v1,marker_info2->coord_num-1,thresh,wv2,&wvnum2)
+ // < 0) {
+ return false;
+ }
+
+ int v2;
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1)
+ {// if(wvnum1 == 1 && wvnum2== 1) {
+ o_vertex[1] = wv1.vertex[0];
+ o_vertex[2] = v1;
+ o_vertex[3] = wv2.vertex[0];
+ }
+ else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0)
+ {// }else if( wvnum1 > 1 && wvnum2== 0) {
+ //頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。
+ v2 = (v1 - i_vertex1_index) / 2 + i_vertex1_index;
+ if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v2, thresh))
+ {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v2, v1, thresh))
+ {
+ return false;
+ }
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1)
+ {
+ o_vertex[1] = wv1.vertex[0];
+ o_vertex[2] = wv2.vertex[0];
+ o_vertex[3] = v1;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1)
+ {
+ //v2 = (v1-i_vertex1_index+ end_of_coord-i_vertex1_index) / 2+i_vertex1_index;
+ v2 = (v1 + end_of_coord) / 2;
+
+ if (!wv1.getVertex(i_x_coord, i_y_coord, v1, v2, thresh))
+ {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v2, end_of_coord, thresh))
+ {
+ return false;
+ }
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1)
+ {
+ o_vertex[1] = v1;
+ o_vertex[2] = wv1.vertex[0];
+ o_vertex[3] = wv2.vertex[0];
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ o_vertex[4] = end_of_coord;
+ return true;
+ }
+ private int[] _xpos;
+ private int[] _ypos;
+ private NyARFixedFloatPca2d _pca;
+ private NyARI64Matrix22 __getSquareLine_evec = new NyARI64Matrix22();
+ private NyARI64Point2d __getSquareLine_mean = new NyARI64Point2d();
+ private NyARI64Point2d __getSquareLine_ev = new NyARI64Point2d();
+ private NyARI64Linear[] __getSquareLine_i64liner = NyARI64Linear.createArray(4);
+ /**
+ * arGetLine(int x_coord[], int y_coord[], int coord_num,int vertex[], double line[4][3], double v[4][2]) arGetLine2(int x_coord[], int y_coord[], int
+ * coord_num,int vertex[], double line[4][3], double v[4][2], double *dist_factor) の2関数の合成品です。 マーカーのvertex,lineを計算して、結果をo_squareに保管します。
+ * Optimize:STEP[424->391]
+ *
+ * @param i_cparam
+ * @return
+ * @throws NyARException
+ */
+ private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square) throws NyARException
+ {
+ NyARLinear[] l_line = o_square.line;
+ NyARI64Matrix22 evec = this.__getSquareLine_evec;
+ NyARI64Point2d mean = this.__getSquareLine_mean;
+ NyARI64Point2d ev = this.__getSquareLine_ev;
+ NyARI64Linear[] i64liner = this.__getSquareLine_i64liner;
+
+
+ for (int i = 0; i < 4; i++)
+ {
+ double w1 = (double)(i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;
+ int st = (int)(i_mkvertex[i] + w1);
+ int ed = (int)(i_mkvertex[i + 1] - w1);
+ int n = ed - st + 1;
+ if (n < 2)
+ {
+ // nが2以下でmatrix.PCAを計算することはできないので、エラー
+ return false;
+ }
+ //配列作成
+ n = this._dist_factor.observ2IdealSampling(i_xcoord, i_ycoord, st, n, this._xpos, this._ypos, PCA_LENGTH);
+
+ //主成分分析する。
+ this._pca.pcaF16(this._xpos, this._ypos, n, evec, ev, mean);
+ NyARI64Linear l_line_i = i64liner[i];
+ l_line_i.run = evec.m01;// line[i][0] = evec->m[1];
+ l_line_i.rise = -evec.m00;// line[i][1] = -evec->m[0];
+ l_line_i.intercept = -((l_line_i.run * mean.x + l_line_i.rise * mean.y) >> 16);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);
+ }
+
+ NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;
+ NyARIntPoint[] l_imvertex = o_square.imvertex;
+ for (int i = 0; i < 4; i++)
+ {
+ NyARI64Linear l_line_i = i64liner[i];
+ NyARI64Linear l_line_2 = i64liner[(i + 3) % 4];
+ long w1 = (l_line_2.run * l_line_i.rise - l_line_i.run * l_line_2.rise) >> 16;
+ if (w1 == 0)
+ {
+ return false;
+ }
+ l_sqvertex[i].x = (double)((l_line_2.rise * l_line_i.intercept - l_line_i.rise * l_line_2.intercept) / w1) *2/ 65536.0;
+ l_sqvertex[i].y = (double)((l_line_i.run * l_line_2.intercept - l_line_2.run * l_line_i.intercept) / w1) *2/ 65536.0;
+ // 頂点インデクスから頂点座標を得て保存
+ l_imvertex[i].x = i_xcoord[i_mkvertex[i]]*2;
+ l_imvertex[i].y = i_ycoord[i_mkvertex[i]]*2;
+ l_line[i].run = (double)l_line_i.run / 65536.0;
+ l_line[i].rise = (double)l_line_i.rise / 65536.0;
+ l_line[i].intercept = (double)l_line_i.intercept*2 / 65536.0;
+ }
+ return true;
+ }
+}
+
+
+/**
+ * ラベル同士の重なり(内包関係)を調べるクラスです。
+ * ラベルリストに内包するラベルを蓄積し、それにターゲットのラベルが内包されているか を確認します。
+ */
+class OverlapChecker
+{
+ private NyARLabelingLabel[] _labels = new NyARLabelingLabel[32];
+
+ private int _length;
+
+ /**
+ * 最大i_max_label個のラベルを蓄積できるようにオブジェクトをリセットする
+ *
+ * @param i_max_label
+ */
+ public void reset(int i_max_label)
+ {
+ if (i_max_label > this._labels.length)
+ {
+ this._labels = new NyARLabelingLabel[i_max_label];
+ }
+ this._length = 0;
+ }
+
+ /**
+ * チェック対象のラベルを追加する。
+ *
+ * @param i_label_ref
+ */
+ public void push(NyARLabelingLabel i_label_ref)
+ {
+ this._labels[this._length] = i_label_ref;
+ this._length++;
+ }
+
+ /**
+ * 現在リストにあるラベルと重なっているかを返す。
+ *
+ * @param i_label
+ * @return 何れかのラベルの内側にあるならばfalse,独立したラベルである可能性が高ければtrueです.
+ */
+ public boolean check(NyARLabelingLabel i_label)
+ {
+ // 重なり処理かな?
+ NyARLabelingLabel[] label_pt = this._labels;
+ int px1 = (int)i_label.pos_x;
+ int py1 = (int)i_label.pos_y;
+ for (int i = this._length - 1; i >= 0; i--)
+ {
+ int px2 = (int)label_pt[i].pos_x;
+ int py2 = (int)label_pt[i].pos_y;
+ int d = (px1 - px2) * (px1 - px2) + (py1 - py2) * (py1 - py2);
+ if (d < label_pt[i].area / 4)
+ {
+ // 対象外
+ return false;
+ }
+ }
+ // 対象
+ return true;
+ }
+}
+
+
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/vertexdetect/NyARVertexDetector.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/vertexdetect/NyARVertexDetector.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/vertexdetect/NyARVertexDetector.java (revision 199)
@@ -0,0 +1,504 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.vertexdetect;
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.labeling.*;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.sandbox.x2.*;
+/**
+ * PCAではなく、頂点座標そのものからSquare位置を計算するクラス
+ *
+ */
+public class NyARVertexDetector implements INyARSquareDetector
+{
+ private static final double VERTEX_FACTOR = 1.0;// 線検出のファクタ
+
+ private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000
+
+ private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70
+ private final int _width;
+ private final int _height;
+
+ private final NyARLabeling_ARToolKit_X2 _labeling;
+
+ private final NyARLabelingImage _limage;
+
+ private final OverlapChecker _overlap_checker = new OverlapChecker();
+ private final NyARObserv2IdealMap _dist_factor_ref;
+
+ /**
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。
+ *
+ * @param i_param
+ */
+ public NyARVertexDetector(NyARObserv2IdealMap i_dist_factor_ref,NyARIntSize i_size) throws NyARException
+ {
+ this._width = i_size.w;
+ this._height = i_size.h;
+ this._dist_factor_ref = i_dist_factor_ref;
+ this._labeling = new NyARLabeling_ARToolKit_X2();
+ this._limage = new NyARLabelingImage(this._width, this._height);
+ this._labeling.attachDestination(this._limage);
+
+ // 輪郭の最大長は画面に映りうる最大の長方形サイズ。
+ int number_of_coord = (this._width + this._height) * 2;
+
+ // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。
+ this._max_coord = number_of_coord;
+ this._xcoord = new int[number_of_coord * 2];
+ this._ycoord = new int[number_of_coord * 2];
+ }
+
+ private final int _max_coord;
+ private final int[] _xcoord;
+ private final int[] _ycoord;
+
+ private void normalizeCoord(int[] i_coord_x, int[] i_coord_y, int i_index, int i_coord_num)
+ {
+ // vertex1を境界にして、後方に配列を連結
+ System.arraycopy(i_coord_x, 1, i_coord_x, i_coord_num, i_index);
+ System.arraycopy(i_coord_y, 1, i_coord_y, i_coord_num, i_index);
+ }
+
+ private final int[] __detectMarker_mkvertex = new int[5];
+
+ /**
+ * ARMarkerInfo2 *arDetectMarker2( ARInt16 *limage, int label_num, int *label_ref,int *warea, double *wpos, int *wclip,int area_max, int area_min, double
+ * factor, int *marker_num ) 関数の代替品 ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。 関数はo_marker_listに重なりを除外したマーカーリストを作成します。
+ *
+ * @param i_raster
+ * 解析する2値ラスタイメージを指定します。
+ * @param o_square_stack
+ * 抽出した正方形候補を格納するリスト
+ * @throws NyARException
+ */
+ public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException
+ {
+ final INyARLabeling labeling_proc = this._labeling;
+ final NyARLabelingImage limage = this._limage;
+
+ // 初期化
+
+ // マーカーホルダをリセット
+ o_square_stack.clear();
+
+ // ラベリング
+ labeling_proc.labeling(i_raster);
+
+ // ラベル数が0ならここまで
+ final int label_num = limage.getLabelStack().getLength();
+ if (label_num < 1) {
+ return;
+ }
+
+ final NyARLabelingLabelStack stack = limage.getLabelStack();
+ final NyARLabelingLabel[] labels = (NyARLabelingLabel[])stack.getArray();
+
+
+ // ラベルを大きい順に整列
+ stack.sortByArea();
+
+ // デカいラベルを読み飛ばし
+ int i;
+ for (i = 0; i < label_num; i++) {
+ // 検査対象内のラベルサイズになるまで無視
+ if (labels[i].area <= AR_AREA_MAX) {
+ break;
+ }
+ }
+
+ final int xsize = this._width;
+ final int ysize = this._height;
+ final int[] xcoord = this._xcoord;
+ final int[] ycoord = this._ycoord;
+ final int coord_max = this._max_coord;
+ final int[] mkvertex = this.__detectMarker_mkvertex;
+ final OverlapChecker overlap = this._overlap_checker;
+ int coord_num;
+ int label_area;
+ NyARLabelingLabel label_pt;
+
+ //重なりチェッカの最大数を設定
+ overlap.reset(label_num);
+
+ for (; i < label_num; i++) {
+ label_pt = labels[i];
+ label_area = label_pt.area;
+ // 検査対象サイズよりも小さくなったら終了
+ if (label_area < AR_AREA_MIN) {
+ break;
+ }
+ // クリップ領域が画面の枠に接していれば除外
+ if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){
+ continue;
+ }
+ if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){
+ continue;
+ }
+ // 既に検出された矩形との重なりを確認
+ if (!overlap.check(label_pt)) {
+ // 重なっているようだ。
+ continue;
+ }
+
+ // 輪郭を取得
+ coord_num = limage.getContour(i, coord_max, xcoord, ycoord);
+ if (coord_num == coord_max) {
+ // 輪郭が大きすぎる。
+ continue;
+ }
+ //頂点候補のインデクスを取得
+ final int vertex1 = scanVertex(xcoord, ycoord, coord_num);
+
+ // 頂点候補(vertex1)を先頭に並べなおした配列を作成する。
+ normalizeCoord(xcoord, ycoord, vertex1, coord_num);
+
+ // 領域を準備する。
+ NyARSquare square_ptr = (NyARSquare)o_square_stack.prePush();
+
+ // 頂点情報を取得
+ if (!getSquareVertex(xcoord, ycoord, vertex1, coord_num, label_area, mkvertex)) {
+ o_square_stack.pop();// 頂点の取得が出来なかったので破棄
+ continue;
+ }
+ //頂点情報からライン情報を作っちゃう
+ getSquare(mkvertex, xcoord, ycoord, square_ptr);
+
+ // 検出済の矩形の属したラベルを重なりチェックに追加する。
+ overlap.push(label_pt);
+ }
+ return;
+ }
+ /**
+ * 2つの頂点座標を結ぶ直線から、NyARLinearを計算する。
+ * @param i_v1
+ * @param i_v2
+ * @param o_line
+ */
+ final private void getLine(NyARDoublePoint2d i_v1,NyARDoublePoint2d i_v2,NyARLinear o_line)
+ {
+ final double x=i_v1.x-i_v2.x;
+ final double y=i_v1.y-i_v2.y;
+ final double x2=x*x;
+ final double y2=y*y;
+ final double rise_=Math.sqrt(x2/(x2+y2));
+ o_line.rise=rise_;
+ o_line.run=Math.sqrt(y2/(x2+y2));
+ if(x<0){
+ if(y<0){
+ o_line.rise=-o_line.rise;
+ }else{
+ o_line.rise=-o_line.rise;
+ o_line.run=-o_line.run;
+ }
+ }else{
+ if(y<0){
+ o_line.rise=-o_line.rise;
+ o_line.run=-o_line.run;
+ }else{
+ o_line.rise=-o_line.rise;
+ }
+ }
+ o_line.intercept=(i_v1.y+(o_line.run/o_line.rise)*(i_v1.x))*rise_;
+
+ }
+
+ private void getSquare(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square)
+ {
+ final NyARObserv2IdealMap dist_factor=this._dist_factor_ref;
+ final NyARDoublePoint2d[] vertex=o_square.sqvertex;
+ //歪み補正
+ for(int i=0;i<4;i++)
+ {
+ final int idx=i_mkvertex[i];
+ o_square.imvertex[i].x=i_xcoord[idx];
+ o_square.imvertex[i].y=i_ycoord[idx];
+ dist_factor.observ2Ideal(i_xcoord[idx], i_ycoord[idx],vertex[i]);
+ }
+ //ライン計算
+ getLine(vertex[1],vertex[0],o_square.line[0]);
+ getLine(vertex[2],vertex[1],o_square.line[1]);
+ getLine(vertex[3],vertex[2],o_square.line[2]);
+ getLine(vertex[0],vertex[3],o_square.line[3]);
+ return;
+ }
+
+ /**
+ * 辺からの対角線が最長になる点を対角線候補として返す。
+ *
+ * @param i_xcoord
+ * @param i_ycoord
+ * @param i_coord_num
+ * @return
+ */
+ private int scanVertex(int[] i_xcoord, int[] i_ycoord, int i_coord_num)
+ {
+ final int sx = i_xcoord[0];
+ final int sy = i_ycoord[0];
+ int d = 0;
+ int w, x, y;
+ int ret = 0;
+ for (int i = 1; i < i_coord_num; i++) {
+ x = i_xcoord[i] - sx;
+ y = i_ycoord[i] - sy;
+ w = x * x + y * y;
+ if (w > d) {
+ d = w;
+ ret = i;
+ }
+ // ここでうまく終了条件入れられないかな。
+ }
+ return ret;
+ }
+
+ private final NyARVertexCounter __getSquareVertex_wv1 = new NyARVertexCounter();
+
+ private final NyARVertexCounter __getSquareVertex_wv2 = new NyARVertexCounter();
+
+ /**
+ * static int arDetectMarker2_check_square( int area, ARMarkerInfo2 *marker_info2, double factor ) 関数の代替関数 OPTIMIZED STEP [450->415] o_squareに頂点情報をセットします。
+ *
+ * @param i_x_coord
+ * @param i_y_coord
+ * @param i_vertex1_index
+ * @param i_coord_num
+ * @param i_area
+ * @param o_vertex
+ * 要素数はint[4]である事
+ * @return
+ */
+ private boolean getSquareVertex(int[] i_x_coord, int[] i_y_coord, int i_vertex1_index, int i_coord_num, int i_area, int[] o_vertex)
+ {
+ final NyARVertexCounter wv1 = this.__getSquareVertex_wv1;
+ final NyARVertexCounter wv2 = this.__getSquareVertex_wv2;
+ final int end_of_coord = i_vertex1_index + i_coord_num - 1;
+ final int sx = i_x_coord[i_vertex1_index];// sx = marker_info2->x_coord[0];
+ final int sy = i_y_coord[i_vertex1_index];// sy = marker_info2->y_coord[0];
+ int dmax = 0;
+ int v1 = i_vertex1_index;
+ for (int i = 1 + i_vertex1_index; i < end_of_coord; i++) {// for(i=1;i<marker_info2->coord_num-1;i++)
+ // {
+ final int d = (i_x_coord[i] - sx) * (i_x_coord[i] - sx) + (i_y_coord[i] - sy) * (i_y_coord[i] - sy);
+ if (d > dmax) {
+ dmax = d;
+ v1 = i;
+ }
+ }
+ final double thresh = (i_area / 0.75) * 0.01 * VERTEX_FACTOR;
+
+ o_vertex[0] = i_vertex1_index;
+
+ if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v1, thresh)) { // if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,0,v1,thresh,wv1,&wvnum1)<
+ // 0 ) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v1, end_of_coord, thresh)) {// if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,v1,marker_info2->coord_num-1,thresh,wv2,&wvnum2)
+ // < 0) {
+ return false;
+ }
+
+ int v2;
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {// if(wvnum1 == 1 && wvnum2== 1) {
+ o_vertex[1] = wv1.vertex[0];
+ o_vertex[2] = v1;
+ o_vertex[3] = wv2.vertex[0];
+ } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {// }else if( wvnum1 > 1 && wvnum2== 0) {
+ //頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。
+ v2 = (v1-i_vertex1_index)/2+i_vertex1_index;
+ if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v2, thresh)) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v2, v1, thresh)) {
+ return false;
+ }
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+ o_vertex[1] = wv1.vertex[0];
+ o_vertex[2] = wv2.vertex[0];
+ o_vertex[3] = v1;
+ } else {
+ return false;
+ }
+ } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) {
+ //v2 = (v1-i_vertex1_index+ end_of_coord-i_vertex1_index) / 2+i_vertex1_index;
+ v2 = (v1+ end_of_coord)/2;
+
+ if (!wv1.getVertex(i_x_coord, i_y_coord, v1, v2, thresh)) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v2, end_of_coord, thresh)) {
+ return false;
+ }
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+ o_vertex[1] = v1;
+ o_vertex[2] = wv1.vertex[0];
+ o_vertex[3] = wv2.vertex[0];
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ o_vertex[4] = end_of_coord;
+ return true;
+ }
+}
+
+/**
+ * get_vertex関数を切り離すためのクラス
+ *
+ */
+final class NyARVertexCounter
+{
+ public final int[] vertex = new int[10];// 5まで削れる
+
+ public int number_of_vertex;
+
+ private double thresh;
+
+ private int[] x_coord;
+
+ private int[] y_coord;
+
+ public boolean getVertex(int[] i_x_coord, int[] i_y_coord, int st, int ed, double i_thresh)
+ {
+ this.number_of_vertex = 0;
+ this.thresh = i_thresh;
+ this.x_coord = i_x_coord;
+ this.y_coord = i_y_coord;
+ return get_vertex(st, ed);
+ }
+
+ /**
+ * static int get_vertex( int x_coord[], int y_coord[], int st, int ed,double thresh, int vertex[], int *vnum) 関数の代替関数
+ *
+ * @param x_coord
+ * @param y_coord
+ * @param st
+ * @param ed
+ * @param thresh
+ * @return
+ */
+ private boolean get_vertex(int st, int ed)
+ {
+ int v1 = 0;
+ final int[] lx_coord = this.x_coord;
+ final int[] ly_coord = this.y_coord;
+ final double a = ly_coord[ed] - ly_coord[st];
+ final double b = lx_coord[st] - lx_coord[ed];
+ final double c = lx_coord[ed] * ly_coord[st] - ly_coord[ed] * lx_coord[st];
+ double dmax = 0;
+ for (int i = st + 1; i < ed; i++) {
+ final double d = a * lx_coord[i] + b * ly_coord[i] + c;
+ if (d * d > dmax) {
+ dmax = d * d;
+ v1 = i;
+ }
+ }
+ if (dmax / (a * a + b * b) > thresh) {
+ if (!get_vertex(st, v1)) {
+ return false;
+ }
+ if (number_of_vertex > 5) {
+ return false;
+ }
+ vertex[number_of_vertex] = v1;// vertex[(*vnum)] = v1;
+ number_of_vertex++;// (*vnum)++;
+
+ if (!get_vertex(v1, ed)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+
+/**
+ * ラベル同士の重なり(内包関係)を調べるクラスです。 ラベルリストに内包するラベルを蓄積し、それにターゲットのラベルが内包されているか を確認します。
+ */
+class OverlapChecker
+{
+ private NyARLabelingLabel[] _labels = new NyARLabelingLabel[32];
+
+ private int _length;
+
+ /**
+ * 最大i_max_label個のラベルを蓄積できるようにオブジェクトをリセットする
+ *
+ * @param i_max_label
+ */
+ public void reset(int i_max_label)
+ {
+ if (i_max_label > this._labels.length) {
+ this._labels = new NyARLabelingLabel[i_max_label];
+ }
+ this._length = 0;
+ }
+
+ /**
+ * チェック対象のラベルを追加する。
+ *
+ * @param i_label_ref
+ */
+ public void push(NyARLabelingLabel i_label_ref)
+ {
+ this._labels[this._length] = i_label_ref;
+ this._length++;
+ }
+
+ /**
+ * 現在リストにあるラベルと重なっているかを返す。
+ *
+ * @param i_label
+ * @return 何れかのラベルの内側にあるならばfalse,独立したラベルである可能性が高ければtrueです.
+ */
+ public boolean check(NyARLabelingLabel i_label)
+ {
+ // 重なり処理かな?
+ final NyARLabelingLabel[] label_pt = this._labels;
+ final int px1 = (int) i_label.pos_x;
+ final int py1 = (int) i_label.pos_y;
+ for (int i = this._length - 1; i >= 0; i--) {
+ final int px2 = (int) label_pt[i].pos_x;
+ final int py2 = (int) label_pt[i].pos_y;
+ final int d = (px1 - px2) * (px1 - px2) + (py1 - py2) * (py1 - py2);
+ if (d < label_pt[i].area / 4) {
+ // 対象外
+ return false;
+ }
+ }
+ // 対象
+ return true;
+ }
+}
\ No newline at end of file
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyMath.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyMath.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyMath.java (revision 199)
@@ -0,0 +1,230 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+public class NyMath
+{
+ public final static long FIXEDFLOAT24_1=0x1000000L;
+ public final static long FIXEDFLOAT24_0_25=FIXEDFLOAT24_1/4;
+ public final static long FIXEDFLOAT16_1=0x10000L;
+ public final static long FIXEDFLOAT16_0_25=FIXEDFLOAT16_1/4;
+ public final static long FIXEDFLOAT8_1=0x100L;
+
+ private final static int FIXEDFLOAT16I_1=(int)FIXEDFLOAT16_1;
+ private final static int FIXEDFLOAT16I_0_25=(int)FIXEDFLOAT16_1/4;
+
+
+
+
+ private final static int FF16_PI=(int)(Math.PI*FIXEDFLOAT16_1);
+ private final static int FF16_2PI=(int)(2 *FF16_PI);
+ private final static int FF16_05PI=(int)(FF16_PI/2);
+ /* sinテーブルは0-2PIを1024分割
+ * acosテーブルは0-1を256分割
+ */
+ private final static int[] sin_table=new int[339];
+ private final static int[] acos_table=new int[1537];
+ private final static int SQRT_LOOP=10;
+ /**
+ * http://www.geocities.co.jp/SiliconValley-PaloAlto/5438/
+ * 参考にしました。
+ * 少数点部が16bitの変数の平方根を求めます。
+ * 戻り値の小数点部分は16bitです。
+ * @param i_v
+ * @return
+ */
+ public static long sqrtFixdFloat16(long i_ff16)
+ {
+ long t=0,s;
+ s=i_ff16>0?i_ff16:-i_ff16;
+ if(i_ff16==0){
+ return 0;
+ }
+ for(int i=SQRT_LOOP;i>0;i--){
+ t = s;
+ s = (t+((i_ff16<<16)/t))>>1;
+ if(s==t){
+ break;
+ }
+ };
+ return t;
+ }
+ public static long sqrtFixdFloat(long i_ff,int i_bit)
+ {
+ long t=0,s;
+ s=i_ff>0?i_ff:-i_ff;
+ if(i_ff==0){
+ return 0;
+ }
+ for(int i=SQRT_LOOP;i>0;i--){
+ t = s;
+ s = (t+((i_ff<<i_bit)/t))>>1;
+ if(s==t){
+ break;
+ }
+ }
+ return t;
+ }
+ public static int acosFixedFloat16(int i_ff24)
+ {/*
+ long x=i_ff24>>8;
+ long x2=(x*x)>>16;
+ long x3=(x2*x)>>16;
+ long x4=(x2*x2)>>16;
+// return FF16_05PI-(int)(x+x3/6+(((3*x3*x2/(2*4*5)+(3*5*x4*x3)/(2*4*6*7)))>>16));
+*/
+ int result;
+ int abs_ff24=i_ff24>0?i_ff24:-i_ff24;
+ //(0<=n<=0.25) 0<=0-16384(65536/4)まではy=PI/2-xので近似
+ //(0.25<n<=1/2PI) 16385-65536までは(128ステップ単位)のテーブルを使用
+
+ if(abs_ff24<FIXEDFLOAT24_0_25){
+ //0.25までの範囲は、2次の近似式
+ result=(i_ff24>>8);
+ return FF16_05PI-result+((((result*result)>>16)*result)>>16)/6;
+ }else{
+ result=acos_table[((abs_ff24>>8)-FIXEDFLOAT16I_0_25)>>5];
+ if (i_ff24 < 0) {
+ return FF16_PI-result;
+ }else{
+ return result;
+ }
+ }
+// return (int)(Math.acos((double)i_ff24/0x1000000)*0x10000);
+ }
+ /**
+ * 誤差確認用の関数
+ * @param args
+ */
+ public static void main(String[] args)
+ {
+ //sin
+ NyMath.initialize();
+// for(int i=0;i<3600;i++){
+// int s=cosFixedFloat24((int)(FIXEDFLOAT16I_1*i*Math.PI/1800));
+// System.out.println((double)(s-(int)(FIXEDFLOAT24_1*Math.cos((i*Math.PI/1800))))/FIXEDFLOAT24_1);
+// }
+ //acos
+ for(int i=-1000;i<1000;i++){
+ int s=acosFixedFloat16((int)(FIXEDFLOAT24_1*i/1000));
+// System.out.println((double)(s-(int)(FIXEDFLOAT16_1*Math.acos((double)i/1000)))/FIXEDFLOAT16_1);
+ System.out.println((double)s/FIXEDFLOAT16I_1);
+ }
+ }
+ public static int sinFixedFloat24(int i_ff16)
+ {
+ int result;
+ //i_ff16を0-2πに制限
+ int rad=i_ff16%FF16_2PI;
+ if(rad<0){
+ rad=rad+FF16_2PI;
+ }
+ //4ブロックに分割
+ int dv=rad/FF16_05PI;
+ //radを0-0.5PIに制限
+ rad=rad-dv*FF16_05PI;
+ //radをdvにより補正
+ if(dv==1 || dv==3){
+ rad=FF16_05PI-rad;
+ }
+ //(0<=n<=0.25) 0<=0-16384(65536/4)まではy=xので近似
+ //(0.25<n<=1/2PI) 16385-102944までは(256ステップ単位)のテーブルを使用
+ //負にする
+ if(rad<FIXEDFLOAT16_0_25){
+ result=rad<<8;
+ }else{
+ result=sin_table[(rad-FIXEDFLOAT16I_0_25)>>8];
+ }
+ if(dv>=2){
+ result=-result;
+ }
+ return result;
+// return (int)(Math.sin((double)i_ff16/0x10000)*0x1000000);
+ }
+ public static int cosFixedFloat24(int i_ff16)
+ {
+ int result;
+ //i_ff16を0-2πに制限
+ int rad=(i_ff16+FF16_05PI)%FF16_2PI;
+ if(rad<0){
+ rad=rad+FF16_2PI;
+ }
+ //4ブロックに分割
+ int dv=rad/FF16_05PI;
+ //radを0-0.5PIに制限
+ rad=rad-dv*FF16_05PI;
+ //radをdvにより補正
+ if(dv==1 || dv==3){
+ rad=FF16_05PI-rad;
+ }
+ //(0<=n<=0.25) 0<=0-16384(65536/4)まではy=xので近似
+ //(0.25<n<=1/2PI) 16385-102944までは(256ステップ単位)のテーブルを使用
+ //負にする
+ if(rad<FIXEDFLOAT16_0_25){
+ result=rad<<8;
+ }else{
+ result=sin_table[(rad-FIXEDFLOAT16I_0_25)>>8];
+ }
+ if(dv>=2){
+ result=-result;
+ }
+ return result;
+// return (int)(Math.cos((double)i_ff16/0x10000)*0x1000000);
+ }
+ public static void initialize()
+ {
+
+ int step;
+ step=FIXEDFLOAT16I_0_25+256;
+ for(int i=0;i<339;i++){
+ sin_table[i]=(int)((Math.sin((double) step / (double) FIXEDFLOAT16I_1))*FIXEDFLOAT24_1);
+ step+=256;
+ }
+ //acosテーブル初期化
+ step=FIXEDFLOAT16I_0_25+32;
+ for (int i = 0; i < 1537; i++) {
+ acos_table[i] =(int)((Math.acos((double) step/(double) FIXEDFLOAT16I_1))*FIXEDFLOAT16_1);
+ step+=32;
+ }
+ return;
+ }
+ public static void printF16(long i_value)
+ {
+ System.out.println((double)i_value/0x10000);
+ return;
+ }
+ public static void printF24(long i_value)
+ {
+ System.out.println((double)i_value/0x1000000);
+ return;
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/RawFileTest_X2.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/RawFileTest_X2.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/RawFileTest_X2.java (revision 199)
@@ -0,0 +1,111 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import java.io.*;
+import java.util.*;
+
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.core.param.NyARParam;
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;
+import jp.nyatla.nyartoolkit.core.transmat.*;
+
+
+/**
+ * 320x240のBGRA32で記録されたRAWイメージから、1種類のパターンを認識し、
+ * その変換行列を1000回求め、それにかかったミリ秒時間を表示します。
+ *
+ */
+public class RawFileTest_X2
+{
+ private final String code_file = "../../Data/patt.hiro";
+
+ private final String data_file = "../../Data/320x240ABGR.raw";
+
+ private final String camera_file = "../../Data/camera_para.dat";
+
+ public RawFileTest_X2()
+ {
+ NyMath.initialize();
+ }
+
+
+ public void Test_arDetectMarkerLite() throws Exception
+ {
+ // AR用カメラパラメタファイルをロード
+ NyARParam ap = new NyARParam();
+ ap.loadARParamFromFile(camera_file);
+ ap.changeScreenSize(320, 240);
+
+ // AR用のパターンコードを読み出し
+ NyARCode code = new NyARCode(16, 16);
+ code.loadARPattFromFile(code_file);
+
+ // 試験イメージの読み出し(320x240 BGRAのRAWデータ)
+ File f = new File(data_file);
+ FileInputStream fs = new FileInputStream(data_file);
+ byte[] buf = new byte[(int) f.length()];
+ fs.read(buf);
+ INyARRgbRaster ra = NyARRgbRaster_BGRA.wrap(buf, 320, 240);
+ // Blank_Raster ra=new Blank_Raster(320, 240);
+
+ // 1パターンのみを追跡するクラスを作成
+ NyARSingleDetectMarker_X2 ar = new NyARSingleDetectMarker_X2(ap, code, 80.0);
+ NyARTransMatResult result_mat = new NyARTransMatResult();
+ ar.setContinueMode(false);
+ ar.detectMarkerLite(ra, 100);
+ ar.getTransmationMatrix(result_mat);
+
+ // マーカーを検出
+ Date d2 = new Date();
+ for (int i = 0; i < 1000; i++) {
+ // 変換行列を取得
+ ar.detectMarkerLite(ra, 100);
+ ar.getTransmationMatrix(result_mat);
+ }
+ Date d = new Date();
+ System.out.println(d.getTime() - d2.getTime());
+ }
+
+ public static void main(String[] args)
+ {
+
+ try {
+ RawFileTest_X2 t = new RawFileTest_X2();
+ // t.Test_arGetVersion();
+ t.Test_arDetectMarkerLite();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/VisualTest.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/VisualTest.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/VisualTest.java (revision 199)
@@ -0,0 +1,130 @@
+/* このソースは実験用のソースです。
+ * 動いたり動かなかったりします。
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import javax.media.*;
+
+import javax.media.util.BufferToImage;
+import javax.media.format.*;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.jmf.utils.*;
+import jp.nyatla.nyartoolkit.sandbox.quadx2.NyARRasterFilter_ARTTh_Quad;
+
+import jp.nyatla.nyartoolkit.core.*;
+
+import java.awt.*;
+
+import jp.nyatla.nyartoolkit.core.labeling.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.rasterfilter.*;
+import jp.nyatla.nyartoolkit.core2.rasterfilter.rgb2gs.*;
+import jp.nyatla.nyartoolkit.core2.rasterfilter.gs2bin.*;
+import jp.nyatla.utils.j2se.LabelingBufferdImage;
+import jp.nyatla.nyartoolkit.core2.rasteranalyzer.threshold.*;
+
+
+
+public class VisualTest extends Frame implements JmfCaptureListener
+{
+ private final String camera_file = "../../Data/camera_para.dat";
+
+ private JmfNyARRaster_RGB _raster;
+
+ private JmfCameraCapture capture;
+ private NyARParam ap;
+ public VisualTest() throws NyARException, NyARException
+ {
+ setBounds(0, 0, 640 + 64, 720 + 64);
+ // キャプチャの準備
+ capture = new JmfCameraCapture(320, 240, 30f, JmfCameraCapture.PIXEL_FORMAT_RGB);
+ capture.setCaptureListener(this);
+
+ // キャプチャイメージ用のラスタを準備
+ this._raster = new JmfNyARRaster_RGB(320, 240);
+
+ // AR用カメラパラメタファイルをロード
+ ap = new NyARParam();
+ ap.loadARParamFromFile(camera_file);
+ ap.changeScreenSize(320, 240);
+
+
+ }
+
+ private NyARBinRaster _binraster1 = new NyARBinRaster(160,120);
+
+ private NyARGrayscaleRaster _gsraster1 = new NyARGrayscaleRaster(320, 240);
+ private INyARRasterThresholdAnalyzer _tha=new NyARRasterThresholdAnalyzer_DiffHistgram();
+
+ private LabelingBufferdImage _bimg = new LabelingBufferdImage(320, 240);
+ private LabelingBufferdImage _bimg2 = new LabelingBufferdImage(160, 120);
+ private NyARRasterFilter_ARTTh_Quad _tobin_filter=new NyARRasterFilter_ARTTh_Quad(100);
+
+ public void onUpdateBuffer(Buffer i_buffer)
+ {
+
+ try {
+ // キャプチャしたバッファをラスタにセット
+ _raster.setBuffer(i_buffer);
+
+ Graphics g = getGraphics();
+ // キャプチャ画像
+ BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());
+ Image img = b2i.createImage(i_buffer);
+ this.getGraphics().drawImage(img, 32, 32, this);
+
+ // 画像1
+ INyARRasterFilter_RgbToGs filter_rgb2gs = new NyARRasterFilter_RgbAve();
+// INyARRasterFilter_RgbToGs filter_rgb2gs = new NyARRasterFilter_RgbMul();
+
+ filter_rgb2gs.doFilter(_raster, _gsraster1);
+ this._bimg.drawImage(this._gsraster1);
+ this.getGraphics().drawImage(this._bimg, 32 + 320, 32, 320 + 320 + 32, 240 + 32, 0, 240, 320, 0, this);
+ _tha.analyzeRaster(_gsraster1);
+ NyARRasterFilter_Threshold gs2bin=new NyARRasterFilter_Threshold(_tha.getThreshold());
+
+
+ // 画像2
+ _tobin_filter.doFilter(_raster, _binraster1);
+ this._bimg2.drawImage(_binraster1);
+ this.getGraphics().drawImage(this._bimg2, 32, 32 + 240, 320 + 32, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+ // 画像3
+ NyARLabelingImage limage = new NyARLabelingImage(320, 240);
+ NyARLabeling_ARToolKit labeling = new NyARLabeling_ARToolKit();
+ labeling.attachDestination(limage);
+ labeling.labeling(_binraster1);
+ this._bimg.drawImage(this._gsraster1);
+
+ NyARSquareStack stack = new NyARSquareStack(100);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ private void startCapture()
+ {
+ try {
+ capture.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ try {
+ VisualTest mainwin = new VisualTest();
+ mainwin.setVisible(true);
+ mainwin.startCapture();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARLabeling_ARToolKit_X2.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARLabeling_ARToolKit_X2.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARLabeling_ARToolKit_X2.java (revision 199)
@@ -0,0 +1,382 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.labeling.*;
+
+/**
+ * 計算部から浮動小数点計算を除外したNyARLabeling_ARToolKit
+ * NyARLabeling_ARToolKitと同じ処理をするけど、エリア計算にintを使う。
+ * 画面サイズが1600x1600を超えると挙動が怪しくなる。
+ *
+ */
+public class NyARLabeling_ARToolKit_X2 implements INyARLabeling
+{
+ private static final int WORK_SIZE = 1024 * 32;// #define WORK_SIZE 1024*32
+
+ private final NyARWorkHolder work_holder = new NyARWorkHolder(WORK_SIZE);
+
+ private NyARIntSize _dest_size;
+
+ private INyARLabelingImage _out_image;
+
+ public void attachDestination(INyARLabelingImage i_destination_image) throws NyARException
+ {
+ // サイズチェック
+ NyARIntSize size = i_destination_image.getSize();
+ this._out_image = i_destination_image;
+
+ // NyLabelingImageのイメージ初期化(枠書き)
+ int[][] img = (int[][]) i_destination_image.getBufferReader().getBuffer();
+ for (int i = 0; i < size.w; i++) {
+ img[0][i] = 0;
+ img[size.h - 1][i] = 0;
+ }
+ for (int i = 0; i < size.h; i++) {
+ img[i][0] = 0;
+ img[i][size.w - 1] = 0;
+ }
+
+ // サイズ(参照値)を保存
+ this._dest_size = size;
+ }
+
+ public INyARLabelingImage getAttachedDestination()
+ {
+ return this._out_image;
+ }
+
+ /**
+ * static ARInt16 *labeling2( ARUint8 *image, int thresh,int *label_num, int **area, double **pos, int **clip,int **label_ref, int LorR ) 関数の代替品
+ * ラスタimageをラベリングして、結果を保存します。 Optimize:STEP[1514->1493]
+ *
+ * @param i_raster
+ * @throws NyARException
+ */
+ public void labeling(NyARBinRaster i_raster) throws NyARException
+ {
+ int m, n; /* work */
+ int i, j, k;
+ INyARLabelingImage out_image = this._out_image;
+
+ // サイズチェック
+ NyARIntSize in_size = i_raster.getSize();
+ this._dest_size.isEqualSize(in_size);
+
+ final int lxsize = in_size.w;// lxsize = arUtil_c.arImXsize;
+ final int lysize = in_size.h;// lysize = arUtil_c.arImYsize;
+ int[][] label_img = (int[][]) out_image.getBufferReader().getBuffer();
+
+ // 枠作成はインスタンスを作った直後にやってしまう。
+
+ // ラベリング情報のリセット(ラベリングインデックスを使用)
+ out_image.reset(true);
+
+ int[] label_idxtbl = out_image.getIndexArray();
+
+ int[] work2_pt;
+ int wk_max = 0;
+
+ int label_pixel;
+ int[][] raster_buf = (int[][]) i_raster.getBufferReader().getBuffer();
+ int[] line_ptr;
+ int[][] work2 = this.work_holder.work2;
+ int[] label_img_pt0, label_img_pt1;
+ for (j = 1; j < lysize - 1; j++) {// for (int j = 1; j < lysize - 1;j++, pnt += poff*2, pnt2 += 2) {
+ line_ptr = raster_buf[j];
+ label_img_pt0 = label_img[j];
+ label_img_pt1 = label_img[j - 1];
+ for (i = 1; i < lxsize - 1; i++) {// for(int i = 1; i < lxsize-1;i++, pnt+=poff, pnt2++) {
+ // RGBの合計値が閾値より小さいかな?
+ if (line_ptr[i] == 0) {
+ // pnt1 = ShortPointer.wrap(pnt2, -lxsize);//pnt1 =&(pnt2[-lxsize]);
+ if (label_img_pt1[i] > 0) {// if( *pnt1 > 0 ) {
+ label_pixel = label_img_pt1[i];// *pnt2 = *pnt1;
+
+ work2_pt = work2[label_pixel - 1];
+ work2_pt[0]++;// work2[((*pnt2)-1)*7+0] ++;
+ work2_pt[1] += i;// work2[((*pnt2)-1)*7+1] += i;
+ work2_pt[2] += j;// work2[((*pnt2)-1)*7+2] += j;
+ work2_pt[6] = j;// work2[((*pnt2)-1)*7+6] = j;
+ } else if (label_img_pt1[i + 1] > 0) {// }else if(*(pnt1+1) > 0 ) {
+ if (label_img_pt1[i - 1] > 0) {// if( *(pnt1-1) > 0 ) {
+ m = label_idxtbl[label_img_pt1[i + 1] - 1];// m =work[*(pnt1+1)-1];
+ n = label_idxtbl[label_img_pt1[i - 1] - 1];// n =work[*(pnt1-1)-1];
+ if (m > n) {
+ label_pixel = n;// *pnt2 = n;
+ // wk=IntPointer.wrap(work, 0);//wk =
+ // &(work[0]);
+ for (k = 0; k < wk_max; k++) {
+ if (label_idxtbl[k] == m) {// if( *wk == m )
+ label_idxtbl[k] = n;// *wk = n;
+ }
+ }
+ } else if (m < n) {
+ label_pixel = m;// *pnt2 = m;
+ // wk=IntPointer.wrap(work,0);//wk = &(work[0]);
+ for (k = 0; k < wk_max; k++) {
+ if (label_idxtbl[k] == n) {// if( *wk == n ){
+ label_idxtbl[k] = m;// *wk = m;
+ }
+ }
+ } else {
+ label_pixel = m;// *pnt2 = m;
+ }
+ work2_pt = work2[label_pixel - 1];
+ work2_pt[0]++;
+ work2_pt[1] += i;
+ work2_pt[2] += j;
+ work2_pt[6] = j;
+ } else if ((label_img_pt0[i - 1]) > 0) {// }else if(*(pnt2-1) > 0) {
+ m = label_idxtbl[(label_img_pt1[i + 1]) - 1];// m =work[*(pnt1+1)-1];
+ n = label_idxtbl[label_img_pt0[i - 1] - 1];// n =work[*(pnt2-1)-1];
+ if (m > n) {
+
+ label_pixel = n;// *pnt2 = n;
+ for (k = 0; k < wk_max; k++) {
+ if (label_idxtbl[k] == m) {// if( *wk == m ){
+ label_idxtbl[k] = n;// *wk = n;
+ }
+ }
+ } else if (m < n) {
+ label_pixel = m;// *pnt2 = m;
+ for (k = 0; k < wk_max; k++) {
+ if (label_idxtbl[k] == n) {// if( *wk == n ){
+ label_idxtbl[k] = m;// *wk = m;
+ }
+ }
+ } else {
+ label_pixel = m;// *pnt2 = m;
+ }
+ work2_pt = work2[label_pixel - 1];
+ work2_pt[0]++;// work2[((*pnt2)-1)*7+0] ++;
+ work2_pt[1] += i;// work2[((*pnt2)-1)*7+1] += i;
+ work2_pt[2] += j;// work2[((*pnt2)-1)*7+2] += j;
+ } else {
+
+ label_pixel = label_img_pt1[i + 1];// *pnt2 =
+ // *(pnt1+1);
+
+ work2_pt = work2[label_pixel - 1];
+ work2_pt[0]++;// work2[((*pnt2)-1)*7+0] ++;
+ work2_pt[1] += i;// work2[((*pnt2)-1)*7+1] += i;
+ work2_pt[2] += j;// work2[((*pnt2)-1)*7+2] += j;
+ if (work2_pt[3] > i) {// if(
+ // work2[((*pnt2)-1)*7+3] >
+ // i ){
+ work2_pt[3] = i;// work2[((*pnt2)-1)*7+3] = i;
+ }
+ work2_pt[6] = j;// work2[((*pnt2)-1)*7+6] = j;
+ }
+ } else if ((label_img_pt1[i - 1]) > 0) {// }else if(
+ // *(pnt1-1) > 0 ) {
+ label_pixel = label_img_pt1[i - 1];// *pnt2 =
+ // *(pnt1-1);
+
+ work2_pt = work2[label_pixel - 1];
+ work2_pt[0]++;// work2[((*pnt2)-1)*7+0] ++;
+ work2_pt[1] += i;// work2[((*pnt2)-1)*7+1] += i;
+ work2_pt[2] += j;// work2[((*pnt2)-1)*7+2] += j;
+ if (work2_pt[4] < i) {// if( work2[((*pnt2)-1)*7+4] <i ){
+ work2_pt[4] = i;// work2[((*pnt2)-1)*7+4] = i;
+ }
+ work2_pt[6] = j;// work2[((*pnt2)-1)*7+6] = j;
+ } else if (label_img_pt0[i - 1] > 0) {// }else if(*(pnt2-1) > 0) {
+ label_pixel = label_img_pt0[i - 1];// *pnt2 =*(pnt2-1);
+
+ work2_pt = work2[label_pixel - 1];
+ work2_pt[0]++;// work2[((*pnt2)-1)*7+0] ++;
+ work2_pt[1] += i;// work2[((*pnt2)-1)*7+1] += i;
+ work2_pt[2] += j;// work2[((*pnt2)-1)*7+2] += j;
+ if (work2_pt[4] < i) {// if( work2[((*pnt2)-1)*7+4] <i ){
+ work2_pt[4] = i;// work2[((*pnt2)-1)*7+4] = i;
+ }
+ } else {
+ // 現在地までの領域を予約
+ this.work_holder.reserv(wk_max);
+ wk_max++;
+ label_idxtbl[wk_max - 1] = wk_max;
+ label_pixel = wk_max;// work[wk_max-1] = *pnt2 = wk_max;
+ work2_pt = work2[wk_max - 1];
+ work2_pt[0] = 1;
+ work2_pt[1] = i;
+ work2_pt[2] = j;
+ work2_pt[3] = i;
+ work2_pt[4] = i;
+ work2_pt[5] = j;
+ work2_pt[6] = j;
+ }
+ label_img_pt0[i] = label_pixel;
+ } else {
+ label_img_pt0[i] = 0;// *pnt2 = 0;
+ }
+ }
+ }
+ // インデックステーブルとラベル数の計算
+ int wlabel_num = 1;// *label_num = *wlabel_num = j - 1;
+
+ for (i = 0; i < wk_max; i++) {// for(int i = 1; i <= wk_max; i++,wk++) {
+ label_idxtbl[i] = (label_idxtbl[i] == i + 1) ? wlabel_num++ : label_idxtbl[label_idxtbl[i] - 1];// *wk=(*wk==i)?j++:work[(*wk)-1];
+ }
+ wlabel_num -= 1;// *label_num = *wlabel_num = j - 1;
+ if (wlabel_num == 0) {// if( *label_num == 0 ) {
+ // 発見数0
+ out_image.getLabelStack().clear();
+ return;
+ }
+ // ラベルの整理
+ updateLabelStackLarge(out_image.getLabelStack(), label_idxtbl, in_size, work2, wk_max, wlabel_num);
+
+ return;
+ }
+ private int[][] __updateLabelStackLarge_temp=new int[64][7];/*area,x,y,l,r,t,b*/
+
+ /* 構造が変わるから、ハイスピード版実装するときに使う。 */
+ private void updateLabelStackLarge(NyARLabelingLabelStack i_stack, int[] i_lindex, NyARIntSize i_size, int[][] i_work, int i_work_max, int i_number_of_label) throws NyARException
+ {
+ //計算用のワークを確保
+ int[][] temp=this.__updateLabelStackLarge_temp;
+ if(temp.length<i_number_of_label){
+ temp=new int[i_number_of_label+64][7];
+ this.__updateLabelStackLarge_temp=temp;
+ }
+
+ // ラベルバッファを予約
+ i_stack.reserv(i_number_of_label);
+ // エリアと重心、クリップ領域を計算
+ final NyARLabelingLabel[] labels = (NyARLabelingLabel[])i_stack.getArray();
+ for (int i = 0; i < i_number_of_label; i++) {
+ final int[] temp_ptr = temp[i];
+ temp_ptr[0]=0;//area
+ temp_ptr[1]=0;//x
+ temp_ptr[2]=0;//y
+ temp_ptr[3]=i_size.w;//l
+ temp_ptr[4]=0;//r
+ temp_ptr[5]=i_size.h;//t
+ temp_ptr[6]=0;//b
+ }
+ //計算!
+
+ for (int i = 0; i < i_work_max; i++) {
+ final int temp_ptr[] = temp[i_lindex[i] - 1];
+ final int[] work2_pt = i_work[i];
+ temp_ptr[0] += work2_pt[0];
+ temp_ptr[1] += work2_pt[1];
+ temp_ptr[2] += work2_pt[2];
+ if (temp_ptr[3] > work2_pt[3]) {
+ temp_ptr[3] = work2_pt[3];
+ }
+ if (temp_ptr[4] < work2_pt[4]) {
+ temp_ptr[4] = work2_pt[4];
+ }
+ if (temp_ptr[5] > work2_pt[5]) {
+ temp_ptr[5] = work2_pt[5];
+ }
+ if (temp_ptr[6] < work2_pt[6]) {
+ temp_ptr[6] = work2_pt[6];
+ }
+ }
+ //ストア
+ for (int i = 0; i < i_number_of_label; i++) {// for(int i = 0; i < *label_num; i++ ) {
+ final NyARLabelingLabel label_pt = labels[i];
+ final int temp_ptr[] = temp[i];
+ label_pt.id=i+1;
+ label_pt.area=temp_ptr[0];
+ label_pt.pos_x= (double)temp_ptr[1]/label_pt.area;
+ label_pt.pos_y= (double)temp_ptr[2]/label_pt.area;
+ label_pt.clip_l= temp_ptr[3];
+ label_pt.clip_r= temp_ptr[4];
+ label_pt.clip_t= temp_ptr[5];
+ label_pt.clip_b= temp_ptr[6];
+ }
+ return;
+ }
+}
+
+/**
+ * NyARLabeling_O2のworkとwork2を可変長にするためのクラス
+ *
+ *
+ */
+final class NyARWorkHolder
+{
+ private final static int ARRAY_APPEND_STEP = 256;
+
+ public final int[] work;
+
+ public final int[][] work2;
+
+ private int allocate_size;
+
+ /**
+ * 最大i_holder_size個の動的割り当てバッファを準備する。
+ *
+ * @param i_holder_size
+ */
+ public NyARWorkHolder(int i_holder_size)
+ {
+ // ポインタだけははじめに確保しておく
+ this.work = new int[i_holder_size];
+ this.work2 = new int[i_holder_size][];
+ this.allocate_size = 0;
+ }
+
+ /**
+ * i_indexで指定した番号までのバッファを準備する。
+ *
+ * @param i_index
+ */
+ public final void reserv(int i_index) throws NyARException
+ {
+ // アロケート済みなら即リターン
+ if (this.allocate_size > i_index) {
+ return;
+ }
+ // 要求されたインデクスは範囲外
+ if (i_index >= this.work.length) {
+ throw new NyARException();
+ }
+ // 追加アロケート範囲を計算
+ int range = i_index + ARRAY_APPEND_STEP;
+ if (range >= this.work.length) {
+ range = this.work.length;
+ }
+ // アロケート
+ for (int i = this.allocate_size; i < range; i++) {
+ this.work2[i] = new int[8];
+ }
+ this.allocate_size = range;
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatVertexCounter.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatVertexCounter.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatVertexCounter.java (revision 199)
@@ -0,0 +1,66 @@
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+public final class NyARFixedFloatVertexCounter
+{
+ public final int[] vertex = new int[6];// 5まで削れる
+
+ public int number_of_vertex;
+
+ private long thresh_16f;
+
+ private int[] x_coord;
+
+ private int[] y_coord;
+
+ public boolean getVertex(int[] i_x_coord, int[] i_y_coord, int st, int ed, long i_thresh)
+ {
+ this.number_of_vertex = 0;
+ this.thresh_16f = i_thresh;
+ this.x_coord = i_x_coord;
+ this.y_coord = i_y_coord;
+ return get_vertex(st, ed);
+ }
+
+ /**
+ * static int get_vertex( int x_coord[], int y_coord[], int st, int ed,double thresh, int vertex[], int *vnum) 関数の代替関数
+ *
+ * @param x_coord
+ * @param y_coord
+ * @param st
+ * @param ed
+ * @param thresh
+ * @return
+ */
+ private boolean get_vertex(int st, int ed)
+ {
+ int v1 = 0;
+ final int[] lx_coord = this.x_coord;
+ final int[] ly_coord = this.y_coord;
+ final int a = ly_coord[ed] - ly_coord[st];
+ final int b = lx_coord[st] - lx_coord[ed];
+ final int c = lx_coord[ed] * ly_coord[st] - ly_coord[ed] * lx_coord[st];
+ long dmax = 0;
+ for (int i = st + 1; i < ed; i++) {
+ final long d = a * lx_coord[i] + b * ly_coord[i] + c;
+ if (d * d > dmax) {
+ dmax = d * d;
+ v1 = i;
+ }
+ }
+ if ((dmax<<16) / (long)(a * a + b * b) > this.thresh_16f) {
+ if (!get_vertex(st, v1)) {
+ return false;
+ }
+ if (number_of_vertex > 5) {
+ return false;
+ }
+ vertex[number_of_vertex] = v1;// vertex[(*vnum)] = v1;
+ number_of_vertex++;// (*vnum)++;
+
+ if (!get_vertex(v1, ed)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARSingleDetectMarker_X2.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARSingleDetectMarker_X2.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARSingleDetectMarker_X2.java (revision 199)
@@ -0,0 +1,231 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.core.match.*;
+import jp.nyatla.nyartoolkit.core.param.NyARParam;
+import jp.nyatla.nyartoolkit.core.pickup.*;
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.transmat.*;
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilter_ARToolkitThreshold;
+
+
+/**
+ * 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。
+ *
+ */
+public class NyARSingleDetectMarker_X2
+{
+ private static final int AR_SQUARE_MAX = 100;
+
+ private boolean _is_continue = false;
+ private NyARMatchPatt_Color_WITHOUT_PCA _match_patt;
+ private INyARSquareDetector _square_detect;
+
+ private final NyARSquareStack _square_list = new NyARSquareStack(AR_SQUARE_MAX);
+
+ private NyARCode _code;
+
+ protected INyARTransMat _transmat;
+
+ private double _marker_width;
+
+ // 検出結果の保存用
+ private int _detected_direction;
+
+ private double _detected_confidence;
+
+ private NyARSquare _detected_square;
+
+ private INyARColorPatt _patt;
+
+ /**
+ * 検出するARCodeとカメラパラメータから、1個のARCodeを検出するNyARSingleDetectMarkerインスタンスを作ります。
+ *
+ * @param i_param
+ * カメラパラメータを指定します。
+ * @param i_code
+ * 検出するARCodeを指定します。
+ * @param i_marker_width
+ * ARコードの物理サイズを、ミリメートルで指定します。
+ * @throws NyARException
+ */
+ public NyARSingleDetectMarker_X2(NyARParam i_param, NyARCode i_code, double i_marker_width) throws NyARException
+ {
+ final NyARIntSize scr_size=i_param.getScreenSize();
+ final NyARFixedFloatObserv2IdealMap dist_map = new NyARFixedFloatObserv2IdealMap(i_param.getDistortionFactor(), scr_size);
+
+ // 解析オブジェクトを作る
+ this._square_detect = new NyARSquareDetector_X2(dist_map,scr_size);
+ this._transmat = new NyARTransMat_X2(i_param);
+ // 比較コードを保存
+ this._code = i_code;
+ this._marker_width = i_marker_width;
+ // 評価パターンのホルダを作る
+ this._patt = new NyARColorPatt_O3(_code.getWidth(), _code.getHeight());
+ // 評価器を作る。
+ this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA();
+ //2値画像バッファを作る
+ this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);
+ return;
+ }
+
+ private NyARBinRaster _bin_raster;
+ private NyARRasterFilter_ARToolkitThreshold _tobin_filter=new NyARRasterFilter_ARToolkitThreshold(100);
+
+
+ /**
+ * i_imageにマーカー検出処理を実行し、結果を記録します。
+ *
+ * @param i_raster
+ * マーカーを検出するイメージを指定します。イメージサイズは、カメラパラメータ
+ * と一致していなければなりません。
+ * @return マーカーが検出できたかを真偽値で返します。
+ * @throws NyARException
+ */
+ public boolean detectMarkerLite(INyARRgbRaster i_raster,int i_threshold) throws NyARException
+ {
+ //サイズチェック
+ if(!this._bin_raster.getSize().isEqualSize(i_raster.getSize())){
+ throw new NyARException();
+ }
+
+ //ラスタを(1/4の画像の)2値イメージに変換する.
+ this._tobin_filter.setThreshold(i_threshold);
+ this._tobin_filter.doFilter(i_raster,this._bin_raster);
+
+
+ this._detected_square = null;
+ NyARSquareStack l_square_list = this._square_list;
+ // スクエアコードを探す
+ this._square_detect.detectMarker(this._bin_raster, l_square_list);
+
+
+ int number_of_square = l_square_list.getLength();
+ // コードは見つかった?
+ if (number_of_square < 1) {
+ return false;
+ }
+
+ // 評価基準になるパターンをイメージから切り出す
+ if (!this._patt.pickFromRaster(i_raster, (NyARSquare)l_square_list.getItem(0))) {
+ // パターンの切り出しに失敗
+ return false;
+ }
+ // パターンを評価器にセット
+ if (!this._match_patt.setPatt(this._patt)) {
+ // 計算に失敗した。
+ throw new NyARException();
+ }
+ // コードと比較する
+ this._match_patt.evaluate(this._code);
+ int square_index = 0;
+ int direction = this._match_patt.getDirection();
+ double confidence = this._match_patt.getConfidence();
+ for (int i = 1; i < number_of_square; i++) {
+ // 次のパターンを取得
+ this._patt.pickFromRaster(i_raster, (NyARSquare)l_square_list.getItem(i));
+ // 評価器にセットする。
+ this._match_patt.setPatt(this._patt);
+ // コードと比較する
+ this._match_patt.evaluate(this._code);
+ double c2 = this._match_patt.getConfidence();
+ if (confidence > c2) {
+ continue;
+ }
+ // もっと一致するマーカーがあったぽい
+ square_index = i;
+ direction = this._match_patt.getDirection();
+ confidence = c2;
+ }
+ // マーカー情報を保存
+ this._detected_square = (NyARSquare)l_square_list.getItem(square_index);
+ this._detected_direction = direction;
+ this._detected_confidence = confidence;
+ return true;
+ }
+
+ /**
+ * 検出したマーカーの変換行列を計算して、o_resultへ値を返します。
+ * 直前に実行したdetectMarkerLiteが成功していないと使えません。
+ *
+ * @param o_result
+ * 変換行列を受け取るオブジェクトを指定します。
+ * @throws NyARException
+ */
+ public void getTransmationMatrix(NyARTransMatResult o_result) throws NyARException
+ {
+ // 一番一致したマーカーの位置とかその辺を計算
+ if (this._is_continue) {
+ this._transmat.transMatContinue(this._detected_square,this._detected_direction,this._marker_width, o_result);
+ } else {
+ this._transmat.transMat(this._detected_square,this._detected_direction,this._marker_width, o_result);
+ }
+ return;
+ }
+
+ /**
+ * 検出したマーカーの一致度を返します。
+ *
+ * @return マーカーの一致度を返します。0~1までの値をとります。 一致度が低い場合には、誤認識の可能性が高くなります。
+ * @throws NyARException
+ */
+ public double getConfidence()
+ {
+ return this._detected_confidence;
+ }
+
+ /**
+ * 検出したマーカーの方位を返します。
+ *
+ * @return 0,1,2,3の何れかを返します。
+ */
+ public int getDirection()
+ {
+ return this._detected_direction;
+ }
+
+ /**
+ * getTransmationMatrixの計算モードを設定します。 初期値はTRUEです。
+ *
+ * @param i_is_continue
+ * TRUEなら、transMatCont互換の計算をします。 FALSEなら、transMat互換の計算をします。
+ */
+ public void setContinueMode(boolean i_is_continue)
+ {
+ this._is_continue = i_is_continue;
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatObserv2IdealMap.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatObserv2IdealMap.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatObserv2IdealMap.java (revision 199)
@@ -0,0 +1,113 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+/**
+ * 歪み成分マップを使用するINyARCameraDistortionFactor
+ * 内部マップをint(1:15:16)フォーマットの固定小数点で保持する。
+ * 固定小数点で値を提供するインタフェイスを持ちます。
+ */
+final public class NyARFixedFloatObserv2IdealMap
+{
+ private double[] _factor=new double[4];
+ private int _stride;
+ private int[] _mapx;
+ private int[] _mapy;
+ public NyARFixedFloatObserv2IdealMap(NyARCameraDistortionFactor i_distfactor,NyARIntSize i_screen_size)
+ {
+ NyARDoublePoint2d opoint=new NyARDoublePoint2d();
+ this._mapx=new int[i_screen_size.w*i_screen_size.h];
+ this._mapy=new int[i_screen_size.w*i_screen_size.h];
+ this._stride=i_screen_size.w;
+ int ptr=i_screen_size.h*i_screen_size.w-1;
+ //歪みマップを構築
+ for(int i=i_screen_size.h-1;i>=0;i--)
+ {
+ for(int i2=i_screen_size.w-1;i2>=0;i2--)
+ {
+ i_distfactor.observ2Ideal(i2,i,opoint);
+ this._mapx[ptr]=(int)(opoint.x*65536);
+ this._mapy[ptr]=(int)(opoint.y*65536);
+ ptr--;
+ }
+ }
+ i_distfactor.getValue(this._factor);
+ return;
+ }
+ /**
+ * 点集合のi_start~i_numまでの間から、最大i_sample_count個の頂点を取得して返します。
+ * i_sample_countは偶数である必要があります。
+ * @param i_x_coord
+ * @param i_y_coord
+ * @param i_start
+ * @param i_num
+ * @param o_x_coord
+ * @param o_y_coord
+ * @param i_sample_count
+ * @return
+ */
+ public int observ2IdealSampling(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num, int[] o_x_coord,int[] o_y_coord,int i_sample_count)
+ {
+ assert(i_sample_count%2==0);
+ int idx;
+ if (i_num < i_sample_count)
+ {
+ for (int i = i_num - 1; i >= 0; i--)
+ {
+ idx = i_x_coord[i_start + i] + i_y_coord[i_start + i] * this._stride;
+ o_x_coord[i] = this._mapx[idx];
+ o_y_coord[i] = this._mapy[idx];
+ }
+ return i_num;
+ }
+ else
+ {
+ //サンプリング個数分の点を、両端から半分づつ取ってくる。
+ int st = i_start;
+ int ed = i_start + i_num - 1;
+ for (int i = i_sample_count - 1; i >= 0; i -= 2)
+ {
+ idx = i_x_coord[st] + i_y_coord[st] * this._stride;
+ o_x_coord[i] = this._mapx[idx];
+ o_y_coord[i] = this._mapy[idx];
+ idx = i_x_coord[ed] + i_y_coord[ed] * this._stride;
+ o_x_coord[i - 1] = this._mapx[idx];
+ o_y_coord[i - 1] = this._mapy[idx];
+ ed--;
+ st++;
+ }
+ return i_sample_count;
+ }
+ }
+}
\ No newline at end of file
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatIdeal2Observ.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatIdeal2Observ.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatIdeal2Observ.java (revision 199)
@@ -0,0 +1,52 @@
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;
+import jp.nyatla.nyartoolkit.core2.types.NyARFixedFloat16Point2d;
+
+public class NyARFixedFloatIdeal2Observ
+{
+ private double[] _factor=new double[4];
+ public NyARFixedFloatIdeal2Observ(NyARCameraDistortionFactor i_distfactor)
+ {
+ i_distfactor.getValue(this._factor);
+ return;
+ }
+ public void ideal2ObservBatch(final NyARDoublePoint2d[] i_in, NyARFixedFloat16Point2d[] o_out, int i_size)
+ {
+ double x, y;
+ final double d0 = this._factor[0];
+ final double d1 = this._factor[1];
+ final double d3 = this._factor[3];
+ final double d2_w = this._factor[2] / 100000000.0;
+ for (int i = 0; i < i_size; i++) {
+ x = (i_in[i].x - d0) * d3;
+ y = (i_in[i].y - d1) * d3;
+ if (x == 0.0 && y == 0.0) {
+ o_out[i].x = (long)(d0*NyMath.FIXEDFLOAT16_1);
+ o_out[i].y = (long)(d1*NyMath.FIXEDFLOAT16_1);
+ } else {
+ final double d = 1.0 - d2_w * (x * x + y * y);
+ o_out[i].x = (long)((x * d + d0)*NyMath.FIXEDFLOAT16_1);
+ o_out[i].y = (long)((y * d + d1)*NyMath.FIXEDFLOAT16_1);
+ }
+ }
+ return;
+ }
+ public void ideal2Observ(final NyARFixedFloat16Point2d i_in, NyARFixedFloat16Point2d o_out)
+ {
+ final double f0=this._factor[0];
+ final double f1=this._factor[1];
+ final double x = (((double)i_in.x/NyMath.FIXEDFLOAT16_1) - f0) * this._factor[3];
+ final double y = (((double)i_in.y/NyMath.FIXEDFLOAT16_1) - f1) * this._factor[3];
+ if (x == 0.0 && y == 0.0) {
+ o_out.x = (long)(f0*NyMath.FIXEDFLOAT16_1);
+ o_out.y = (long)(f1*NyMath.FIXEDFLOAT16_1);
+ } else {
+ final double d = 1.0 - this._factor[2] / 100000000.0 * (x * x + y * y);
+ o_out.x = (long)((x * d + f0)*NyMath.FIXEDFLOAT16_1);
+ o_out.y = (long)((y * d + f1)*NyMath.FIXEDFLOAT16_1);
+ }
+ return;
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/JavaSimpleLite_X2.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/JavaSimpleLite_X2.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/JavaSimpleLite_X2.java (revision 199)
@@ -0,0 +1,252 @@
+/*
+ * PROJECT: NyARToolkit JOGL sample program.
+ * --------------------------------------------------------------------------------
+ * The MIT License
+ * Copyright (c) 2008 nyatla
+ * airmail(at)ebony.plala.or.jp
+ * http://nyatla.jp/nyartoolkit/
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.*;
+
+import javax.media.Buffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLCanvas;
+
+import com.sun.opengl.util.Animator;
+
+import jp.nyatla.nyartoolkit.core.NyARCode;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;
+import jp.nyatla.nyartoolkit.jmf.utils.JmfCameraCapture;
+import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureListener;
+import jp.nyatla.nyartoolkit.jogl.utils.*;
+/**
+ * simpleLiteと同じようなテストプログラム
+ * 出来る限りARToolKitのサンプルと似せて作ってあります。
+ * 最も一致する"Hiro"マーカーを一つ選択して、その上に立方体を表示します。
+ *
+ */
+public class JavaSimpleLite_X2 implements GLEventListener, JmfCaptureListener
+{
+ private final String CARCODE_FILE = "../../Data/patt.hiro";
+
+ private final String PARAM_FILE = "../../Data/camera_para.dat";
+
+ private final static int SCREEN_X = 320;
+
+ private final static int SCREEN_Y = 240;
+
+ private Animator _animator;
+
+ private GLNyARRaster_RGB _cap_image;
+
+ private JmfCameraCapture _capture;
+
+ private GL _gl;
+
+ private NyARGLUtil _glnya;
+
+ //NyARToolkit関係
+ private NyARSingleDetectMarker_X2 _nya;
+
+ private NyARParam _ar_param;
+
+ /**
+ * 立方体を書く
+ *
+ */
+ void drawCube()
+ {
+ // Colour cube data.
+ int polyList = 0;
+ float fSize = 0.5f;//マーカーサイズに対して0.5倍なので、4cmの立方体
+ int f, i;
+ float[][] cube_vertices = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f } };
+ float[][] cube_vertex_colors = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };
+ int cube_num_faces = 6;
+ short[][] cube_faces = new short[][] { { 3, 2, 1, 0 }, { 2, 3, 7, 6 }, { 0, 1, 5, 4 }, { 3, 0, 4, 7 }, { 1, 2, 6, 5 }, { 4, 5, 6, 7 } };
+
+ if (polyList == 0) {
+ polyList = _gl.glGenLists(1);
+ _gl.glNewList(polyList, GL.GL_COMPILE);
+ _gl.glBegin(GL.GL_QUADS);
+ for (f = 0; f < cube_num_faces; f++)
+ for (i = 0; i < 4; i++) {
+ _gl.glColor3f(cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]);
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);
+ }
+ _gl.glEnd();
+ _gl.glColor3f(0.0f, 0.0f, 0.0f);
+ for (f = 0; f < cube_num_faces; f++) {
+ _gl.glBegin(GL.GL_LINE_LOOP);
+ for (i = 0; i < 4; i++)
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);
+ _gl.glEnd();
+ }
+ _gl.glEndList();
+ }
+
+ _gl.glPushMatrix(); // Save world coordinate system.
+ _gl.glTranslatef(0.0f, 0.0f, 0.5f); // Place base of cube on marker surface.
+ _gl.glRotatef(0.0f, 0.0f, 0.0f, 1.0f); // Rotate about z axis.
+ _gl.glDisable(GL.GL_LIGHTING); // Just use colours.
+ _gl.glCallList(polyList); // Draw the cube.
+ _gl.glPopMatrix(); // Restore world coordinate system.
+
+ }
+
+ public JavaSimpleLite_X2()
+ {
+ NyMath.initialize();
+ Frame frame = new Frame("Java simpleLite with NyARToolkit");
+
+ // 3Dを描画するコンポーネント
+ GLCanvas canvas = new GLCanvas();
+ frame.add(canvas);
+ canvas.addGLEventListener(this);
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e)
+ {
+ System.exit(0);
+ }
+ });
+
+ frame.setVisible(true);
+ Insets ins = frame.getInsets();
+ frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);
+ canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);
+ }
+
+ public void init(GLAutoDrawable drawable)
+ {
+ _gl = drawable.getGL();
+ _gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ //NyARToolkitの準備
+ try {
+ //キャプチャの準備
+ _capture = new JmfCameraCapture(SCREEN_X, SCREEN_Y, 15f, JmfCameraCapture.PIXEL_FORMAT_RGB);
+ _capture.setCaptureListener(this);
+ //NyARToolkitの準備
+ _ar_param = new NyARParam();
+ NyARCode ar_code = new NyARCode(16, 16);
+ _ar_param.loadARParamFromFile(PARAM_FILE);
+ _ar_param.changeScreenSize(SCREEN_X, SCREEN_Y);
+ _nya = new NyARSingleDetectMarker_X2(_ar_param, ar_code, 80.0);
+ _nya.setContinueMode(false);//ここをtrueにすると、transMatContinueモード(History計算)になります。
+ ar_code.loadARPattFromFile(CARCODE_FILE);
+ //NyARToolkit用の支援クラス
+ _glnya = new NyARGLUtil(_gl);
+ //GL対応のRGBラスタオブジェクト
+ _cap_image = new GLNyARRaster_RGB(_ar_param);
+ //キャプチャ開始
+ _capture.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ //カメラパラメータの計算
+ _glnya.toCameraFrustumRH(_ar_param,_camera_projection);
+ _animator = new Animator(drawable);
+
+ _animator.start();
+
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
+ {
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ _gl.glViewport(0, 0, width, height);
+
+ //視体積の設定
+ _gl.glMatrixMode(GL.GL_PROJECTION);
+ _gl.glLoadIdentity();
+ //見る位置
+ _gl.glMatrixMode(GL.GL_MODELVIEW);
+ _gl.glLoadIdentity();
+ }
+ private double[] _camera_projection=new double[16];
+ private NyARTransMatResult __display_transmat_result=new NyARTransMatResult();
+ private double[] __display_wk=new double[16];
+ public void display(GLAutoDrawable drawable)
+ {
+ NyARTransMatResult transmat_result=__display_transmat_result;
+ try {
+ if (!_cap_image.hasData()) {
+ return;
+ }
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.
+ //画像チェックしてマーカー探して、背景を書く
+ boolean is_marker_exist;
+ synchronized (_cap_image) {
+ is_marker_exist = _nya.detectMarkerLite(_cap_image, 110);
+ //背景を書く
+ _glnya.drawBackGround(_cap_image, 1.0);
+ }
+ //マーカーがあれば、立方体を描画
+ if (is_marker_exist) {
+ //マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。
+ // Projection transformation.
+ _gl.glMatrixMode(GL.GL_PROJECTION);
+ _gl.glLoadMatrixd(_camera_projection, 0);
+ _gl.glMatrixMode(GL.GL_MODELVIEW);
+ // Viewing transformation.
+ _gl.glLoadIdentity();
+ //変換行列を取得
+ _nya.getTransmationMatrix(transmat_result);
+ //変換行列をOpenGL形式に変換
+ _glnya.toCameraViewRH(transmat_result, __display_wk);
+ _gl.glLoadMatrixd(__display_wk, 0);
+
+ // All other lighting and geometry goes here.
+ drawCube();
+ }
+ Thread.sleep(1);//タスク実行権限を一旦渡す
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+ public void onUpdateBuffer(Buffer i_buffer)
+ {
+ try {
+ synchronized (_cap_image) {
+ _cap_image.setBuffer(i_buffer, true);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)
+ {
+ }
+
+ public static void main(String[] args)
+ {
+ new JavaSimpleLite_X2();
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatRotVector.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatRotVector.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatRotVector.java (revision 199)
@@ -0,0 +1,403 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.NyARMat;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core2.types.matrix.*;
+import jp.nyatla.nyartoolkit.core2.types.*;
+
+public class NyARFixedFloatRotVector
+{
+ //publicメンバ達
+ public long v1;
+
+ public long v2;
+
+ public long v3;
+
+ //privateメンバ達
+ private NyARFixedFloat16Matrix33 _cmat = new NyARFixedFloat16Matrix33();
+
+ private NyARPerspectiveProjectionMatrix _projection_mat_ref;
+
+ private double[][] _inv_cpara_array_ref;
+
+ public NyARFixedFloatRotVector(NyARPerspectiveProjectionMatrix i_cmat) throws NyARException
+ {
+ final NyARMat mat_a = new NyARMat(3, 3);
+ final double[][] a_array = mat_a.getArray();
+
+ a_array[0][0] = i_cmat.m00;
+ a_array[0][1] = i_cmat.m01;
+ a_array[0][2] = i_cmat.m02;
+ a_array[1][0] = i_cmat.m10;
+ a_array[1][1] = i_cmat.m11;
+ a_array[1][2] = i_cmat.m12;
+ a_array[2][0] = i_cmat.m20;
+ a_array[2][1] = i_cmat.m21;
+ a_array[2][2] = i_cmat.m22;
+
+ mat_a.matrixSelfInv();
+ this._projection_mat_ref = i_cmat;
+ //FixedFloat16にコピー
+ this._cmat.m00 = (long)(i_cmat.m00 * NyMath.FIXEDFLOAT24_1);
+ this._cmat.m01 = (long)(i_cmat.m01 * NyMath.FIXEDFLOAT24_1);
+ this._cmat.m02 = (long)(i_cmat.m02 * NyMath.FIXEDFLOAT24_1);
+ this._cmat.m10 = (long)(i_cmat.m10 * NyMath.FIXEDFLOAT24_1);
+ this._cmat.m11 = (long)(i_cmat.m11 * NyMath.FIXEDFLOAT24_1);
+ this._cmat.m12 = (long)(i_cmat.m12 * NyMath.FIXEDFLOAT24_1);
+ this._cmat.m20 = (long)(i_cmat.m20 * NyMath.FIXEDFLOAT24_1);
+ this._cmat.m21 = (long)(i_cmat.m21 * NyMath.FIXEDFLOAT24_1);
+ this._cmat.m22 = (long)(i_cmat.m22 * NyMath.FIXEDFLOAT24_1);
+ this._inv_cpara_array_ref = mat_a.getArray();
+ //GCない言語のときは、ここで配列の所有権委譲してね!
+ }
+
+ /**
+ * 2直線に直交するベクトルを計算する・・・だと思う。
+ * @param i_linear1
+ * @param i_linear2
+ */
+ public void exteriorProductFromLinear(NyARLinear i_linear1, NyARLinear i_linear2)
+ {
+ //1行目
+ NyARPerspectiveProjectionMatrix cmat = this._projection_mat_ref;
+ final double w1 = i_linear1.run * i_linear2.rise - i_linear2.run * i_linear1.rise;
+ final double w2 = i_linear1.rise * i_linear2.intercept - i_linear2.rise * i_linear1.intercept;
+ final double w3 = i_linear1.intercept * i_linear2.run - i_linear2.intercept * i_linear1.run;
+
+ final double m0 = w1 * (cmat.m01 * cmat.m12 - cmat.m02 * cmat.m11) + w2 * cmat.m11 - w3 * cmat.m01;//w1 * (cpara[0 * 4 + 1] * cpara[1 * 4 + 2] - cpara[0 * 4 + 2] * cpara[1 * 4 + 1]) + w2 * cpara[1 * 4 + 1] - w3 * cpara[0 * 4 + 1];
+ final double m1 = -w1 * cmat.m00 * cmat.m12 + w3 * cmat.m00;//-w1 * cpara[0 * 4 + 0] * cpara[1 * 4 + 2] + w3 * cpara[0 * 4 + 0];
+ final double m2 = w1 * cmat.m00 * cmat.m11;//w1 * cpara[0 * 4 + 0] * cpara[1 * 4 + 1];
+ final double w = Math.sqrt(m0 * m0 + m1 * m1 + m2 * m2);
+ this.v1 = (long)(m0 * NyMath.FIXEDFLOAT16_1 / w);
+ this.v2 = (long)(m1 * NyMath.FIXEDFLOAT16_1 / w);
+ this.v3 = (long)(m2 * NyMath.FIXEDFLOAT16_1 / w);
+ return;
+ }
+
+ /**
+ * static int check_dir( double dir[3], double st[2], double ed[2],double cpara[3][4] ) Optimize:STEP[526->468]
+ * ベクトルの開始/終了座標を指定して、ベクトルの方向を調整する。
+ * @param i_start_vertex
+ * @param i_end_vertex
+ * @param cpara
+ */
+ public void checkVectorByVertex(NyARFixedFloat16Point2d i_start_vertex, NyARFixedFloat16Point2d i_end_vertex) throws NyARException
+ {
+ long h;
+ final double[][] inv_cpara = this._inv_cpara_array_ref;
+ final double stx = (double)(i_start_vertex.x / NyMath.FIXEDFLOAT16_1);
+ final double sty = (double)(i_start_vertex.y / NyMath.FIXEDFLOAT16_1);
+
+ //final double[] world = __checkVectorByVertex_world;// [2][3];
+ final long world0 = (long)((inv_cpara[0][0] * stx + inv_cpara[0][1] * sty + inv_cpara[0][2]) * 10.0 * NyMath.FIXEDFLOAT16_1);// mat_a->m[0]*st[0]*10.0+
+ final long world1 = (long)((inv_cpara[1][0] * stx + inv_cpara[1][1] * sty + inv_cpara[1][2]) * 10.0 * NyMath.FIXEDFLOAT16_1);// mat_a->m[3]*st[0]*10.0+
+ final long world2 = (long)((inv_cpara[2][0] * stx + inv_cpara[2][1] * sty + inv_cpara[2][2]) * 10.0 * NyMath.FIXEDFLOAT16_1);// mat_a->m[6]*st[0]*10.0+
+ final long world3 = world0 + (this.v1);
+ final long world4 = world1 + (this.v2);
+ final long world5 = world2 + (this.v3);
+ // </Optimize>
+
+ //final double[] camera = __checkVectorByVertex_camera;// [2][2];
+ //h = cpara[2 * 4 + 0] * world0 + cpara[2 * 4 + 1] * world1 + cpara[2 * 4 + 2] * world2;
+ h = (this._cmat.m20 * world0 + this._cmat.m21 * world1 + this._cmat.m22 * world2) >> 16;
+ if (h == 0)
+ {
+ throw new NyARException();
+ }
+ //final double camera0 = (cpara[0 * 4 + 0] * world0 + cpara[0 * 4 + 1] * world1 + cpara[0 * 4 + 2] * world2) / h;
+ //final double camera1 = (cpara[1 * 4 + 0] * world0 + cpara[1 * 4 + 1] * world1 + cpara[1 * 4 + 2] * world2) / h;
+ final long camera0 = (this._cmat.m00 * world0 + this._cmat.m01 * world1 + this._cmat.m02 * world2) / h;
+ final long camera1 = (this._cmat.m10 * world0 + this._cmat.m11 * world1 + this._cmat.m12 * world2) / h;
+
+ //h = cpara[2 * 4 + 0] * world3 + cpara[2 * 4 + 1] * world4 + cpara[2 * 4 + 2] * world5;
+ h = (this._cmat.m20 * world3 + this._cmat.m21 * world4 + this._cmat.m22 * world5) >> 16;
+ if (h == 0)
+ {
+ throw new NyARException();
+ }
+ //final double camera2 = (cpara[0 * 4 + 0] * world3 + cpara[0 * 4 + 1] * world4 + cpara[0 * 4 + 2] * world5) / h;
+ //final double camera3 = (cpara[1 * 4 + 0] * world3 + cpara[1 * 4 + 1] * world4 + cpara[1 * 4 + 2] * world5) / h;
+ final long camera2 = (this._cmat.m00 * world3 + this._cmat.m01 * world4 + this._cmat.m02 * world5) / h;
+ final long camera3 = (this._cmat.m10 * world3 + this._cmat.m11 * world4 + this._cmat.m12 * world5) / h;
+
+
+ long v = ((i_end_vertex.x - i_start_vertex.x) * (camera2 - camera0) + (i_end_vertex.y - i_start_vertex.y) * (camera3 - camera1)) >> 16;
+
+ if (v < 0)
+ {
+ this.v1 = -this.v1;
+ this.v2 = -this.v2;
+ this.v3 = -this.v3;
+ }
+
+ return;
+ }
+ private static int DIV0_CANCEL=1;
+ /**
+ * int check_rotation( double rot[2][3] )
+ * 2つのベクトル引数の調整をする?
+ * @param i_r
+ * @throws NyARException
+ */
+ public final static void checkRotation(NyARFixedFloatRotVector io_vec1, NyARFixedFloatRotVector io_vec2) throws NyARException
+ {
+ long w;
+ int f;
+
+ long vec10 = io_vec1.v1;
+ long vec11 = io_vec1.v2;
+ long vec12 = io_vec1.v3;
+ long vec20 = io_vec2.v1;
+ long vec21 = io_vec2.v2;
+ long vec22 = io_vec2.v3;
+
+ long vec30 = (vec11 * vec22 - vec12 * vec21)>>16;
+ long vec31 = (vec12 * vec20 - vec10 * vec22)>>16;
+ long vec32 = (vec10 * vec21 - vec11 * vec20)>>16;
+ w = NyMath.sqrtFixdFloat16((vec30 * vec30 + vec31 * vec31 + vec32 * vec32)>>16);
+ if (w == 0) {
+ w=1;//極小値
+ //throw new NyARException();
+ }
+ vec30= (vec30<<16)/w;
+ vec31= (vec31<<16)/w;
+ vec32= (vec32<<16)/w;
+
+ long cb = (vec10 * vec20 + vec11 * vec21 + vec12 * vec22)>>16;
+ if (cb < 0){
+ cb=-cb;//cb *= -1.0;
+ }
+ final long ca = (NyMath.sqrtFixdFloat16(cb + NyMath.FIXEDFLOAT16_1) + NyMath.sqrtFixdFloat16(NyMath.FIXEDFLOAT16_1 - cb)) >>1;
+
+ if (vec31 * vec10 - vec11 * vec30 != 0) {
+ f = 0;
+ } else {
+ if (vec32 * vec10 - vec12 * vec30 != 0) {
+ w = vec11;vec11 = vec12;vec12 = w;
+ w = vec31;vec31 = vec32;vec32 = w;
+ f = 1;
+ } else {
+ w = vec10;vec10 = vec12;vec12 = w;
+ w = vec30;vec30 = vec32;vec32 = w;
+ f = 2;
+ }
+ }
+ if (vec31 * vec10 - vec11 * vec30 == 0) {
+ throw new NyARException();
+ }
+
+ long k1,k2,k3,k4;
+ long a, b, c, d;
+ long p1, q1, r1;
+ long p2, q2, r2;
+ long p3, q3, r3;
+ long p4, q4, r4;
+
+
+ k1 = ((vec11 * vec32 - vec31 * vec12)) / (DIV0_CANCEL+((vec31 * vec10 - vec11 * vec30)>>16));
+ k2 = (vec31 * ca) / (DIV0_CANCEL+((vec31 * vec10 - vec11 * vec30)>>16));
+ k3 = (vec10 * vec32 - vec30 * vec12) / (DIV0_CANCEL+((vec30 * vec11 - vec10 * vec31)>>16));
+ k4 = (vec30 * ca) / (DIV0_CANCEL+((vec30 * vec11 - vec10 * vec31)>>16));
+
+ a = ((k1 * k1 + k3 * k3)>>16) + NyMath.FIXEDFLOAT16_1;
+ b = ((k1 * k2 + k3 * k4)>>16);
+ c = ((k2 * k2 + k4 * k4)>>16) - NyMath.FIXEDFLOAT16_1;
+ d = (b*b - a*c)>>16;
+ if (d < 0) {
+ //誤差で計算エラーが頻発するのでExceptionはしない
+ //throw new NyARException();
+ }
+ r1 = ((-b + NyMath.sqrtFixdFloat16(d))<<16) / a;
+ p1 = ((k1 * r1)>>16) + k2;
+ q1 = ((k3 * r1)>>16) + k4;
+ r2 = ((-b - NyMath.sqrtFixdFloat16(d))<<16) / a;
+ p2 = ((k1 * r2)>>16) + k2;
+ q2 = ((k3 * r2)>>16) + k4;
+ if (f == 1) {
+ w = q1;q1 = r1;r1 = w;
+ w = q2;q2 = r2;r2 = w;
+ w = vec11;vec11 = vec12;vec12 = w;
+ w = vec31;vec31 = vec32;vec32 = w;
+ f = 0;
+ }
+ if (f == 2) {
+ w = p1;p1 = r1;r1 = w;
+ w = p2;p2 = r2;r2 = w;
+ w = vec10;vec10 = vec12;vec12 = w;
+ w = vec30;vec30 = vec32;vec32 = w;
+ f = 0;
+ }
+
+ if (vec31 * vec20 - vec21 * vec30 != 0) {
+ f = 0;
+ } else {
+ if (vec32 * vec20 - vec22 * vec30 != 0) {
+ w = vec21;vec21 = vec22;vec22 = w;
+ w = vec31;vec31 = vec32;vec32 = w;
+ f = 1;
+ } else {
+ w = vec20;vec20 = vec22;vec22 = w;
+ w = vec30;vec30 = vec32;vec32 = w;
+ f = 2;
+ }
+ }
+ if (vec31 * vec20 - vec21 * vec30 == 0) {
+ throw new NyARException();
+ }
+ k1 = (vec21 * vec32 - vec31 * vec22) / (DIV0_CANCEL+((vec31 * vec20 - vec21 * vec30)>>16));
+ k2 = (vec31 * ca) / (DIV0_CANCEL+((vec31 * vec20 - vec21 * vec30)>>16));
+ k3 = (vec20 * vec32 - vec30 * vec22) / ((vec30 * vec21 - vec20 * vec31)>>16);
+ k4 = (vec30 * ca) / (DIV0_CANCEL+((vec30 * vec21 - vec20 * vec31)>>16));
+
+ a = ((k1 * k1 + k3 * k3)>>16) + NyMath.FIXEDFLOAT16_1;
+ b = ((k1 * k2 + k3 * k4)>>16);
+ c = ((k2 * k2 + k4 * k4)>>16) - NyMath.FIXEDFLOAT16_1;
+
+ d = (b*b - a*c)>>16;
+ if (d < 0) {
+ //誤差で計算エラーが頻発するのでExceptionはしない
+// throw new NyARException();
+ }
+ r3 = ((-b + NyMath.sqrtFixdFloat16(d))<<16) / a;
+ p3 = ((k1 * r3)>>16) + k2;
+ q3 = ((k3 * r3)>>16) + k4;
+ r4 = ((-b - NyMath.sqrtFixdFloat16(d))<<16) / a;
+ p4 = ((k1 * r4)>>16) + k2;
+ q4 = ((k3 * r4)>>16) + k4;
+ if (f == 1) {
+ w = q3;q3 = r3;r3 = w;
+ w = q4;q4 = r4;r4 = w;
+ w = vec21;vec21 = vec22;vec22 = w;
+ w = vec31;vec31 = vec32;vec32 = w;
+ f = 0;
+ }
+ if (f == 2) {
+ w = p3;p3 = r3;r3 = w;
+ w = p4;p4 = r4;r4 = w;
+ w = vec20;vec20 = vec22;vec22 = w;
+ w = vec30;vec30 = vec32;vec32 = w;
+ f = 0;
+ }
+
+ long e1 = (p1 * p3 + q1 * q3 + r1 * r3)>>16;
+ if (e1 < 0) {
+ e1 = -e1;
+ }
+ long e2 = (p1 * p4 + q1 * q4 + r1 * r4)>>16;
+ if (e2 < 0) {
+ e2 = -e2;
+ }
+ long e3 = (p2 * p3 + q2 * q3 + r2 * r3)>>16;
+ if (e3 < 0) {
+ e3 = -e3;
+ }
+ long e4 = (p2 * p4 + q2 * q4 + r2 * r4)>>16;
+ if (e4 < 0) {
+ e4 = -e4;
+ }
+ if (e1 < e2) {
+ if (e1 < e3) {
+ if (e1 < e4) {
+ io_vec1.v1 = p1;
+ io_vec1.v2 = q1;
+ io_vec1.v3 = r1;
+ io_vec2.v1 = p3;
+ io_vec2.v2 = q3;
+ io_vec2.v3 = r3;
+ } else {
+ io_vec1.v1 = p2;
+ io_vec1.v2 = q2;
+ io_vec1.v3 = r2;
+ io_vec2.v1 = p4;
+ io_vec2.v2 = q4;
+ io_vec2.v3 = r4;
+ }
+ } else {
+ if (e3 < e4) {
+ io_vec1.v1 = p2;
+ io_vec1.v2 = q2;
+ io_vec1.v3 = r2;
+ io_vec2.v1 = p3;
+ io_vec2.v2 = q3;
+ io_vec2.v3 = r3;
+ } else {
+ io_vec1.v1 = p2;
+ io_vec1.v2 = q2;
+ io_vec1.v3 = r2;
+ io_vec2.v1 = p4;
+ io_vec2.v2 = q4;
+ io_vec2.v3 = r4;
+ }
+ }
+ } else {
+ if (e2 < e3) {
+ if (e2 < e4) {
+ io_vec1.v1 = p1;
+ io_vec1.v2 = q1;
+ io_vec1.v3 = r1;
+ io_vec2.v1 = p4;
+ io_vec2.v2 = q4;
+ io_vec2.v3 = r4;
+ } else {
+ io_vec1.v1 = p2;
+ io_vec1.v2 = q2;
+ io_vec1.v3 = r2;
+ io_vec2.v1 = p4;
+ io_vec2.v2 = q4;
+ io_vec2.v3 = r4;
+ }
+ } else {
+ if (e3 < e4) {
+ io_vec1.v1 = p2;
+ io_vec1.v2 = q2;
+ io_vec1.v3 = r2;
+ io_vec2.v1 = p3;
+ io_vec2.v2 = q3;
+ io_vec2.v3 = r3;
+ } else {
+ io_vec1.v1 = p2;
+ io_vec1.v2 = q2;
+ io_vec1.v3 = r2;
+ io_vec2.v1 = p4;
+ io_vec2.v2 = q4;
+ io_vec2.v3 = r4;
+ }
+ }
+ }
+ return;
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloat16Mat.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloat16Mat.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloat16Mat.java (revision 199)
@@ -0,0 +1,123 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import jp.nyatla.nyartoolkit.NyARException;
+
+
+
+/**
+ * ARMat構造体に対応するクラス typedef struct { double *m; int row; int clm; }ARMat;
+ *
+ */
+public class NyARFixedFloat16Mat
+{
+ /**
+ * 配列サイズと行列サイズは必ずしも一致しないことに注意 返された配列のサイズを行列の大きさとして使わないこと!
+ *
+ */
+ protected long[][] m;
+ private int clm, row;
+
+ /**
+ * デフォルトコンストラクタは機能しません。
+ *
+ * @throws NyARException
+ */
+ protected NyARFixedFloat16Mat() throws NyARException
+ {
+ throw new NyARException();
+ }
+
+ public NyARFixedFloat16Mat(int i_row, int i_clm)
+ {
+ this.m = new long[i_row][i_clm];
+ clm = i_clm;
+ row = i_row;
+ return;
+ }
+ public int getClm()
+ {
+ return clm;
+ }
+ public int getRow()
+ {
+ return row;
+ }
+ /**
+ * 行列をゼロクリアする。
+ */
+ public void zeroClear()
+ {
+ int i, i2;
+ // For順変更OK
+ for (i = row - 1; i >= 0; i--) {
+ for (i2 = clm - 1; i2 >= 0; i2--) {
+ m[i][i2] = 0;
+ }
+ }
+ }
+ public long[][] getArray()
+ {
+ return this.m;
+ }
+ // public void getRowVec(int i_row,NyARVec o_vec)
+ // {
+ // o_vec.set(this.m[i_row],this.clm);
+ // }
+ /**
+ * aとbの積を自分自身に格納する。arMatrixMul()の代替品
+ *
+ * @param a
+ * @param b
+ * @throws NyARException
+ */
+ public void matrixMul(NyARFixedFloat16Mat a, NyARFixedFloat16Mat b) throws NyARException
+ {
+ if (a.clm != b.row || this.row != a.row || this.clm != b.clm) {
+ throw new NyARException();
+ }
+ long w;
+ int r, c, i;
+ long[][] am = a.m, bm = b.m, dm = this.m;
+ // For順変更禁止
+ for (r = 0; r < this.row; r++) {
+ for (c = 0; c < this.clm; c++) {
+ w = 0L;// dest.setARELEM0(r, c,0.0);
+ for (i = 0; i < a.clm; i++) {
+ w += (am[r][i] * bm[i][c])>>16;// ARELEM0(dest, r, c) +=ARELEM0(a, r, i) * ARELEM0(b,i, c);
+ }
+ dm[r][c] = w;
+ }
+ }
+ }
+}
\ No newline at end of file
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatRotMatrix.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatRotMatrix.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatRotMatrix.java (revision 199)
@@ -0,0 +1,296 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core2.types.*;
+import jp.nyatla.nyartoolkit.core2.types.matrix.NyARFixedFloat24Matrix33;
+
+
+
+/**
+ * 回転行列計算用の、3x3行列
+ *
+ */
+public class NyARFixedFloatRotMatrix extends NyARFixedFloat24Matrix33
+{
+ private static int DIV0CANCEL=1;
+ /**
+ * インスタンスを準備します。
+ *
+ * @param i_param
+ */
+ public NyARFixedFloatRotMatrix(NyARPerspectiveProjectionMatrix i_matrix) throws NyARException
+ {
+ this.__initRot_vec1 = new NyARFixedFloatRotVector(i_matrix);
+ this.__initRot_vec2 = new NyARFixedFloatRotVector(i_matrix);
+ return;
+ }
+
+ final private NyARFixedFloatRotVector __initRot_vec1;
+
+ final private NyARFixedFloatRotVector __initRot_vec2;
+
+ public final void initRotByPrevResult(NyARTransMatResult i_prev_result)
+ {
+ this.m00 =(long)(i_prev_result.m00*0x1000000);
+ this.m01 =(long)(i_prev_result.m01*0x1000000);
+ this.m02 =(long)(i_prev_result.m02*0x1000000);
+
+ this.m10 =(long)(i_prev_result.m10*0x1000000);
+ this.m11 =(long)(i_prev_result.m11*0x1000000);
+ this.m12 =(long)(i_prev_result.m12*0x1000000);
+
+ this.m20 =(long)(i_prev_result.m20*0x1000000);
+ this.m21 =(long)(i_prev_result.m21*0x1000000);
+ this.m22 =(long)(i_prev_result.m22*0x1000000);
+ return;
+ }
+
+ public final void initRotBySquare(final NyARLinear[] i_linear, final NyARFixedFloat16Point2d[] i_sqvertex) throws NyARException
+ {
+ final NyARFixedFloatRotVector vec1 = this.__initRot_vec1;
+ final NyARFixedFloatRotVector vec2 = this.__initRot_vec2;
+
+ // 向かい合った辺から、2本のベクトルを計算
+
+ // 軸1
+ vec1.exteriorProductFromLinear(i_linear[0], i_linear[2]);
+ vec1.checkVectorByVertex(i_sqvertex[0], i_sqvertex[1]);
+
+ // 軸2
+ vec2.exteriorProductFromLinear(i_linear[1], i_linear[3]);
+ vec2.checkVectorByVertex(i_sqvertex[3], i_sqvertex[0]);
+
+ // 回転の最適化?
+ NyARFixedFloatRotVector.checkRotation(vec1, vec2);
+
+
+ this.m00 = vec1.v1<<8;
+ this.m10 = vec1.v2<<8;
+ this.m20 = vec1.v3<<8;
+ this.m01 = vec2.v1<<8;
+ this.m11 = vec2.v2<<8;
+ this.m21 = vec2.v3<<8;
+
+
+
+ // 最後の軸を計算
+ final long w02 = (vec1.v2 * vec2.v3 - vec1.v3 * vec2.v2)>>16;//S16
+ final long w12 = (vec1.v3 * vec2.v1 - vec1.v1 * vec2.v3)>>16;//S16
+ final long w22 = (vec1.v1 * vec2.v2 - vec1.v2 * vec2.v1)>>16;//S16
+ final long w = NyMath.sqrtFixdFloat((w02 * w02 + w12 * w12 + w22 * w22)>>16,16);//S16
+ this.m02 = (w02<<24) / w;
+ this.m12 = (w12<<24) / w;
+ this.m22 = (w22<<24) / w;
+ return;
+ }
+
+ /**
+ * int arGetAngle( double rot[3][3], double *wa, double *wb, double *wc ) Optimize:2008.04.20:STEP[481→433] 3x3変換行列から、回転角を復元して返します。
+ *
+ * @param o_angle
+ * @return
+ */
+ public final void getAngle(final NyARFixedFloat16Point3d o_angle)
+ {
+ int a, b, c;
+ long sina, cosa, sinb, cosb, sinc, cosc;
+
+ if (this.m22 > NyMath.FIXEDFLOAT24_1) {// <Optimize/>if( rot[2][2] > 1.0 ) {
+ this.m22 = NyMath.FIXEDFLOAT24_1;// <Optimize/>rot[2][2] = 1.0;
+ } else if (this.m22 < -NyMath.FIXEDFLOAT24_1) {// <Optimize/>}else if( rot[2][2] < -1.0 ) {
+ this.m22 = -NyMath.FIXEDFLOAT24_1;// <Optimize/>rot[2][2] = -1.0;
+ }
+ cosb = this.m22;// <Optimize/>cosb = rot[2][2];
+ b=NyMath.acosFixedFloat16((int)cosb);
+ sinb = (long)NyMath.sinFixedFloat24(b);
+ final long rot02 = this.m02;
+ final long rot12 = this.m12;
+ if (sinb!=0) {
+ cosa = (rot02<<24) / sinb;// <Optimize/>cosa = rot[0][2] / sinb;
+ sina = (rot12<<24) / sinb;// <Optimize/>sina = rot[1][2] / sinb;
+ if (cosa > NyMath.FIXEDFLOAT24_1) {
+ /* printf("cos(alph) = %f\n", cosa); */
+ cosa = NyMath.FIXEDFLOAT24_1;
+ sina = 0;
+ }
+ if (cosa < -NyMath.FIXEDFLOAT24_1) {
+ /* printf("cos(alph) = %f\n", cosa); */
+ cosa = -NyMath.FIXEDFLOAT24_1;
+ sina = 0;
+ }
+ if (sina > NyMath.FIXEDFLOAT24_1) {
+ /* printf("sin(alph) = %f\n", sina); */
+ sina = NyMath.FIXEDFLOAT24_1;
+ cosa = 0;
+ }
+ if (sina < -NyMath.FIXEDFLOAT24_1) {
+ /* printf("sin(alph) = %f\n", sina); */
+ sina = -NyMath.FIXEDFLOAT24_1;
+ cosa = 0;
+ }
+ a = (int)NyMath.acosFixedFloat16((int)cosa);
+ if (sina < 0) {
+ a = -a;
+ }
+ // <Optimize>
+ // sinc = (rot[2][1]*rot[0][2]-rot[2][0]*rot[1][2])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);
+ // cosc = -(rot[0][2]*rot[2][0]+rot[1][2]*rot[2][1])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);
+ final long tmp = DIV0CANCEL+((rot02 * rot02 + rot12 * rot12)>>24);
+ sinc = (this.m21 * rot02 - this.m20 * rot12) / tmp;
+ cosc = -(rot02 * this.m20 + rot12 * this.m21) / tmp;
+ // </Optimize>
+
+ if (cosc > NyMath.FIXEDFLOAT24_1){
+ /* printf("cos(r) = %f\n", cosc); */
+ cosc = NyMath.FIXEDFLOAT24_1;
+ sinc = 0;
+ }
+ if (cosc < -NyMath.FIXEDFLOAT24_1) {
+ /* printf("cos(r) = %f\n", cosc); */
+ cosc = -NyMath.FIXEDFLOAT24_1;
+ sinc = 0;
+ }
+ if (sinc > NyMath.FIXEDFLOAT24_1) {
+ /* printf("sin(r) = %f\n", sinc); */
+ sinc = NyMath.FIXEDFLOAT24_1;
+ cosc = 0;
+ }
+ if (sinc < -NyMath.FIXEDFLOAT24_1) {
+ /* printf("sin(r) = %f\n", sinc); */
+ sinc = -NyMath.FIXEDFLOAT24_1;
+ cosc = 0;
+ }
+ c = (int)NyMath.acosFixedFloat16((int)cosc);
+ if (sinc < 0) {
+ c = -c;
+ }
+ } else {
+ a = b = 0;
+ cosa = cosb = NyMath.FIXEDFLOAT24_1;
+ sina = sinb = 0;
+ cosc = this.m00;// cosc = rot[0];// <Optimize/>cosc = rot[0][0];
+ sinc = this.m01;// sinc = rot[1];// <Optimize/>sinc = rot[1][0];
+ if (cosc > NyMath.FIXEDFLOAT24_1) {
+ /* printf("cos(r) = %f\n", cosc); */
+ cosc = NyMath.FIXEDFLOAT24_1;
+ sinc = 0;
+ }
+ if (cosc < -NyMath.FIXEDFLOAT24_1) {
+ /* printf("cos(r) = %f\n", cosc); */
+ cosc = -NyMath.FIXEDFLOAT24_1;
+ sinc = 0;
+ }
+ if (sinc > NyMath.FIXEDFLOAT24_1) {
+ /* printf("sin(r) = %f\n", sinc); */
+ sinc = NyMath.FIXEDFLOAT24_1;
+ cosc = 0;
+ }
+ if (sinc < -NyMath.FIXEDFLOAT24_1) {
+ /* printf("sin(r) = %f\n", sinc); */
+ sinc = -NyMath.FIXEDFLOAT24_1;
+ cosc = 0;
+ }
+ c = (int)NyMath.acosFixedFloat16((int)cosc);
+ if (sinc < 0) {
+ c = -c;
+ }
+ }
+ o_angle.x = (long)a;// wa.value=a;//*wa = a;
+ o_angle.y = (long)b;// wb.value=b;//*wb = b;
+ o_angle.z = (long)c;// wc.value=c;//*wc = c;
+ return;
+ }
+ public final void setAngle(int i_x, int i_y, int i_z)
+ {
+ /*
+ * |cos(a) -sin(a) 0| |cos(b) 0 sin(b)| |cos(a-c) sin(a-c) 0| rot = |sin(a) cos(a) 0| |0 1 0 | |-sin(a-c) cos(a-c) 0| |0 0 1| |-sin(b) 0 cos(b)| |0 0 1|
+ */
+
+ long Sa, Sb, Ca, Cb, Sac, Cac, CaCb, SaCb;
+ Sa = NyMath.sinFixedFloat24(i_x);
+ Ca = NyMath.cosFixedFloat24(i_x);
+ Sb = NyMath.sinFixedFloat24(i_y);
+ Cb = NyMath.cosFixedFloat24(i_y);
+ Sac = NyMath.sinFixedFloat24(i_x - i_z);
+ Cac = NyMath.cosFixedFloat24(i_x - i_z);
+ CaCb =(Ca * Cb)>>24;
+ SaCb =(Sa * Cb)>>24;
+
+ this.m00 =(CaCb * Cac + Sa * Sac)>>24;
+ this.m01 =(CaCb * Sac - Sa * Cac)>>24;
+ this.m02 =(Ca * Sb)>>24;
+ this.m10 =(SaCb * Cac - Ca * Sac)>>24;
+ this.m11 =(SaCb * Sac + Ca * Cac)>>24;
+ this.m12 =(Sa * Sb)>>24;
+ this.m20 =(-Sb * Cac)>>24;
+ this.m21 =(-Sb * Sac)>>24;
+ this.m22 =Cb;
+ return;
+ }
+ /**
+ * i_in_pointを変換行列で座標変換する。
+ *
+ * @param i_in_point
+ * @param i_out_point
+ */
+ public final void getPoint3d(final NyARFixedFloat16Point3d i_in_point, final NyARFixedFloat16Point3d i_out_point)
+ {
+ i_out_point.x = (this.m00 * i_in_point.x + this.m01 * i_in_point.y + this.m02 * i_in_point.z)>>24;
+ i_out_point.y = (this.m10 * i_in_point.x + this.m11 * i_in_point.y + this.m12 * i_in_point.z)>>24;
+ i_out_point.z = (this.m20 * i_in_point.x + this.m21 * i_in_point.y + this.m22 * i_in_point.z)>>24;
+ return;
+ }
+
+ /**
+ * 複数の頂点を一括して変換する
+ *
+ * @param i_in_point
+ * @param i_out_point
+ * @param i_number_of_vertex
+ */
+ public final void getPoint3dBatch(final NyARFixedFloat16Point3d[] i_in_point, NyARFixedFloat16Point3d[] i_out_point, int i_number_of_vertex)
+ {
+ for (int i = i_number_of_vertex - 1; i >= 0; i--) {
+ final NyARFixedFloat16Point3d out_ptr = i_out_point[i];
+ final NyARFixedFloat16Point3d in_ptr = i_in_point[i];
+ out_ptr.x =(this.m00 * in_ptr.x + this.m01 * in_ptr.y + this.m02 * in_ptr.z)>>24;
+ out_ptr.y =(this.m10 * in_ptr.x + this.m11 * in_ptr.y + this.m12 * in_ptr.z)>>24;
+ out_ptr.z =(this.m20 * in_ptr.x + this.m21 * in_ptr.y + this.m22 * in_ptr.z)>>24;
+ }
+ return;
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatPca2d.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatPca2d.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatPca2d.java (revision 199)
@@ -0,0 +1,273 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.types.matrix.*;
+import jp.nyatla.nyartoolkit.core.pca2d.*;
+import jp.nyatla.nyartoolkit.core2.types.NyARI64Point2d;
+import jp.nyatla.nyartoolkit.core2.types.matrix.NyARI64Matrix22;
+/**
+ * 64bit(小数部16bit)の固定小数点を利用したPCA関数
+ *
+ */
+public class NyARFixedFloatPca2d implements INyARPca2d
+{
+// private static final double PCA_EPS = 1e-6; // #define EPS 1e-6
+
+ private static final int PCA_MAX_ITER = 100; // #define MAX_ITER 100
+ /**
+ * static int QRM( ARMat *a, ARVec *dv )の代替関数
+ *
+ * @param a
+ * @param dv
+ * @throws NyARException
+ */
+ private static void PCA_QRM(NyARI64Matrix22 o_matrix, NyARI64Point2d dv) throws NyARException
+ {
+ long abs_x;
+ long w, t, s, x, y, c;
+ long ev1;
+ long dv_x,dv_y;
+ long mat00,mat01,mat10,mat11;
+ // <this.vecTridiagonalize2d(i_mat, dv, ev);>
+ dv_x =o_matrix.m00;// this.m[dim - 2][dim - 2];// d.v[dim-2]=a.m[dim-2][dim-2];//d->v[dim-2]=a->m[(dim-2)*dim+(dim-2)];
+ ev1 =o_matrix.m01;// this.m[dim - 2][dim - 1];// e.v[dim-2+i_e_start]=a.m[dim-2][dim-1];//e->v[dim-2] = a->m[(dim-2)*dim+(dim-1)];
+ dv_y =o_matrix.m11;// this.m[dim - 1][dim - 1];// d.v[dim-1]=a_array[dim-1][dim-1];//d->v[dim-1] =a->m[(dim-1)*dim+(dim-1)];
+ // 単位行列にする。
+ mat00 = mat11 = (1<<16);
+ mat01 = mat10 = 0;
+ // </this.vecTridiagonalize2d(i_mat, dv, ev);>
+
+ // int j = 1;
+ // // while(j>0 && fabs(ev->v[j])>EPS*(fabs(dv->v[j-1])+fabs(dv->v[j])))
+ // while (j > 0 && Math.abs(ev1) > PCA_EPS * (Math.abs(dv.x) + Math.abs(dv.y))) {
+ // j--;
+ // }
+ // if (j == 0) {
+ int iter = 0;
+ do {
+ iter++;
+ if (iter > PCA_MAX_ITER) {
+ break;
+ }
+ w = (dv_x - dv_y) / 2L;//S16
+ t = (ev1 * ev1)>>16;// t = ev->v[h] * ev->v[h];
+ s = NyMath.sqrtFixdFloat16(((w * w)>>16) + t);
+ if (w < 0) {
+ s = -s;
+ }
+ x = dv_x - dv_y + (t<<16) / (w + s);// x = dv->v[j] -dv->v[h] +t/(w+s);
+ y = ev1;// y = ev->v[j+1];
+
+ abs_x=(x>0?x:-x);
+ if (abs_x >= (y>0?y:-y)) { //if (Math.abs(x) >= Math.abs(y)) {
+ if ((abs_x>>16) > 0) {
+ t = -(y<<16) / x;
+ c = (1L<<32) / NyMath.sqrtFixdFloat16(((t * t)>>16) + (1L<<16));
+ s = (t * c)>>16;
+ } else {
+ c = (1L<<16);
+ s = 0;
+ }
+ } else {
+ t = -(x<<16) / y;
+ s = (1L<<32) / NyMath.sqrtFixdFloat16(((t * t)>>16) + (1L<<16));
+ c = (t * s)>>16;
+ }
+ w = dv_x - dv_y;// w = dv->v[k] -dv->v[k+1];
+ t = (((w * s + 2L * c * ev1)>>16) * s)>>16;// t = (w * s +2 * c *ev->v[k+1]) *s;
+ dv_x -= t;// dv->v[k] -= t;
+ dv_y += t;// dv->v[k+1] += t;
+ ev1 += (s * ((c * w - 2L * s * ev1)>>16)>>16);// ev->v[k+1]+= s * (c* w- 2* s *ev->v[k+1]);
+
+ x = mat00;// x = a->m[k*dim+i];
+ y = mat10;// y = a->m[(k+1)*dim+i];
+ mat00 = (c * x - s * y)>>16;// a->m[k*dim+i] = c * x - s* y;
+ mat10 = (s * x + c * y)>>16;// a->m[(k+1)*dim+i] = s* x + c * y;
+
+ x = mat01;// x = a->m[k*dim+i];
+ y = mat11;// y = a->m[(k+1)*dim+i];
+ mat01 = (c * x - s * y)>>16;// a->m[k*dim+i] = c * x - s* y;
+ mat11 = (s * x + c * y)>>16;// a->m[(k+1)*dim+i] = s* x + c * y;
+ } while (((ev1>0?ev1:-ev1)>>16) > ((((dv_x>0?dv_x:-dv_x) + (dv_y>0?dv_y:-dv_y))>>16)/1000000L));
+ // }
+
+ t = dv_x;// t = dv->v[h];
+ if (dv_y > t) {// if( dv->v[i] > t ) {
+ t = dv_y;// t = dv->v[h];
+ dv_y = dv_x;// dv->v[h] = dv->v[k];
+ dv_x = t;// dv->v[k] = t;
+ // 行の入れ替え
+ o_matrix.m00 = mat10;
+ o_matrix.m01 = mat11;
+ o_matrix.m10 = mat00;
+ o_matrix.m11 = mat01;
+
+ } else {
+ // 行の入れ替えはなし
+ o_matrix.m00 = mat00;
+ o_matrix.m01 = mat01;
+ o_matrix.m10 = mat10;
+ o_matrix.m11 = mat11;
+ }
+ dv.x=dv_x;
+ dv.y=dv_y;
+ return;
+ }
+
+ /**
+ * static int PCA( ARMat *input, ARMat *output, ARVec *ev )
+ *
+ * @param output
+ * @param o_ev
+ * @throws NyARException
+ */
+ /**
+ * static int PCA( ARMat *input, ARMat *output, ARVec *ev )
+ *
+ * @param output
+ * @param o_ev
+ * @throws NyARException
+ */
+ private void PCA_PCA(int[] i_x,int[] i_y,int i_number_of_data,NyARI64Matrix22 o_matrix, NyARI64Point2d o_ev,NyARI64Point2d o_mean) throws NyARException
+ {
+ // double[] mean_array=mean.getArray();
+ // mean.zeroClear();
+
+ //PCA_EXの処理
+ long sx = 0;
+ long sy = 0;
+ for (int i = 0; i < i_number_of_data; i++) {
+ sx += i_x[i];//S16
+ sy += i_y[i];//S16
+ }
+ sx = sx / i_number_of_data;//S16
+ sy = sy / i_number_of_data;//S16
+
+ //PCA_CENTERとPCA_xt_by_xを一緒に処理
+ final long srow = NyMath.sqrtFixdFloat16((long)i_number_of_data<<16);//S16
+ long w00, w11, w10;
+ w00 = w11 = w10 = 0L;// *out = 0.0;
+ for (int i = 0; i < i_number_of_data; i++) {
+ final long x = ((i_x[i] - sx)<<16) / srow;//S6
+ final long y = ((i_y[i] - sy)<<16) / srow;//S6
+ w00 += (x * x)>>16;//S16
+ w10 += (x * y)>>16;//S16
+ w11 += (y * y)>>16;//S16
+ }
+ o_matrix.m00=w00;
+ o_matrix.m01=o_matrix.m10=w10;
+ o_matrix.m11=w11;
+
+ //PCA_PCAの処理
+ PCA_QRM(o_matrix, o_ev);
+ // m2 = o_output.m;// m2 = output->m;
+ if (o_ev.x < 0) {// if( ev->v[i] < VZERO ){
+ o_ev.x = 0;// ev->v[i] = 0.0;
+ o_matrix.m00 = 0;// *(m2++) = 0.0;
+ o_matrix.m01 = 0;// *(m2++) = 0.0;
+ }
+
+ if (o_ev.y < 0) {// if( ev->v[i] < VZERO ){
+ o_ev.y = 0;// ev->v[i] = 0.0;
+ o_matrix.m10 = 0;// *(m2++) = 0.0;
+ o_matrix.m11 = 0;// *(m2++) = 0.0;
+ }
+ o_mean.x=sx;
+ o_mean.y=sy;
+ // }
+ return;
+ }
+ private int[] __pca_tmpx=null;
+ private int[] __pca_tmpy=null;
+ private NyARI64Matrix22 __pca_evec=null;
+ private NyARI64Point2d __pca_ev=null;
+ private NyARI64Point2d __pca_mean=null;
+ public void pca(double[] i_x,double[] i_y,int i_number_of_point,NyARDoubleMatrix22 o_evec, NyARDoublePoint2d o_ev,NyARDoublePoint2d o_mean) throws NyARException
+ {
+ //変換用のワーク変数作成
+ if(__pca_tmpx==null)
+ {
+ this.__pca_tmpx=new int[i_number_of_point];
+ this.__pca_tmpy=new int[i_number_of_point];
+ this.__pca_evec=new NyARI64Matrix22 ();
+ this.__pca_ev=new NyARI64Point2d ();
+ this.__pca_mean=new NyARI64Point2d ();
+ }else if(i_number_of_point>this.__pca_tmpx.length)
+ {
+ this.__pca_tmpx=new int[i_number_of_point];
+ this.__pca_tmpy=new int[i_number_of_point];
+ }
+ //値のセット
+ final int[] x_ptr=this.__pca_tmpx;
+ final int[] y_ptr=this.__pca_tmpy;
+ for(int i=0;i<i_number_of_point;i++)
+ {
+ x_ptr[i]=(int)(i_x[i]*65536L);
+ y_ptr[i]=(int)(i_y[i]*65536L);
+ }
+ //計算
+ pcaF16(x_ptr,y_ptr,i_number_of_point,this.__pca_evec,this.__pca_ev,this.__pca_mean);
+ //結果値を変換
+ o_evec.m00=(double)this.__pca_evec.m00/65536.0;
+ o_evec.m01=(double)this.__pca_evec.m01/65536.0;
+ o_evec.m10=(double)this.__pca_evec.m10/65536.0;
+ o_evec.m11=(double)this.__pca_evec.m11/65536.0;
+ o_ev.x=this.__pca_ev.x/65536.0;
+ o_ev.y=this.__pca_ev.y/65536.0;
+ o_mean.x=this.__pca_mean.x/65536.0;
+ o_mean.y=this.__pca_mean.y/65536.0;
+ return;
+ }
+ /**
+ * 値は全て小数点部16bitの固定小数点です。
+ * @param i_x
+ * @param i_y
+ * @param i_number_of_point
+ * @param o_evec
+ * @param o_ev
+ * @param o_mean
+ * @throws NyARException
+ */
+ public void pcaF16(int[] i_x,int[] i_y,int i_number_of_point,NyARI64Matrix22 o_evec, NyARI64Point2d o_ev,NyARI64Point2d o_mean) throws NyARException
+ {
+ //計算
+ PCA_PCA(i_x,i_y,i_number_of_point,o_evec,o_ev,o_mean);
+ final long sum = o_ev.x + o_ev.y;
+ // For順変更禁止
+ o_ev.x = (o_ev.x<<16)/sum;// ev->v[i] /= sum;
+ o_ev.y = (o_ev.y<<16)/sum;// ev->v[i] /= sum;
+ return;
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatFitVecCalculator.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatFitVecCalculator.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatFitVecCalculator.java (revision 199)
@@ -0,0 +1,196 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core2.types.NyARFixedFloat16Point2d;
+import jp.nyatla.nyartoolkit.core2.types.NyARFixedFloat16Point3d;
+import jp.nyatla.nyartoolkit.core.*;
+
+class NyARCustomMatrix extends NyARMat
+{
+ public NyARCustomMatrix(int i_row, int i_clm)
+ {
+ super(i_row,i_clm);
+ return;
+ }
+ public void copyFrom(NyARFixedFloat16Mat i_mat) throws NyARException
+ {
+ long[][] ptr;
+ int r,c;
+ // For順変更禁止
+ for (r = 0; r < this.row; r++){
+ ptr=i_mat.getArray();
+ for (c = 0; c < this.clm; c++){
+ this.m[c][r]=(double)ptr[c][r]/0x10000;
+ }
+ }
+ return;
+ }
+}
+/**
+ * 平行移動量を計算するクラス
+ *
+ * NyARPerspectiveProjectionMatrixに直接アクセスしてる場所があるけど、
+ * この辺の計算はNyARPerspectiveProjectionMatrixクラスの関数にして押し込む予定。
+ *
+ */
+public class NyARFixedFloatFitVecCalculator
+{
+ private final NyARFixedFloat16Mat _mat_b = new NyARFixedFloat16Mat(3,8);//3,NUMBER_OF_VERTEX*2
+ private final NyARFixedFloat16Mat _mat_a = new NyARFixedFloat16Mat(8,3);/*NUMBER_OF_VERTEX,3*/
+ private final NyARFixedFloat16Mat _mat_d = new NyARFixedFloat16Mat(3,3);
+ private final NyARCustomMatrix _mat_d2=new NyARCustomMatrix(3,3);
+ private final NyARPerspectiveProjectionMatrix _projection_mat;
+ private final NyARFixedFloatIdeal2Observ _distortionfactor;
+
+
+// private NyARDoublePoint2d[] _vertex_2d_ref;
+ public NyARFixedFloatFitVecCalculator(final NyARPerspectiveProjectionMatrix i_projection_mat_ref,final NyARCameraDistortionFactor i_distortion_ref)
+ {
+ // 変換マトリクスdとbの準備(arGetTransMatSubの一部)
+ final long[][] a_array = this._mat_a.getArray();
+ final long[][] b_array = this._mat_b.getArray();
+
+ //変換用行列のcpara固定値の部分を先に初期化してしまう。
+ for (int i = 0; i < 4; i++) {
+ final int x2 = i * 2;
+ a_array[x2][0] = b_array[0][x2] =(long)(i_projection_mat_ref.m00*NyMath.FIXEDFLOAT16_1);// mat_a->m[j*6+0]=mat_b->m[num*0+j*2] =cpara[0][0];
+ a_array[x2][1] = b_array[1][x2] =(long)(i_projection_mat_ref.m01*NyMath.FIXEDFLOAT16_1);// mat_a->m[j*6+1]=mat_b->m[num*2+j*2]=cpara[0][1];
+ a_array[x2 + 1][0] = b_array[0][x2 + 1] =0;// mat_a->m[j*6+3] =mat_b->m[num*0+j*2+1]= 0.0;
+ a_array[x2 + 1][1] = b_array[1][x2 + 1] =(long)(i_projection_mat_ref.m11*NyMath.FIXEDFLOAT16_1);// mat_a->m[j*6+4] =mat_b->m[num*2+j*2+1]= cpara[1][1];
+ }
+ this._projection_mat=i_projection_mat_ref;
+ this._distortionfactor=new NyARFixedFloatIdeal2Observ(i_distortion_ref);
+ return;
+ }
+ private final NyARFixedFloat16Point2d[] _fitsquare_vertex=NyARFixedFloat16Point2d.createArray(4);;
+ private NyARFixedFloatTransOffset _offset_square;
+ public void setOffsetSquare(NyARFixedFloatTransOffset i_offset)
+ {
+ this._offset_square=i_offset;
+ return;
+ }
+ public NyARFixedFloat16Point2d[] getFitSquare()
+ {
+ return this._fitsquare_vertex;
+ }
+ public NyARFixedFloatTransOffset getOffsetVertex()
+ {
+ return this._offset_square;
+ }
+
+ /**
+ * 適合させる矩形座標を指定します。
+ * @param i_square_vertex
+ * @throws NyARException
+ */
+ public void setFittedSquare(NyARFixedFloat16Point2d[] i_square_vertex) throws NyARException
+ {
+ final NyARFixedFloat16Point2d[] vertex=_fitsquare_vertex;
+ for(int i=0;i<4;i++){
+ this._distortionfactor.ideal2Observ(i_square_vertex[i], vertex[i]);
+ }
+
+ final long cpara02=(long)(this._projection_mat.m02*NyMath.FIXEDFLOAT16_1);
+ final long cpara12=(long)(this._projection_mat.m12*NyMath.FIXEDFLOAT16_1);
+ final NyARFixedFloat16Mat mat_d=_mat_d;
+ final NyARFixedFloat16Mat mat_a=this._mat_a;
+ final NyARFixedFloat16Mat mat_b=this._mat_b;
+ final long[][] a_array = mat_a.getArray();
+ final long[][] b_array = mat_b.getArray();
+ for (int i = 0; i < 4; i++) {
+ final int x2 = i * 2;
+ a_array[x2][2] = b_array[2][x2] = (long)((cpara02 - vertex[i].x));// mat_a->m[j*6+2]=mat_b->m[num*4+j*2]=cpara[0][2]-pos2d[j][0];
+ a_array[x2 + 1][2] = b_array[2][x2 + 1] = (long)((cpara12 - vertex[i].y));// mat_a->m[j*6+5]=mat_b->m[num*4+j*2+1]=cpara[1][2]-pos2d[j][1];
+ }
+ // mat_d
+ mat_d.matrixMul(mat_b, mat_a);
+ this._mat_d2.copyFrom(mat_d);
+ this._mat_d2.matrixSelfInv();
+ return;
+ }
+ private final NyARFixedFloat16Mat _mat_e = new NyARFixedFloat16Mat(3, 1);
+ private final NyARFixedFloat16Mat __calculateTransferVec_mat_c = new NyARFixedFloat16Mat(8, 1);//NUMBER_OF_VERTEX * 2, 1
+ private final NyARFixedFloat16Point3d[] __calculateTransfer_point3d=NyARFixedFloat16Point3d.createArray(4);
+
+ /**
+ * 現在のオフセット矩形、適合先矩形と、回転行列から、平行移動量を計算します。
+ * @param i_rotation
+ * @param o_transfer
+ * @throws NyARException
+ */
+ final public void calculateTransfer(NyARFixedFloatRotMatrix i_rotation,NyARFixedFloat16Point3d o_transfer) throws NyARException
+ {
+ assert(this._offset_square!=null);
+ final long cpara00=(long)(this._projection_mat.m00*NyMath.FIXEDFLOAT16_1);
+ final long cpara01=(long)(this._projection_mat.m01*NyMath.FIXEDFLOAT16_1);
+ final long cpara02=(long)(this._projection_mat.m02*NyMath.FIXEDFLOAT16_1);
+ final long cpara11=(long)(this._projection_mat.m11*NyMath.FIXEDFLOAT16_1);
+ final long cpara12=(long)(this._projection_mat.m12*NyMath.FIXEDFLOAT16_1);
+
+ final NyARFixedFloat16Point3d[] point3d=this.__calculateTransfer_point3d;
+ final NyARFixedFloat16Point3d[] vertex3d=this._offset_square.vertex;
+ final NyARFixedFloat16Point2d[] vertex2d=this._fitsquare_vertex;
+ final NyARFixedFloat16Mat mat_c = this.__calculateTransferVec_mat_c;// 次処理で値をもらうので、初期化の必要は無い。
+
+ final long[][] c_array = mat_c.getArray();
+
+
+ //(3D座標?)を一括請求
+ i_rotation.getPoint3dBatch(vertex3d,point3d,4);
+ for (int i = 0; i < 4; i++) {
+ final int x2 = i+i;
+ final NyARFixedFloat16Point3d point3d_ptr=point3d[i];
+ //透視変換?
+ c_array[x2][0] =(long)((point3d_ptr.z * vertex2d[i].x - cpara00 * point3d_ptr.x - cpara01 * point3d_ptr.y - cpara02 * point3d_ptr.z)>>16);// mat_c->m[j*2+0] = wz*pos2d[j][0]-cpara[0][0]*wx-cpara[0][1]*wy-cpara[0][2]*wz;
+ c_array[x2 + 1][0] =(long)((point3d_ptr.z * vertex2d[i].y - cpara11 * point3d_ptr.y - cpara12 * point3d_ptr.z)>>16);// mat_c->m[j*2+1]= wz*pos2d[j][1]-cpara[1][1]*wy-cpara[1][2]*wz;
+ }
+ this._mat_e.matrixMul(this._mat_b, mat_c);
+ final double[][] d2=this._mat_d2.getArray();
+ final long[][] e2=this._mat_e.getArray();
+
+
+ //this._mat_f.matrixMul(this._mat_d, this._mat_e);
+
+ // double[] trans=wk_arGetTransMatSub_trans;//double trans[3];
+ o_transfer.x=(long)(d2[0][0]*e2[0][0]+d2[0][1]*e2[1][0]+d2[0][2]*e2[2][0]);
+ o_transfer.y=(long)(d2[1][0]*e2[0][0]+d2[1][1]*e2[1][0]+d2[1][2]*e2[2][0]);
+ o_transfer.z=(long)(d2[2][0]*e2[0][0]+d2[2][1]*e2[1][0]+d2[2][2]*e2[2][0]);
+ return;
+ }
+
+
+
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARTransMat_X2.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARTransMat_X2.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARTransMat_X2.java (revision 199)
@@ -0,0 +1,224 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.NyARSquare;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.transmat.*;
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;
+import jp.nyatla.nyartoolkit.core.transmat.fitveccalc.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core2.types.*;
+
+
+/**
+ * This class calculates ARMatrix from square information and holds it. --
+ * 変換行列を計算して、結果を保持するクラス。
+ *
+ */
+public class NyARTransMat_X2 implements INyARTransMat
+{
+ private final NyARFixedFloat16Point2d _center=new NyARFixedFloat16Point2d();
+ private final NyARFixedFloatTransOffset _offset=new NyARFixedFloatTransOffset();
+ private NyARFixedFloatRotMatrix _rotmatrix;
+ private NyARFixedFloatFitVecCalculator _calculator;
+ private NyARFixedFloatRotTransOptimize_O2 _mat_optimize;
+
+ public NyARTransMat_X2(NyARParam i_param) throws NyARException
+ {
+ final NyARPerspectiveProjectionMatrix pmat=i_param.getPerspectiveProjectionMatrix();
+ this._calculator=new NyARFixedFloatFitVecCalculator(pmat,i_param.getDistortionFactor());
+ this._rotmatrix = new NyARFixedFloatRotMatrix(pmat);
+ this._mat_optimize=new NyARFixedFloatRotTransOptimize_O2(pmat);
+ }
+
+ public void setCenter(double i_x, double i_y)
+ {
+ this._center.x= (long)i_x*NyMath.FIXEDFLOAT16_1;
+ this._center.y= (long)i_y*NyMath.FIXEDFLOAT16_1;
+ return;
+ }
+ /**
+ * 頂点順序をi_directionに対応して並べ替えます。
+ * @param i_square
+ * @param i_direction
+ * @param o_sqvertex_ref
+ * @param o_liner_ref
+ */
+ private final void initVertexOrder(NyARSquare i_square, int i_direction, NyARFixedFloat16Point2d[] o_sqvertex_ref, NyARLinear[] o_liner_ref)
+ {
+ //頂点順序を考慮した矩形の頂点情報
+ o_sqvertex_ref[0].x= (long)(i_square.sqvertex[(4 - i_direction) % 4].x*NyMath.FIXEDFLOAT16_1);
+ o_sqvertex_ref[0].y= (long)(i_square.sqvertex[(4 - i_direction) % 4].y*NyMath.FIXEDFLOAT16_1);
+ o_sqvertex_ref[1].x= (long)(i_square.sqvertex[(5 - i_direction) % 4].x*NyMath.FIXEDFLOAT16_1);
+ o_sqvertex_ref[1].y= (long)(i_square.sqvertex[(5 - i_direction) % 4].y*NyMath.FIXEDFLOAT16_1);
+ o_sqvertex_ref[2].x= (long)(i_square.sqvertex[(6 - i_direction) % 4].x*NyMath.FIXEDFLOAT16_1);
+ o_sqvertex_ref[2].y= (long)(i_square.sqvertex[(6 - i_direction) % 4].y*NyMath.FIXEDFLOAT16_1);
+ o_sqvertex_ref[3].x= (long)(i_square.sqvertex[(7 - i_direction) % 4].x*NyMath.FIXEDFLOAT16_1);
+ o_sqvertex_ref[3].y= (long)(i_square.sqvertex[(7 - i_direction) % 4].y*NyMath.FIXEDFLOAT16_1);
+ o_liner_ref[0]=i_square.line[(4 - i_direction) % 4];
+ o_liner_ref[1]=i_square.line[(5 - i_direction) % 4];
+ o_liner_ref[2]=i_square.line[(6 - i_direction) % 4];
+ o_liner_ref[3]=i_square.line[(7 - i_direction) % 4];
+ return;
+ }
+
+
+ private final NyARFixedFloat16Point2d[] __transMat_sqvertex_ref = NyARFixedFloat16Point2d.createArray(4);
+ private final NyARLinear[] __transMat_linear_ref=new NyARLinear[4];
+ private final NyARFixedFloat16Point3d __transMat_trans=new NyARFixedFloat16Point3d();
+ /**
+ * double arGetTransMat( ARMarkerInfo *marker_info,double center[2], double width, double conv[3][4] )
+ *
+ * @param i_square
+ * 計算対象のNyARSquareオブジェクト
+ * @param i_direction
+ * @param i_width
+ * @return
+ * @throws NyARException
+ */
+ public void transMat(final NyARSquare i_square, int i_direction, double i_width, NyARTransMatResult o_result_conv) throws NyARException
+ {
+ final NyARFixedFloat16Point2d[] sqvertex_ref = __transMat_sqvertex_ref;
+ final NyARLinear[] linear_ref=__transMat_linear_ref;
+ final NyARFixedFloat16Point3d trans=this.__transMat_trans;
+
+ //計算用に頂点情報を初期化(順番調整)
+ initVertexOrder(i_square, i_direction, sqvertex_ref,linear_ref);
+
+ //基準矩形を設定
+ this._offset.setSquare((long)(i_width*NyMath.FIXEDFLOAT16_1),this._center);
+
+ // rotationを矩形情報から計算
+ this._rotmatrix.initRotBySquare(linear_ref,sqvertex_ref);
+
+ //平行移動量計算機にオフセット頂点をセット
+ this._calculator.setOffsetSquare(this._offset);
+
+ //平行移動量計算機に適応先矩形の情報をセット
+ this._calculator.setFittedSquare(sqvertex_ref);
+
+ //回転行列の平行移動量の計算
+ this._calculator.calculateTransfer(this._rotmatrix,trans);
+
+ //計算結果の最適化(this._rotmatrix,trans)
+ this._mat_optimize.optimize(this._rotmatrix,trans,this._calculator);
+
+ // マトリクスの保存
+ this.updateMatrixValue(this._rotmatrix, this._offset.point, trans,o_result_conv);
+ return;
+ }
+ /**
+ * double arGetTransMatCont( ARMarkerInfo *marker_info, double prev_conv[3][4],double center[2], double width, double conv[3][4] )
+ *
+ * @param i_square
+ * @param i_direction
+ * マーカーの方位を指定する。
+ * @param i_width
+ * @param io_result_conv
+ * 計算履歴を持つNyARTransMatResultオブジェクトを指定する。 履歴を持たない場合は、transMatと同じ処理を行う。
+ * @return
+ * @throws NyARException
+ */
+ public void transMatContinue(NyARSquare i_square, int i_direction, double i_width, NyARTransMatResult io_result_conv) throws NyARException
+ {
+ /* 今度実装
+ final NyARDoublePoint2d[] sqvertex_ref = __transMat_sqvertex_ref;
+ final NyARLinear[] linear_ref=__transMat_linear_ref;
+ final NyARDoublePoint3d trans=this.__transMat_trans;
+
+ // io_result_convが初期値なら、transMatで計算する。
+ if (!io_result_conv.hasValue()) {
+ this.transMat(i_square, i_direction, i_width, io_result_conv);
+ return;
+ }
+
+ //基準矩形を設定
+ this._offset.setSquare(i_width,this._center);
+
+ // rotationを矩形情報を一つ前の変換行列で初期化
+ this._rotmatrix.initRotByPrevResult(io_result_conv);
+
+ //平行移動量計算機に、オフセット頂点をセット
+ this._calculator.setOffsetSquare(this._offset);
+
+ //平行移動量計算機に、適応先矩形の情報をセット
+ this._calculator.setFittedSquare(sqvertex_ref);
+
+ //回転行列の平行移動量の計算
+ this._calculator.calculateTransfer(this._rotmatrix,trans);
+
+ //計算結果の最適化(this._rotmatrix,trans)
+ final double err=this._mat_optimize.optimize(this._rotmatrix,trans,this._calculator);
+
+ //計算結果を保存
+ io_result_conv.updateMatrixValue(this._rotmatrix, this._offset.point, trans);
+
+ // エラー値が許容範囲でなければTransMatをやり直し
+ if (err > AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR) {
+ // rotationを矩形情報で初期化
+ this._rotmatrix.initRotBySquare(linear_ref,sqvertex_ref);
+ //回転行列の平行移動量の計算
+ this._calculator.calculateTransfer(this._rotmatrix,trans);
+ //計算結果の最適化(this._rotmatrix,trans)
+ final double err2=this._mat_optimize.optimize(this._rotmatrix,trans,this._calculator);
+ //エラー値が低かったら値を差換え
+ if (err2 < err) {
+ // 良い値が取れたら、差換え
+ io_result_conv.updateMatrixValue(this._rotmatrix, this._offset.point, trans);
+ }
+ }
+ return;*/
+ NyARException.notImplement();
+ }
+ public void updateMatrixValue(NyARFixedFloatRotMatrix i_rot, NyARFixedFloat16Point3d i_off, NyARFixedFloat16Point3d i_trans,NyARTransMatResult o_result)
+ {
+ o_result.m00=(double)i_rot.m00/NyMath.FIXEDFLOAT24_1;
+ o_result.m01=(double)i_rot.m01/NyMath.FIXEDFLOAT24_1;
+ o_result.m02=(double)i_rot.m02/NyMath.FIXEDFLOAT24_1;
+ o_result.m03=(double)(((i_rot.m00 * i_off.x + i_rot.m01 * i_off.y + i_rot.m02 * i_off.z)>>24) + i_trans.x)/NyMath.FIXEDFLOAT16_1;
+
+ o_result.m10 =(double)i_rot.m10/NyMath.FIXEDFLOAT24_1;
+ o_result.m11 =(double)i_rot.m11/NyMath.FIXEDFLOAT24_1;
+ o_result.m12 =(double)i_rot.m12/NyMath.FIXEDFLOAT24_1;
+ o_result.m13 =(double)(((i_rot.m10 * i_off.x + i_rot.m11 * i_off.y + i_rot.m12 * i_off.z)>>24) + i_trans.y)/NyMath.FIXEDFLOAT16_1;
+
+ o_result.m20 =(double)i_rot.m20/NyMath.FIXEDFLOAT24_1;
+ o_result.m21 =(double)i_rot.m21/NyMath.FIXEDFLOAT24_1;
+ o_result.m22 =(double)i_rot.m22/NyMath.FIXEDFLOAT24_1;
+ o_result.m23 =(double)(((i_rot.m20 * i_off.x + i_rot.m21 * i_off.y + i_rot.m22 * i_off.z)>>24) + i_trans.z)/NyMath.FIXEDFLOAT16_1;
+
+ o_result.has_value = true;
+ return;
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARSquareDetector_X2.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARSquareDetector_X2.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARSquareDetector_X2.java (revision 199)
@@ -0,0 +1,465 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.labeling.*;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.types.matrix.*;
+import jp.nyatla.nyartoolkit.core2.types.NyARI64Linear;
+import jp.nyatla.nyartoolkit.core2.types.NyARI64Point2d;
+import jp.nyatla.nyartoolkit.core2.types.matrix.NyARI64Matrix22;
+import jp.nyatla.nyartoolkit.core.*;
+
+
+
+/**
+ * イメージから正方形候補を検出するクラス。
+ * このクラスは、arDetectMarker2.cとの置き換えになります。
+ *
+ */
+public class NyARSquareDetector_X2 implements INyARSquareDetector
+{
+ private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000
+
+ private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70
+ private final int _width;
+ private final int _height;
+
+ private final INyARLabeling _labeling;
+
+ private final NyARLabelingImage _limage;
+
+ private final OverlapChecker _overlap_checker = new OverlapChecker();
+ private final NyARFixedFloatObserv2IdealMap _dist_factor_ref;
+// private final NyARFixFloatCameraDistortionFactorMap _dist_factor_ref;
+ private final NyARFixedFloatPca2d _pca;
+// private final INyARPca2d _pca;
+
+ /**
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。
+ *
+ * @param i_param
+ */
+ public NyARSquareDetector_X2(NyARFixedFloatObserv2IdealMap i_dist_factor_ref,NyARIntSize i_size) throws NyARException
+ {
+ this._width = i_size.w;
+ this._height = i_size.h;
+ this._dist_factor_ref = i_dist_factor_ref;
+ this._labeling = new NyARLabeling_ARToolKit_X2();
+ this._limage = new NyARLabelingImage(this._width, this._height);
+ this._labeling.attachDestination(this._limage);
+
+ // 輪郭の最大長は画面に映りうる最大の長方形サイズ。
+ int number_of_coord = (this._width + this._height) * 2;
+
+ // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。
+ this._max_coord = number_of_coord;
+ this._xcoord = new int[number_of_coord * 2];
+ this._ycoord = new int[number_of_coord * 2];
+ //PCA
+
+ this._pca=new NyARFixedFloatPca2d();
+ }
+ private final int PCA_LENGTH=20;
+
+ private final int _max_coord;
+ private final int[] _xcoord;
+ private final int[] _ycoord;
+ private final int[] _xpos=new int[PCA_LENGTH];
+ private final int[] _ypos=new int[PCA_LENGTH];
+
+ private void normalizeCoord(int[] i_coord_x, int[] i_coord_y, int i_index, int i_coord_num)
+ {
+ // vertex1を境界にして、後方に配列を連結
+ System.arraycopy(i_coord_x, 1, i_coord_x, i_coord_num, i_index);
+ System.arraycopy(i_coord_y, 1, i_coord_y, i_coord_num, i_index);
+ }
+
+ private final int[] __detectMarker_mkvertex = new int[5];
+
+ /**
+ * arDetectMarker2を基にした関数
+ * この関数はNyARSquare要素のうち、directionを除くパラメータを取得して返します。
+ * directionの確定は行いません。
+ * @param i_raster
+ * 解析する2値ラスタイメージを指定します。
+ * @param o_square_stack
+ * 抽出した正方形候補を格納するリスト
+ * @throws NyARException
+ */
+ public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException
+ {
+ final INyARLabeling labeling_proc = this._labeling;
+ final NyARLabelingImage limage = this._limage;
+
+ // 初期化
+
+ // マーカーホルダをリセット
+ o_square_stack.clear();
+
+ // ラベリング
+ labeling_proc.labeling(i_raster);
+
+ // ラベル数が0ならここまで
+ final int label_num = limage.getLabelStack().getLength();
+ if (label_num < 1) {
+ return;
+ }
+
+ final NyARLabelingLabelStack stack = limage.getLabelStack();
+ final NyARLabelingLabel[] labels = (NyARLabelingLabel[])stack.getArray();
+
+
+ // ラベルを大きい順に整列
+ stack.sortByArea();
+
+ // デカいラベルを読み飛ばし
+ int i;
+ for (i = 0; i < label_num; i++) {
+ // 検査対象内のラベルサイズになるまで無視
+ if (labels[i].area <= AR_AREA_MAX) {
+ break;
+ }
+ }
+
+ final int xsize = this._width;
+ final int ysize = this._height;
+ final int[] xcoord = this._xcoord;
+ final int[] ycoord = this._ycoord;
+ final int coord_max = this._max_coord;
+ final int[] mkvertex = this.__detectMarker_mkvertex;
+ final OverlapChecker overlap = this._overlap_checker;
+ int coord_num;
+ int label_area;
+ NyARLabelingLabel label_pt;
+
+ //重なりチェッカの最大数を設定
+ overlap.reset(label_num);
+
+ for (; i < label_num; i++) {
+ label_pt = labels[i];
+ label_area = label_pt.area;
+ // 検査対象サイズよりも小さくなったら終了
+ if (label_area < AR_AREA_MIN) {
+ break;
+ }
+ // クリップ領域が画面の枠に接していれば除外
+ if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){
+ continue;
+ }
+ if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){
+ continue;
+ }
+ // 既に検出された矩形との重なりを確認
+ if (!overlap.check(label_pt)) {
+ // 重なっているようだ。
+ continue;
+ }
+
+ // 輪郭を取得
+ coord_num = limage.getContour(i, coord_max, xcoord, ycoord);
+ if (coord_num == coord_max) {
+ // 輪郭が大きすぎる。
+ continue;
+ }
+ //頂点候補のインデクスを取得
+ final int vertex1 = scanVertex(xcoord, ycoord, coord_num);
+
+ // 頂点候補(vertex1)を先頭に並べなおした配列を作成する。
+ normalizeCoord(xcoord, ycoord, vertex1, coord_num);
+
+ // 領域を準備する。
+ NyARSquare square_ptr = (NyARSquare)o_square_stack.prePush();
+
+ // 頂点情報を取得
+ if (!getSquareVertex(xcoord, ycoord, vertex1, coord_num, label_area, mkvertex)) {
+ o_square_stack.pop();// 頂点の取得が出来なかったので破棄
+ continue;
+ }
+ // マーカーを検出
+ if (!getSquareLine(mkvertex, xcoord, ycoord, square_ptr)) {
+ // 矩形が成立しなかった。
+ o_square_stack.pop();
+ continue;
+ }
+ // 検出済の矩形の属したラベルを重なりチェックに追加する。
+ overlap.push(label_pt);
+ }
+ return;
+ }
+
+ /**
+ * 辺からの対角線が最長になる点を対角線候補として返す。
+ *
+ * @param i_xcoord
+ * @param i_ycoord
+ * @param i_coord_num
+ * @return
+ */
+ private int scanVertex(int[] i_xcoord, int[] i_ycoord, int i_coord_num)
+ {
+ final int sx = i_xcoord[0];
+ final int sy = i_ycoord[0];
+ int d = 0;
+ int w, x, y;
+ int ret = 0;
+ for (int i = 1; i < i_coord_num; i++) {
+ x = i_xcoord[i] - sx;
+ y = i_ycoord[i] - sy;
+ w = x * x + y * y;
+ if (w > d) {
+ d = w;
+ ret = i;
+ }
+ // ここでうまく終了条件入れられないかな。
+ }
+ return ret;
+ }
+
+ private final NyARFixedFloatVertexCounter __getSquareVertex_wv1 = new NyARFixedFloatVertexCounter();
+
+ private final NyARFixedFloatVertexCounter __getSquareVertex_wv2 = new NyARFixedFloatVertexCounter();
+
+ /**
+ * static int arDetectMarker2_check_square( int area, ARMarkerInfo2 *marker_info2, double factor ) 関数の代替関数 OPTIMIZED STEP [450->415] o_squareに頂点情報をセットします。
+ *
+ * @param i_x_coord
+ * @param i_y_coord
+ * @param i_vertex1_index
+ * @param i_coord_num
+ * @param i_area
+ * @param o_vertex
+ * 要素数はint[4]である事
+ * @return
+ */
+ private boolean getSquareVertex(int[] i_x_coord, int[] i_y_coord, int i_vertex1_index, int i_coord_num, int i_area, int[] o_vertex)
+ {
+ final NyARFixedFloatVertexCounter wv1 = this.__getSquareVertex_wv1;
+ final NyARFixedFloatVertexCounter wv2 = this.__getSquareVertex_wv2;
+ final int end_of_coord = i_vertex1_index + i_coord_num - 1;
+ final int sx = i_x_coord[i_vertex1_index];// sx = marker_info2->x_coord[0];
+ final int sy = i_y_coord[i_vertex1_index];// sy = marker_info2->y_coord[0];
+ int dmax = 0;
+ int v1 = i_vertex1_index;
+ for (int i = 1 + i_vertex1_index; i < end_of_coord; i++) {// for(i=1;i<marker_info2->coord_num-1;i++)
+ // {
+ final int d = (i_x_coord[i] - sx) * (i_x_coord[i] - sx) + (i_y_coord[i] - sy) * (i_y_coord[i] - sy);
+ if (d > dmax) {
+ dmax = d;
+ v1 = i;
+ }
+ }
+ //final double thresh = (i_area / 0.75) * 0.01;
+ final long thresh_f16 =(i_area<<16)/75;
+
+ o_vertex[0] = i_vertex1_index;
+
+ if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v1, thresh_f16)) { // if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,0,v1,thresh,wv1,&wvnum1)<
+ // 0 ) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v1, end_of_coord, thresh_f16)) {// if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,v1,marker_info2->coord_num-1,thresh,wv2,&wvnum2)
+ // < 0) {
+ return false;
+ }
+
+ int v2;
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {// if(wvnum1 == 1 && wvnum2== 1) {
+ o_vertex[1] = wv1.vertex[0];
+ o_vertex[2] = v1;
+ o_vertex[3] = wv2.vertex[0];
+ } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {// }else if( wvnum1 > 1 && wvnum2== 0) {
+ //頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。
+ v2 = (v1-i_vertex1_index)/2+i_vertex1_index;
+ if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v2, thresh_f16)) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v2, v1, thresh_f16)) {
+ return false;
+ }
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+ o_vertex[1] = wv1.vertex[0];
+ o_vertex[2] = wv2.vertex[0];
+ o_vertex[3] = v1;
+ } else {
+ return false;
+ }
+ } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) {
+ //v2 = (v1-i_vertex1_index+ end_of_coord-i_vertex1_index) / 2+i_vertex1_index;
+ v2 = (v1+ end_of_coord)/2;
+
+ if (!wv1.getVertex(i_x_coord, i_y_coord, v1, v2, thresh_f16)) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v2, end_of_coord, thresh_f16)) {
+ return false;
+ }
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+ o_vertex[1] = v1;
+ o_vertex[2] = wv1.vertex[0];
+ o_vertex[3] = wv2.vertex[0];
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ o_vertex[4] = end_of_coord;
+ return true;
+ }
+
+ private final NyARI64Matrix22 __getSquareLine_evec=new NyARI64Matrix22();
+ private final NyARI64Point2d __getSquareLine_mean=new NyARI64Point2d();
+ private final NyARI64Point2d __getSquareLine_ev=new NyARI64Point2d();
+ private final NyARI64Linear[] __getSquareLine_i64liner=NyARI64Linear.createArray(4);
+
+ /**
+ * arGetLine(int x_coord[], int y_coord[], int coord_num,int vertex[], double line[4][3], double v[4][2]) arGetLine2(int x_coord[], int y_coord[], int
+ * coord_num,int vertex[], double line[4][3], double v[4][2], double *dist_factor) の2関数の合成品です。 マーカーのvertex,lineを計算して、結果をo_squareに保管します。
+ * Optimize:STEP[424->391]
+ *
+ * @param i_cparam
+ * @return
+ * @throws NyARException
+ */
+ private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square) throws NyARException
+ {
+ final NyARLinear[] l_line = o_square.line;
+ final NyARI64Matrix22 evec=this.__getSquareLine_evec;
+ final NyARI64Point2d mean=this.__getSquareLine_mean;
+ final NyARI64Point2d ev=this.__getSquareLine_ev;
+ final NyARI64Linear[] i64liner=this.__getSquareLine_i64liner;
+
+ for (int i = 0; i < 4; i++) {
+// final double w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;
+ final int w1 = ((((i_mkvertex[i + 1] - i_mkvertex[i] + 1)<<8)*13)>>8) + (1<<7);
+ final int st = i_mkvertex[i] + (w1>>8);
+ final int ed = i_mkvertex[i + 1] - (w1>>8);
+ int n = ed - st + 1;
+ if (n < 2) {
+ // nが2以下でmatrix.PCAを計算することはできないので、エラー
+ return false;
+ }
+ //配列作成
+ n=this._dist_factor_ref.observ2IdealSampling(i_xcoord, i_ycoord, st, n,this._xpos,this._ypos,PCA_LENGTH);
+ //主成分分析する。
+ this._pca.pcaF16(this._xpos,this._ypos, n,evec, ev,mean);
+ final NyARI64Linear l_line_i = i64liner[i];
+ l_line_i.run = evec.m01;// line[i][0] = evec->m[1];
+ l_line_i.rise = -evec.m00;// line[i][1] = -evec->m[0];
+ l_line_i.intercept = -((l_line_i.run * mean.x + l_line_i.rise * mean.y)>>16);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);
+ }
+
+ final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;
+ final NyARIntPoint[] l_imvertex = o_square.imvertex;
+ for (int i = 0; i < 4; i++) {
+ final NyARI64Linear l_line_i = i64liner[i];
+ final NyARI64Linear l_line_2 = i64liner[(i + 3) % 4];
+ final long w1 =(l_line_2.run * l_line_i.rise - l_line_i.run * l_line_2.rise)>>16;
+ if (w1 == 0) {
+ return false;
+ }
+ l_sqvertex[i].x = (double)((l_line_2.rise * l_line_i.intercept - l_line_i.rise * l_line_2.intercept) / w1)/65536.0;
+ l_sqvertex[i].y = (double)((l_line_i.run * l_line_2.intercept - l_line_2.run * l_line_i.intercept) / w1)/65536.0;
+ // 頂点インデクスから頂点座標を得て保存
+ l_imvertex[i].x = i_xcoord[i_mkvertex[i]];
+ l_imvertex[i].y = i_ycoord[i_mkvertex[i]];
+ l_line[i].run=(double)l_line_i.run/65536.0;
+ l_line[i].rise=(double)l_line_i.rise/65536.0;
+ l_line[i].intercept=(double)l_line_i.intercept/65536.0;
+ }
+ return true;
+ }
+}
+
+
+/**
+ * ラベル同士の重なり(内包関係)を調べるクラスです。
+ * ラベルリストに内包するラベルを蓄積し、それにターゲットのラベルが内包されているか を確認します。
+ */
+class OverlapChecker
+{
+ private NyARLabelingLabel[] _labels = new NyARLabelingLabel[32];
+
+ private int _length;
+
+ /**
+ * 最大i_max_label個のラベルを蓄積できるようにオブジェクトをリセットする
+ *
+ * @param i_max_label
+ */
+ public void reset(int i_max_label)
+ {
+ if (i_max_label > this._labels.length) {
+ this._labels = new NyARLabelingLabel[i_max_label];
+ }
+ this._length = 0;
+ }
+
+ /**
+ * チェック対象のラベルを追加する。
+ *
+ * @param i_label_ref
+ */
+ public void push(NyARLabelingLabel i_label_ref)
+ {
+ this._labels[this._length] = i_label_ref;
+ this._length++;
+ }
+
+ /**
+ * 現在リストにあるラベルと重なっているかを返す。
+ *
+ * @param i_label
+ * @return 何れかのラベルの内側にあるならばfalse,独立したラベルである可能性が高ければtrueです.
+ */
+ public boolean check(NyARLabelingLabel i_label)
+ {
+ // 重なり処理かな?
+ final NyARLabelingLabel[] label_pt = this._labels;
+ final int px1 = (int) i_label.pos_x;
+ final int py1 = (int) i_label.pos_y;
+ for (int i = this._length - 1; i >= 0; i--) {
+ final int px2 = (int) label_pt[i].pos_x;
+ final int py2 = (int) label_pt[i].pos_y;
+ final int d = (px1 - px2) * (px1 - px2) + (py1 - py2) * (py1 - py2);
+ if (d < label_pt[i].area / 4) {
+ // 対象外
+ return false;
+ }
+ }
+ // 対象
+ return true;
+ }
+}
\ No newline at end of file
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatRotTransOptimize_O2.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatRotTransOptimize_O2.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatRotTransOptimize_O2.java (revision 199)
@@ -0,0 +1,279 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core2.types.NyARFixedFloat16Point2d;
+import jp.nyatla.nyartoolkit.core2.types.NyARFixedFloat16Point3d;
+
+/**
+ * 基本姿勢と実画像を一致するように、角度を微調整→平行移動量を再計算
+ * を繰り返して、変換行列を最適化する。
+ *
+ */
+public class NyARFixedFloatRotTransOptimize_O2
+{
+ private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT = 1;// #define AR_GET_TRANS_MAT_MAX_LOOP_COUNT 5
+ private final NyARPerspectiveProjectionMatrix _projection_mat_ref;
+ public NyARFixedFloatRotTransOptimize_O2(NyARPerspectiveProjectionMatrix i_projection_mat_ref)
+ {
+ this._projection_mat_ref=i_projection_mat_ref;
+ return;
+ }
+
+ final public double optimize(NyARFixedFloatRotMatrix io_rotmat,NyARFixedFloat16Point3d io_transvec,NyARFixedFloatFitVecCalculator i_calculator) throws NyARException
+ {
+ final NyARFixedFloat16Point2d[] fit_vertex=i_calculator.getFitSquare();
+ final NyARFixedFloat16Point3d[] offset_square=i_calculator.getOffsetVertex().vertex;
+
+ double err = -1;
+ err = modifyMatrix(io_rotmat,io_transvec,offset_square,fit_vertex);
+ /*ループを抜けるタイミングをARToolKitと合わせるために変なことしてます。*/
+ for (int i = 0; ; i++)
+ {
+ // <arGetTransMat3>
+ err = modifyMatrix(io_rotmat, io_transvec, offset_square, fit_vertex);
+ i_calculator.calculateTransfer(io_rotmat, io_transvec);
+ err = modifyMatrix(io_rotmat, io_transvec, offset_square, fit_vertex);
+ // //</arGetTransMat3>
+ if (err < 1.0 || i == AR_GET_TRANS_MAT_MAX_LOOP_COUNT - 1)
+ {
+ break;
+ }
+ i_calculator.calculateTransfer(io_rotmat, io_transvec);
+ }
+ return err;
+ }
+
+ private final long[][] __modifyMatrix_double1D = new long[8][3];
+ private final NyARFixedFloat16Point3d __modifyMatrix_angle = new NyARFixedFloat16Point3d();
+ private final long INITIAL_FACTOR=(long)(0x10000*5.0 * Math.PI / 180.0);
+ /**
+ * arGetRot計算を階層化したModifyMatrix 896
+ *
+ * @param nyrot
+ * @param trans
+ * @param i_vertex3d
+ * [m][3]
+ * @param i_vertex2d
+ * [n][2]
+ * @return
+ * @throws NyARException
+ */
+ private double modifyMatrix(NyARFixedFloatRotMatrix io_rot,NyARFixedFloat16Point3d trans, NyARFixedFloat16Point3d[] i_vertex3d, NyARFixedFloat16Point2d[] i_vertex2d) throws NyARException
+ {
+ long a2, b2, c2;
+ long h, x, y;
+ long err, minerr = 0;
+ int t1, t2, t3;
+ int best_idx=0;
+
+ long factor = INITIAL_FACTOR;
+ long rot0, rot1, rot2;
+ long combo00, combo01, combo02, combo03, combo10, combo11, combo12, combo13, combo20, combo21, combo22, combo23;
+ long combo02_2, combo02_5, combo02_8, combo02_11;
+ long combo22_2, combo22_5, combo22_8, combo22_11;
+ long combo12_2, combo12_5, combo12_8, combo12_11;
+ // vertex展開
+ final long VX00, VX01, VX02, VX10, VX11, VX12, VX20, VX21, VX22, VX30, VX31, VX32;
+ VX00 = i_vertex3d[0].x;
+ VX01 = i_vertex3d[0].y;
+ VX02 = i_vertex3d[0].z;
+ VX10 = i_vertex3d[1].x;
+ VX11 = i_vertex3d[1].y;
+ VX12 = i_vertex3d[1].z;
+ VX20 = i_vertex3d[2].x;
+ VX21 = i_vertex3d[2].y;
+ VX22 = i_vertex3d[2].z;
+ VX30 = i_vertex3d[3].x;
+ VX31 = i_vertex3d[3].y;
+ VX32 = i_vertex3d[3].z;
+ final long P2D00, P2D01, P2D10, P2D11, P2D20, P2D21, P2D30, P2D31;
+ P2D00 = i_vertex2d[0].x;
+ P2D01 = i_vertex2d[0].y;
+ P2D10 = i_vertex2d[1].x;
+ P2D11 = i_vertex2d[1].y;
+ P2D20 = i_vertex2d[2].x;
+ P2D21 = i_vertex2d[2].y;
+ P2D30 = i_vertex2d[3].x;
+ P2D31 = i_vertex2d[3].y;
+ final NyARPerspectiveProjectionMatrix prjmat = this._projection_mat_ref;
+ final long CP0,CP1,CP2,CP3,CP4,CP5,CP6,CP7,CP8,CP9,CP10;
+ CP0 = (long)(prjmat.m00*0x10000L);
+ CP1 = (long)(prjmat.m01*0x10000L);
+ CP2 = (long)(prjmat.m02*0x10000L);
+ CP4 = (long)(prjmat.m10*0x10000L);
+ CP5 = (long)(prjmat.m11*0x10000L);
+ CP6 = (long)(prjmat.m12*0x10000L);
+ CP8 = (long)(prjmat.m20*0x10000L);
+ CP9 = (long)(prjmat.m21*0x10000L);
+ CP10 =(long)(prjmat.m22*0x10000L);
+
+ combo03 = ((CP0 * trans.x + CP1 * trans.y + CP2 * trans.z)>>16) + (long)(prjmat.m03*0x10000L);
+ combo13 = ((CP4 * trans.x + CP5 * trans.y + CP6 * trans.z)>>16) + (long)(prjmat.m13*0x10000L);
+ combo23 = ((CP8 * trans.x + CP9 * trans.y + CP10 * trans.z)>>16) + (long)(prjmat.m23*0x10000L);
+ long CACA, SASA, SACA, CA, SA;
+ long CACACB, SACACB, SASACB, CASB, SASB;
+ long SACASC, SACACBSC, SACACBCC, SACACC;
+ final long[][] double1D = this.__modifyMatrix_double1D;
+
+ final NyARFixedFloat16Point3d angle = this.__modifyMatrix_angle;
+ final long[] a_factor = double1D[1];
+ final long[] sinb = double1D[2];
+ final long[] cosb = double1D[3];
+ final long[] b_factor = double1D[4];
+ final long[] sinc = double1D[5];
+ final long[] cosc = double1D[6];
+ final long[] c_factor = double1D[7];
+ long w, w2;
+ long wsin, wcos;
+
+ io_rot.getAngle(angle);// arGetAngle( rot, &a, &b, &c );
+ a2 =angle.x;
+ b2 =angle.y;
+ c2 =angle.z;
+
+ // comboの3行目を先に計算
+ for (int i = 0; i < 10; i++) {
+ minerr = 0x4000000000000000L;
+ // sin-cosテーブルを計算(これが外に出せるとは…。)
+ for (int j = 0; j < 3; j++) {
+ w2 = factor * (j - 1);//S16
+ w = a2 + w2;//S16
+ a_factor[j] = w;//S16
+ w = b2 + w2;//S16
+ b_factor[j] = w;//S16
+ sinb[j] = NyMath.sinFixedFloat24((int)w);
+ cosb[j] = NyMath.cosFixedFloat24((int)w);
+ w = c2 + w2;//S16
+ c_factor[j] = w;//S16
+ sinc[j] = NyMath.sinFixedFloat24((int)w);
+ cosc[j] = NyMath.cosFixedFloat24((int)w);
+ }
+ //
+ for (t1 = 0; t1 < 3; t1++) {
+ SA = NyMath.sinFixedFloat24((int)a_factor[t1]);
+ CA = NyMath.cosFixedFloat24((int)a_factor[t1]);
+ // Optimize
+ CACA = (CA * CA)>>24;//S24
+ SASA = (SA * SA)>>24;//S24
+ SACA = (SA * CA)>>24;//S24
+ for (t2 = 0; t2 < 3; t2++) {
+ wsin = sinb[t2];//S24
+ wcos = cosb[t2];//S24
+ CACACB = (CACA * wcos)>>24;//S24
+ SACACB = (SACA * wcos)>>24;//S24
+ SASACB = (SASA * wcos)>>24;//S24
+ CASB = (CA * wsin)>>24;//S24
+ SASB = (SA * wsin)>>24;//S24
+
+ // comboの計算1
+ combo02 = (CP0 * CASB + CP1 * SASB + CP2 * wcos)>>24;//S24*S16>>24=S16
+ combo12 = (CP4 * CASB + CP5 * SASB + CP6 * wcos)>>24;//S24*S16>>24=S16
+ combo22 = (CP8 * CASB + CP9 * SASB + CP10 * wcos)>>24;//S24*S16>>24=S16
+
+ combo02_2 = ((combo02 * VX02)>>16) + combo03;//S16
+ combo02_5 = ((combo02 * VX12)>>16) + combo03;//S16
+ combo02_8 = ((combo02 * VX22)>>16) + combo03;//S16
+ combo02_11 = ((combo02 * VX32)>>16) + combo03;//S16
+ combo12_2 = ((combo12 * VX02)>>16) + combo13;//S16
+ combo12_5 = ((combo12 * VX12)>>16) + combo13;//S16
+ combo12_8 = ((combo12 * VX22)>>16) + combo13;//S16
+ combo12_11 = ((combo12 * VX32)>>16) + combo13;//S16
+ combo22_2 = ((combo22 * VX02)>>16) + combo23;//S16
+ combo22_5 = ((combo22 * VX12)>>16) + combo23;//S16
+ combo22_8 = ((combo22 * VX22)>>16) + combo23;//S16
+ combo22_11 = ((combo22 * VX32)>>16) + combo23;//S16
+ for (t3 = 0; t3 < 3; t3++) {
+ wsin = sinc[t3];//S24
+ wcos = cosc[t3];//S24
+ SACASC = (SACA * wsin)>>24;//S24
+ SACACC = (SACA * wcos)>>24;//S24
+ SACACBSC =(SACACB * wsin)>>24;//S24;
+ SACACBCC = (SACACB * wcos)>>24;//S24;
+
+ rot0 = ((CACACB * wcos + SASA * wcos)>>24) + SACACBSC - SACASC;//S24;
+ rot1 = SACACBCC - SACACC + ((SASACB * wsin + CACA * wsin)>>24);//S24;
+ rot2 = (-CASB * wcos - SASB * wsin)>>24;//S24;
+ combo00 = (CP0 * rot0 + CP1 * rot1 + CP2 * rot2)>>24;//S16
+ combo10 = (CP4 * rot0 + CP5 * rot1 + CP6 * rot2)>>24;//S16
+ combo20 = (CP8 * rot0 + CP9 * rot1 + CP10 * rot2)>>24;//S16
+
+ rot0 = ((-CACACB * wsin - SASA * wsin)>>24) + SACACBCC - SACACC;//S24
+ rot1 = -SACACBSC + SACASC + ((SASACB * wcos + CACA * wcos)>>24);//S24
+ rot2 = (CASB * wsin - SASB * wcos)>>24;//S24
+
+ combo01 =(CP0 * rot0 + CP1 * rot1 + CP2 * rot2)>>24;//S16
+ combo11 =(CP4 * rot0 + CP5 * rot1 + CP6 * rot2)>>24;//S16
+ combo21 =(CP8 * rot0 + CP9 * rot1 + CP10 * rot2)>>24;//S16
+ //
+ err =0;
+ h = ((combo20 * VX00 + combo21 * VX01)>>16) + combo22_2;//S16
+ x = P2D00 - ((((combo00 * VX00 + combo01 * VX01)>>16) + combo02_2)<<16) / h;//S16
+ y = P2D01 - ((((combo10 * VX00 + combo11 * VX01)>>16) + combo12_2)<<16) / h;//S16
+ err += ((x * x + y * y)>>16);
+ h = ((combo20 * VX10 + combo21 * VX11)>>16) + combo22_5;
+ x = P2D10 - ((((combo00 * VX10 + combo01 * VX11)>>16) + combo02_5)<<16) / h;//S16
+ y = P2D11 - ((((combo10 * VX10 + combo11 * VX11)>>16) + combo12_5)<<16) / h;//S16
+ err += ((x * x + y * y)>>16);
+ h = ((combo20 * VX20 + combo21 * VX21)>>16) + combo22_8;
+ x = P2D20 - ((((combo00 * VX20 + combo01 * VX21)>>16) + combo02_8)<<16) / h;//S16
+ y = P2D21 - ((((combo10 * VX20 + combo11 * VX21)>>16) + combo12_8)<<16) / h;//S16
+ err += ((x * x + y * y)>>16);
+ h = ((combo20 * VX30 + combo21 * VX31)>>16) + combo22_11;
+ x = P2D30 - ((((combo00 * VX30 + combo01 * VX31)>>16) + combo02_11)<<16) / h;//S16
+ y = P2D31 - ((((combo10 * VX30 + combo11 * VX31)>>16) + combo12_11)<<16) / h;//S16
+ err += ((x * x + y * y)>>16);
+ if (err < minerr) {
+ minerr = err;
+ a2 = a_factor[t1];
+ b2 = b_factor[t2];
+ c2 = c_factor[t3];
+ best_idx=t1+t2*3+t3*9;
+ }
+ }
+ }
+ }
+ if (best_idx==(1+3+9)) {
+ factor=factor>>1;
+ }
+ }
+ io_rot.setAngle((int)a2,(int)b2,(int)c2);
+ /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */
+ return minerr /4;
+ }
+
+
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatTransOffset.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatTransOffset.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatTransOffset.java (revision 199)
@@ -0,0 +1,74 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import jp.nyatla.nyartoolkit.core2.types.*;
+
+
+final public class NyARFixedFloatTransOffset
+{
+ public NyARFixedFloat16Point3d[] vertex=NyARFixedFloat16Point3d.createArray(4);
+ public NyARFixedFloat16Point3d point=new NyARFixedFloat16Point3d();
+ /**
+ * 中心位置と辺長から、オフセット情報を作成して設定する。
+ * @param i_width
+ * FF16で渡すこと!
+ * @param i_center
+ */
+ public void setSquare(long i_width,NyARFixedFloat16Point2d i_center)
+ {
+ final long w_2 = i_width>>1;
+
+ NyARFixedFloat16Point3d vertex3d_ptr;
+ vertex3d_ptr= this.vertex[0];
+ vertex3d_ptr.x = -w_2;
+ vertex3d_ptr.y = w_2;
+ vertex3d_ptr.z = 0;
+ vertex3d_ptr= this.vertex[1];
+ vertex3d_ptr.x = w_2;
+ vertex3d_ptr.y = w_2;
+ vertex3d_ptr.z = 0;
+ vertex3d_ptr= this.vertex[2];
+ vertex3d_ptr.x = w_2;
+ vertex3d_ptr.y = -w_2;
+ vertex3d_ptr.z = 0;
+ vertex3d_ptr= this.vertex[3];
+ vertex3d_ptr.x = -w_2;
+ vertex3d_ptr.y = -w_2;
+ vertex3d_ptr.z = 0;
+
+ this.point.x=-i_center.x;
+ this.point.y=-i_center.y;
+ this.point.z=0;
+ return;
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARQrCodeDetector.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARQrCodeDetector.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARQrCodeDetector.java (revision 199)
@@ -0,0 +1,494 @@
+package jp.nyatla.nyartoolkit.sandbox.qrcode;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.INyARSquareDetector;
+import jp.nyatla.nyartoolkit.core.NyARSquare;
+import jp.nyatla.nyartoolkit.core.NyARSquareStack;
+import jp.nyatla.nyartoolkit.core.NyARVertexCounter;
+import jp.nyatla.nyartoolkit.core.labeling.INyARLabeling;
+import jp.nyatla.nyartoolkit.core.labeling.NyARLabelingImage;
+import jp.nyatla.nyartoolkit.core.labeling.NyARLabelingLabel;
+import jp.nyatla.nyartoolkit.core.labeling.NyARLabelingLabelStack;
+import jp.nyatla.nyartoolkit.core.labeling.NyARLabeling_ARToolKit;
+import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;
+import jp.nyatla.nyartoolkit.core.pca2d.INyARPca2d;
+import jp.nyatla.nyartoolkit.core.pca2d.*;
+import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint;
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;
+import jp.nyatla.nyartoolkit.core.types.NyARLinear;
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;
+
+public class NyARQrCodeDetector implements INyARSquareDetector
+{
+ private NyARQrCodeSymbolBinder _binder;
+ private static final double VERTEX_FACTOR = 2.0;// 線検出のファクタ
+
+ private static final int AR_AREA_MAX = 10000;
+
+ private static final int AR_AREA_MIN = 50;
+
+ private final int _width;
+
+ private final int _height;
+
+ private final NyARLabeling_ARToolKit _labeling;
+
+ private final NyARLabelingImage _limage;
+
+ private final NyARCameraDistortionFactor _dist_factor_ref;
+ private final double[] _xpos;
+ private final double[] _ypos;
+ /**
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。
+ *
+ * @param i_param
+ */
+ public NyARQrCodeDetector(NyARCameraDistortionFactor i_dist_factor_ref, NyARIntSize i_size) throws NyARException
+ {
+ this._width = i_size.w;
+ this._height = i_size.h;
+ this._dist_factor_ref = i_dist_factor_ref;
+ this._labeling = new NyARLabeling_ARToolKit();
+ this._limage = new NyARLabelingImage(this._width, this._height);
+ this._labeling.attachDestination(this._limage);
+ this._binder=new NyARQrCodeSymbolBinder(i_dist_factor_ref);
+
+ // 輪郭の最大長はMAX_COORD_NUMの2倍に制限
+ int number_of_coord = MAX_COORD_NUM* 2;
+
+ // 輪郭バッファはnumber_of_coordの2倍
+ this._max_coord = number_of_coord;
+ this._xcoord = new int[number_of_coord * 2];
+ this._ycoord = new int[number_of_coord * 2];
+ this._xpos=new double[this._width+this._height];//最大辺長はthis._width+this._height
+ this._ypos=new double[this._width+this._height];//最大辺長はthis._width+this._height
+
+ }
+
+ private final int _max_coord;
+
+ private final int[] _xcoord;
+
+ private final int[] _ycoord;
+
+ private void normalizeCoord(int[] i_coord_x, int[] i_coord_y, int i_index, int i_coord_num)
+ {
+ // vertex1を境界にして、後方に配列を連結
+ System.arraycopy(i_coord_x, 1, i_coord_x, i_coord_num, i_index);
+ System.arraycopy(i_coord_y, 1, i_coord_y, i_coord_num, i_index);
+ }
+
+ private final int[] __detectMarker_mkvertex = new int[5];
+
+ /**
+ * ARMarkerInfo2 *arDetectMarker2( ARInt16 *limage, int label_num, int *label_ref,int *warea, double *wpos, int *wclip,int area_max, int area_min, double
+ * factor, int *marker_num ) 関数の代替品 ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。 関数はo_marker_listに重なりを除外したマーカーリストを作成します。
+ *
+ * @param i_raster
+ * 解析する2値ラスタイメージを指定します。
+ * @param o_square_stack
+ * 抽出した正方形候補を格納するリスト
+ * @throws NyARException
+ */
+ public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException
+ {
+ final INyARLabeling labeling_proc = this._labeling;
+ final NyARLabelingImage limage = this._limage;
+
+ // 初期化
+
+ // マーカーホルダをリセット
+ o_square_stack.clear();
+
+ // ラベリング
+ labeling_proc.labeling(i_raster);
+
+ // ラベル数が0ならここまで
+ final int label_num = limage.getLabelStack().getLength();
+ if (label_num < 1) {
+ return;
+ }
+
+ final NyARLabelingLabelStack stack = limage.getLabelStack();
+ final NyARLabelingLabel[] labels = (NyARLabelingLabel[]) stack.getArray();
+
+ // ラベルを大きい順に整列
+ stack.sortByArea();
+
+ // デカいラベルを読み飛ばし
+ int i;
+ for (i = 0; i < label_num; i++) {
+ // 検査対象内のラベルサイズになるまで無視
+ if (labels[i].area <= AR_AREA_MAX) {
+ break;
+ }
+ }
+
+ final int xsize = this._width;
+ final int ysize = this._height;
+ final int[] xcoord = this._xcoord;
+ final int[] ycoord = this._ycoord;
+ final int coord_max = this._max_coord;
+ final int[] mkvertex = this.__detectMarker_mkvertex;
+ final int[][] buf = (int[][]) limage.getBufferReader().getBuffer();
+ final int[] indextable = limage.getIndexArray();
+ int coord_num;
+ int label_area;
+ NyARLabelingLabel label_pt;
+ NyARSquareStack wk_stack=new NyARSquareStack(10);
+ wk_stack.clear();
+
+ for (; i < label_num; i++) {
+ label_pt = labels[i];
+ label_area = label_pt.area;
+ // 検査対象サイズよりも小さくなったら終了
+ if (label_area < AR_AREA_MIN) {
+ break;
+ }
+ // クリップ領域が画面の枠に接していれば除外
+ if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){
+ continue;
+ }
+ if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){
+ continue;
+ }
+ // 特徴点候補であるかを確認する。
+ if (!hasQrEdgeFeature(buf, indextable, label_pt)) {
+ continue;
+ }
+
+ // 輪郭を取得
+ coord_num = limage.getContour(i, coord_max, xcoord, ycoord);
+ if (coord_num == coord_max) {
+ // 輪郭が大きすぎる。
+ continue;
+ }
+ // 頂点候補のインデクスを取得
+ final int vertex1 = scanVertex(xcoord, ycoord, coord_num);
+
+ // 頂点候補(vertex1)を先頭に並べなおした配列を作成する。
+ normalizeCoord(xcoord, ycoord, vertex1, coord_num);
+
+ // 頂点情報を取得
+ if (!getSquareVertex(xcoord, ycoord, vertex1, coord_num, label_area, mkvertex)) {
+ continue;
+ }
+ NyARSquare square=(NyARSquare)wk_stack.prePush();
+ //矩形からラインと観察座標を取得
+ if(!getSquareLine(mkvertex,xcoord,ycoord,square.line,square.imvertex)){
+ wk_stack.pop();
+ continue;
+ }
+ }
+ //シンボルの関連付け
+ bindQrcodeEdge(wk_stack,o_square_stack);
+ //エッジ同士の相関関係をしらべる。
+
+ return;
+ }
+
+ /**
+ * QRコードのエッジグループを作る
+ * @param i_square_stack
+ */
+ public void bindQrcodeEdge(NyARSquareStack i_square_stack,NyARSquareStack o_square_stack) throws NyARException
+ {
+ NyARSquare[] group=new NyARSquare[3];
+ int number_of_edge=i_square_stack.getLength();
+ if(number_of_edge<3){
+ return;
+ }
+ NyARSquare[] sa=(NyARSquare[])i_square_stack.getArray();
+ for(int i=0;i<number_of_edge-2;i++)
+ {
+ group[0]=sa[i];
+ for(int i2=i+1;i2<number_of_edge-1;i2++)
+ {
+ group[1]=sa[i2];
+ for(int i3=i2+1;i3<number_of_edge;i3++){
+ group[2]=sa[i3];
+ //3個のエッジの関連性を確認する。
+ NyARSquare new_square=(NyARSquare)o_square_stack.prePush();
+ if(!this._binder.composeSquare(group,new_square)){
+ o_square_stack.pop();
+ }
+ }
+ }
+ }
+ return;
+ }
+ private static int MAX_COORD_NUM=(320+240)*2;//サイズの1/2の長方形の編程度が目安(VGAなら(320+240)*2)
+ private final INyARPca2d _pca=new NyARPca2d_MatrixPCA_O2();
+ private final NyARDoubleMatrix22 __getSquareLine_evec=new NyARDoubleMatrix22();
+ private final NyARDoublePoint2d __getSquareLine_mean=new NyARDoublePoint2d();
+ private final NyARDoublePoint2d __getSquareLine_ev=new NyARDoublePoint2d();
+ /**
+ * 頂点インデクスと輪郭配列から、Ideal座標系とLineを作成して変数に返す
+ * @param i_cparam
+ * @return
+ * @throws NyARException
+ */
+ private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARLinear[] o_line,NyARIntPoint[] o_imvertex) throws NyARException
+ {
+ final NyARDoubleMatrix22 evec=this.__getSquareLine_evec;
+ final NyARDoublePoint2d mean=this.__getSquareLine_mean;
+ final NyARDoublePoint2d ev=this.__getSquareLine_ev;
+
+
+ for (int i = 0; i < 4; i++) {
+ final double w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;
+ final int st = (int) (i_mkvertex[i] + w1);
+ final int ed = (int) (i_mkvertex[i + 1] - w1);
+ final int n = ed - st + 1;
+ if (n < 2 || n>MAX_COORD_NUM) {
+ // nが2以下、又はMAX_COORD_NUM以上なら主成分分析をしない。
+ return false;
+ }
+ //配列作成
+ this._dist_factor_ref.observ2IdealBatch(i_xcoord, i_ycoord, st, n,this._xpos,this._ypos);
+
+ //主成分分析する。
+ this._pca.pca(this._xpos,this._ypos,n,evec, ev,mean);
+ final NyARLinear l_line_i = o_line[i];
+ l_line_i.run = evec.m01;// line[i][0] = evec->m[1];
+ l_line_i.rise = -evec.m00;// line[i][1] = -evec->m[0];
+ l_line_i.intercept = -(l_line_i.run * mean.x + l_line_i.rise * mean.y);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);
+ }
+ for (int i = 0; i < 4; i++) {
+ final NyARLinear l_line_i = o_line[i];
+ final NyARLinear l_line_2 = o_line[(i + 3) % 4];
+ final double w1 = l_line_2.run * l_line_i.rise - l_line_i.run * l_line_2.rise;
+ if (w1 == 0.0) {
+ return false;
+ }
+ // 頂点インデクスから頂点座標を得て保存
+ o_imvertex[i].x = i_xcoord[i_mkvertex[i]];
+ o_imvertex[i].y = i_ycoord[i_mkvertex[i]];
+ }
+ return true;
+ }
+ /**
+ * 辺からの対角線が最長になる点を対角線候補として返す。
+ *
+ * @param i_xcoord
+ * @param i_ycoord
+ * @param i_coord_num
+ * @return
+ */
+ private int scanVertex(int[] i_xcoord, int[] i_ycoord, int i_coord_num)
+ {
+ final int sx = i_xcoord[0];
+ final int sy = i_ycoord[0];
+ int d = 0;
+ int w, x, y;
+ int ret = 0;
+ for (int i = 1; i < i_coord_num; i++) {
+ x = i_xcoord[i] - sx;
+ y = i_ycoord[i] - sy;
+ w = x * x + y * y;
+ if (w > d) {
+ d = w;
+ ret = i;
+ }
+ // ここでうまく終了条件入れられないかな。
+ }
+ return ret;
+ }
+
+ private final NyARVertexCounter __getSquareVertex_wv1 = new NyARVertexCounter();
+ private final NyARVertexCounter __getSquareVertex_wv2 = new NyARVertexCounter();
+
+ /**
+ * static int arDetectMarker2_check_square( int area, ARMarkerInfo2 *marker_info2, double factor ) 関数の代替関数 OPTIMIZED STEP [450->415] o_squareに頂点情報をセットします。
+ *
+ * @param i_x_coord
+ * @param i_y_coord
+ * @param i_vertex1_index
+ * @param i_coord_num
+ * @param i_area
+ * @param o_vertex
+ * 要素数はint[4]である事
+ * @return
+ */
+ private boolean getSquareVertex(int[] i_x_coord, int[] i_y_coord, int i_vertex1_index, int i_coord_num, int i_area, int[] o_vertex)
+ {
+ final NyARVertexCounter wv1 = this.__getSquareVertex_wv1;
+ final NyARVertexCounter wv2 = this.__getSquareVertex_wv2;
+ final int end_of_coord = i_vertex1_index + i_coord_num - 1;
+ final int sx = i_x_coord[i_vertex1_index];// sx = marker_info2->x_coord[0];
+ final int sy = i_y_coord[i_vertex1_index];// sy = marker_info2->y_coord[0];
+ int dmax = 0;
+ int v1 = i_vertex1_index;
+ for (int i = 1 + i_vertex1_index; i < end_of_coord; i++) {// for(i=1;i<marker_info2->coord_num-1;i++)
+ // {
+ final int d = (i_x_coord[i] - sx) * (i_x_coord[i] - sx) + (i_y_coord[i] - sy) * (i_y_coord[i] - sy);
+ if (d > dmax) {
+ dmax = d;
+ v1 = i;
+ }
+ }
+ final double thresh = (i_area / 0.75) * 0.01 * VERTEX_FACTOR;
+
+ o_vertex[0] = i_vertex1_index;
+
+ if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v1, thresh)) { // if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,0,v1,thresh,wv1,&wvnum1)<
+ // 0 ) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v1, end_of_coord, thresh)) {// if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,v1,marker_info2->coord_num-1,thresh,wv2,&wvnum2)
+ // < 0) {
+ return false;
+ }
+
+ int v2;
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {// if(wvnum1 == 1 && wvnum2== 1) {
+ o_vertex[1] = wv1.vertex[0];
+ o_vertex[2] = v1;
+ o_vertex[3] = wv2.vertex[0];
+ } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {// }else if( wvnum1 > 1 && wvnum2== 0) {
+ // 頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。
+ v2 = (v1 - i_vertex1_index) / 2 + i_vertex1_index;
+ if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v2, thresh)) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v2, v1, thresh)) {
+ return false;
+ }
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+ o_vertex[1] = wv1.vertex[0];
+ o_vertex[2] = wv2.vertex[0];
+ o_vertex[3] = v1;
+ } else {
+ return false;
+ }
+ } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) {
+ // v2 = (v1-i_vertex1_index+ end_of_coord-i_vertex1_index) / 2+i_vertex1_index;
+ v2 = (v1 + end_of_coord) / 2;
+
+ if (!wv1.getVertex(i_x_coord, i_y_coord, v1, v2, thresh)) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v2, end_of_coord, thresh)) {
+ return false;
+ }
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+ o_vertex[1] = v1;
+ o_vertex[2] = wv1.vertex[0];
+ o_vertex[3] = wv2.vertex[0];
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ o_vertex[4] = end_of_coord;
+ return true;
+ }
+ /**
+ * QRコードのシンボル特徴を持つラベルであるかを調べる
+ * @param buf
+ * @param index_table
+ * @param i_label
+ * @return
+ */
+ private boolean hasQrEdgeFeature(int buf[][], int[] index_table, NyARLabelingLabel i_label)
+ {
+ int tx, bx;
+ int w;
+ int i_label_id = i_label.id;
+ int[] limage_j;
+ final int clip_l = i_label.clip_l;
+ final int clip_b = i_label.clip_b;
+ final int clip_r = i_label.clip_r;
+ final int clip_t = i_label.clip_t;
+
+ tx = bx = 0;
+ // 上接点(→)
+ limage_j = buf[clip_t];
+ for (int i = clip_l; i <= clip_r; i++) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {
+ w = limage_j[i];
+ if (w > 0 && index_table[w - 1] == i_label_id) {
+ tx = i;
+ break;
+ }
+ }
+ // 下接点(←)
+ limage_j = buf[clip_b];
+ for (int i = clip_r; i >= clip_l; i--) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {
+ w = limage_j[i];
+ if (w > 0 && index_table[w - 1] == i_label_id) {
+ bx = i;
+ break;
+ }
+ }
+ final int cx = (clip_l + clip_r) / 2;
+ final int cy = (clip_t + clip_b) / 2;
+ // 横断チェック(中心から線を引いて、010になるかしらべる)
+ if (!checkDiagonalLine(buf, cx, cy, bx, clip_b)) {
+ return false;
+ }
+ if (!checkDiagonalLine(buf, tx, clip_t, cx, cy)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * シンボルのパターン特徴を調べる関数
+ * 対角線の一部が010になってるか調べる。
+ *
+ * @param buf
+ * @param i_px1
+ * @param i_py1
+ * @param i_px2
+ * @param i_py2
+ * @return
+ */
+ private boolean checkDiagonalLine(int[][] buf, int i_px1, int i_py1, int i_px2, int i_py2)
+ {
+ int sub_y = i_py2 - i_py1;
+ int sub_x = i_px2 - i_px1;
+ // 黒
+ int i = 0;
+ for (; i < sub_y; i++) {
+ int yp = i_py1 + i;
+ int xp = i_px1 + i * sub_x / sub_y;
+ if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) {
+ break;
+ }
+
+ }
+ if (i == sub_y) {
+ return false;
+ }
+ // 白
+ for (; i < sub_y; i++) {
+ int yp = i_py1 + i;
+ int xp = i_px1 + i * sub_x / sub_y;
+ if (buf[yp][xp] != 0 && buf[yp][xp-1] != 0 && buf[yp][xp+1] != 0) {
+ break;
+ }
+
+ }
+ if (i == sub_y) {
+ return false;
+ }
+ // 黒
+ for (; i < sub_y; i++) {
+ int yp = i_py1 + i;
+ int xp = i_px1 + i * sub_x / sub_y;
+ if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) {
+ break;
+ }
+
+ }
+ if (i != sub_y) {
+ return false;
+ }
+ // 端まで到達したらOK
+ return true;
+ }
+
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARQrCodeSymbolBinder.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARQrCodeSymbolBinder.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARQrCodeSymbolBinder.java (revision 199)
@@ -0,0 +1,291 @@
+package jp.nyatla.nyartoolkit.sandbox.qrcode;
+
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+/**
+ * QRコードのシンボルを結びつける偉いクラス
+ * アルゴリズムはこんな感じ。
+ * 1.3シンボルの位置関係から中間のシンボルを探す。
+ * 2.中間シンボルの内角点を探す
+ * 3.残りの2シンボル間の最短距離の頂点セットを見つけて、それぞれの内角点を探す
+ * 4.3個の内角点が決まったら、各シンボルごとに外角点(反対側の頂点)を特定する。
+ * 5.対角のシンボルの外角頂点から伸びる線分を合成して、矩形を決める。
+ * 6.矩形が決まったら、方程式を解いて交点を出して、頂点にする。
+ * 7.交点と中央のシンボルの位置関係から、正しい計算が行われたかを判定(まだ実装してない)
+ *
+ *
+ * この方法は浅い角度でシンボル集合を見たときに、1や3の手順が高い確率で失敗する。
+ * その場合計算が途中で破綻するのでわかる(はず)
+ * 他の方法もあるけど、それはまた今度。
+ */
+public class NyARQrCodeSymbolBinder
+{
+ private NyARCameraDistortionFactor _distfactor;
+
+ public NyARQrCodeSymbolBinder(NyARCameraDistortionFactor i_ref_distortion)
+ {
+ this._distfactor=i_ref_distortion;
+ return;
+ }
+ /**
+ * 最小の三角形を構成する頂点セットを得る
+ * @param i_s0
+ * @param i_s1
+ * @param i_s2
+ * @param o_vertex
+ */
+ private static void getMinimumTriangleVertex(NyARSquare[] i_sqare,int[] o_vertex_id)
+ {
+ //辺の長さが最小になる頂点の組合せを探す
+ int d;
+ int x,y;
+ int dmax=0x7fffffff;
+ final NyARIntPoint[] vertex0=i_sqare[0].imvertex;
+ final NyARIntPoint[] vertex1=i_sqare[1].imvertex;
+ final NyARIntPoint[] vertex2=i_sqare[2].imvertex;
+ for(int i=0;i<4;i++)
+ {
+ for(int i2=0;i2<4;i2++)
+ {
+ for(int i3=0;i3<4;i3++){
+ x=vertex0[i].x-vertex2[i3].x;
+ y=vertex0[i].y-vertex2[i3].y;
+ d=x*x+y*y;
+ x=vertex1[i2].x-vertex2[i3].x;
+ y=vertex1[i2].y-vertex2[i3].y;
+ d+=x*x+y*y;
+ x=vertex1[i2].x-vertex0[i].x;
+ y=vertex1[i2].y-vertex0[i].y;
+ d+=x*x+y*y;
+ if(d<dmax){
+ dmax=d;
+ o_vertex_id[0]=i;
+ o_vertex_id[1]=i2;
+ o_vertex_id[2]=i3;
+ }
+ }
+ }
+ }
+ return;
+ }
+ /**
+ * 2矩形の頂点距離が最低の組合せを探す
+ * @param i_sqare
+ * @param o_vertex_id
+ */
+ private static void getMinimumLineVertex(NyARIntPoint[] i_sqare0,NyARIntPoint[] i_sqare1,int[] o_vertex_id)
+ {
+ //辺の長さが最小になる頂点の組合せを探す
+ int d;
+ int x,y;
+ int dmax=0x7fffffff;
+ for(int i=0;i<4;i++)
+ {
+ for(int i2=0;i2<4;i2++)
+ {
+ x=i_sqare1[i2].x-i_sqare0[i].x;
+ y=i_sqare1[i2].y-i_sqare0[i].y;
+ d=x*x+y*y;
+ if(d<dmax){
+ dmax=d;
+ o_vertex_id[0]=i;
+ o_vertex_id[1]=i2;
+ }
+ }
+ }
+ return;
+ }
+ /**
+ * シンボルグループの重心を計算する
+ * @param i_sqare
+ * @param i_center
+ */
+ private void getSymbolGroupCenter(NyARSquare[] i_sqare,NyARIntPoint i_center)
+ {
+ //シンボルグループの重心を計算
+ int cx,cy;
+ cx=cy=0;
+ for(int i=0;i<3;i++)
+ {
+ final NyARIntPoint[] sq_ptr=i_sqare[i].imvertex;
+ cx+=sq_ptr[0].x;
+ cx+=sq_ptr[1].x;
+ cx+=sq_ptr[2].x;
+ cx+=sq_ptr[3].x;
+ cy+=sq_ptr[0].y;
+ cy+=sq_ptr[1].y;
+ cy+=sq_ptr[2].y;
+ cy+=sq_ptr[3].y;
+ }
+ i_center.x=cx/12;
+ i_center.y=cy/12;
+ return;
+ }
+ /**
+ * キーシンボルのインデックスを得る
+ * @param i_sqare
+ * @param i_vertex_id
+ * 最小三角形の頂点IDセット
+ * @return
+ */
+ private static int getKeySymble(NyARSquare[] i_sqare,NyARIntPoint i_center,int[] i_vertex_id)
+ {
+ //シンボルグループの重心を計算
+ final int cx=i_center.x;
+ final int cy=i_center.y;
+ //前段で探した頂点候補のうち、最も重心に近いものが中心シンボルの内対角点
+ int key_symble_idx=0;
+ int x=i_sqare[0].imvertex[i_vertex_id[0]].x-cx;
+ int y=i_sqare[0].imvertex[i_vertex_id[0]].y-cy;
+ int dmax=x*x+y*y;
+ for(int i=1;i<3;i++){
+ x=i_sqare[i].imvertex[i_vertex_id[i]].x-cx;
+ y=i_sqare[i].imvertex[i_vertex_id[i]].y-cy;
+ final int d=x*x+y*y;
+ if(d<dmax){
+ dmax=d;
+ key_symble_idx=i;
+ }
+ }
+ return key_symble_idx;
+ }
+ private NyARDoublePoint2d __bindSquare_ideal_vertex=new NyARDoublePoint2d();
+ /**
+ * 2つの対角にある矩形から、それらを対角とする矩形を作る。
+ * @param i_sq1
+ * @param i_lv1
+ * @param i_sq2
+ * @param i_lv2
+ */
+ private void bindSquare(NyARSquare i_sq1,int i_lv1,NyARSquare i_sq2,int i_lv2,NyARSquare o_qr_square)
+ {
+ //4辺の式を計算
+ o_qr_square.line[0].copyFrom(i_sq1.line[(i_lv1+3)%4]);
+ o_qr_square.line[1].copyFrom(i_sq1.line[(i_lv1+0)%4]);
+ o_qr_square.line[2].copyFrom(i_sq2.line[(i_lv2+3)%4]);
+ o_qr_square.line[3].copyFrom(i_sq2.line[(i_lv2+0)%4]);
+ //歪み無しの座標系を計算
+ final NyARDoublePoint2d[] l_sqvertex = o_qr_square.sqvertex;
+ final NyARIntPoint[] imvertex_ptr = o_qr_square.imvertex;
+
+ final NyARLinear[] l_line = o_qr_square.line;
+ final NyARDoublePoint2d ideal_vertex=this.__bindSquare_ideal_vertex;
+ for (int i = 0; i < 4; i++) {
+ final NyARLinear l_line_i = l_line[i];
+ final NyARLinear l_line_2 = l_line[(i + 3) % 4];
+ final double w1 = l_line_2.run * l_line_i.rise - l_line_i.run * l_line_2.rise;
+ if (w1 == 0.0) {
+ return;
+ }
+ l_sqvertex[i].x = (l_line_2.rise * l_line_i.intercept - l_line_i.rise * l_line_2.intercept) / w1;
+ l_sqvertex[i].y = (l_line_i.run * l_line_2.intercept - l_line_2.run * l_line_i.intercept) / w1;
+ _distfactor.ideal2Observ(l_sqvertex[i], ideal_vertex);
+ //Ideal→observに変換して、画面上の座標とする。
+ imvertex_ptr[i].x=(int)l_sqvertex[i].x;
+ imvertex_ptr[i].y=(int)l_sqvertex[i].y;
+ }
+// Graphics g=this.bimg.getGraphics();
+// g.setColor(Color.red);
+// int[] x=new int[4];
+// int[] y=new int[4];
+// for(int i=0;i<4;i++){
+// x[i]=(int)l_sqvertex[i].x;
+// y[i]=(int)l_sqvertex[i].y;
+// }
+// g.drawPolygon(x,y,4);
+ return;
+ //基準点はVertexをそのまま採用
+ //2個の想定点は座標を逆変換して設定
+ }
+ /**
+ * directionはキーシンボルのインデックスでARToolKitの頂点座標じゃないので注意すること。
+ * @param i_sq
+ * @param o_sq
+ * @return
+ */
+ public boolean composeSquare(NyARSquare[] i_sq,NyARSquare o_sq)
+ {
+ int[] minimum_triangle_vertex=new int[3];
+ int[] minimum_line_vertex=new int[2];
+
+ NyARIntPoint center=new NyARIntPoint();
+
+ //辺の長さが最小になる頂点の組合せを探す
+ getMinimumTriangleVertex(i_sq,minimum_triangle_vertex);
+
+ //中心位置を計算する。
+ getSymbolGroupCenter(i_sq,center);
+
+ //キーシンボルのインデクス番号を得る
+ int key_simble_idx=getKeySymble(i_sq,center,minimum_triangle_vertex);
+
+ //対角シンボルのインデックス番号を決める
+ int symbol_e1_idx=(key_simble_idx+1)%3;
+ int symbol_e2_idx=(key_simble_idx+2)%3;
+
+ //対角シンボル間で最短距離を取る頂点ペアを取る
+ //(角度を低くするとエラーが出やすい。対角線との類似性を確認する方法のほうがいい。多分)
+ getMinimumLineVertex(i_sq[symbol_e1_idx].imvertex,i_sq[symbol_e2_idx].imvertex,minimum_line_vertex);
+
+ //内対角を外対角に変換
+ int lv1=(minimum_line_vertex[0]+2)%4;
+ int lv2=(minimum_line_vertex[1]+2)%4;
+ int kv =(minimum_triangle_vertex[key_simble_idx]+2)%4;
+ //矩形の合成
+ bindSquare(i_sq[symbol_e1_idx],lv1,i_sq[symbol_e2_idx],lv2,o_sq);
+
+ //方位判定
+ int direction=getDirection(o_sq,i_sq[key_simble_idx].imvertex[kv],center);
+ if(direction==-1){
+ return false;
+ }
+ o_sq.direction=direction;
+
+ return true;
+ }
+ /**
+ * この関数はあんまり頂点ズレがひどいと失敗する
+ * @param i_square
+ * @param i_vertex
+ * @param i_center
+ * @return
+ */
+ private int getDirection(NyARSquare i_square,NyARIntPoint i_vertex,NyARIntPoint i_center)
+ {
+ //開始点(中央シンボル)までの頂点のシフト数を決める
+ int x,y;
+ x=i_square.imvertex[0].x-i_vertex.x;
+ y=i_square.imvertex[0].y-i_vertex.y;
+ int v1=x*x+y*y;
+ x=i_square.imvertex[2].x-i_vertex.x;
+ y=i_square.imvertex[2].y-i_vertex.y;
+ int v2=x*x+y*y;
+ int shift;
+ int v;
+ if(v1<v2){
+ shift=0;
+ v=v1;
+ }else{
+ shift=2;
+ v=v2;
+ }
+ //小さい方の対角線が64(8x8)より大きくずれてたら認識ミスとみなす
+ if(v>64){
+ return -1;
+ }
+ //シンボルがどの象限にあるか確認する
+ x=i_vertex.x=i_center.x;
+ y=i_vertex.y=i_center.y;
+ int dir;
+ if(x<0){
+ dir=2;//dir=y<0?1:2;
+ }else{
+ dir=4;//dir=y<0?3:4;
+ }
+ return (dir+shift)%4;
+ }
+
+
+
+}
\ No newline at end of file
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/SingleQrTest.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/SingleQrTest.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/SingleQrTest.java (revision 199)
@@ -0,0 +1,177 @@
+/* このソースは実験用のソースです。
+ * 動いたり動かなかったりします。
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.qrcode;
+
+import javax.media.*;
+
+import javax.media.util.BufferToImage;
+import javax.media.format.*;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.jmf.utils.*;
+
+import jp.nyatla.nyartoolkit.core.*;
+
+import java.awt.*;
+
+import jp.nyatla.nyartoolkit.core.labeling.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.rasterfilter.*;
+import jp.nyatla.nyartoolkit.core2.rasterfilter.rgb2gs.*;
+import jp.nyatla.nyartoolkit.core2.rasterfilter.gs2bin.*;
+import jp.nyatla.utils.j2se.LabelingBufferdImage;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core2.rasteranalyzer.threshold.*;
+
+
+
+public class SingleQrTest extends Frame implements JmfCaptureListener
+{
+ private final String camera_file = "../../Data/camera_para.dat";
+
+ private JmfNyARRaster_RGB _raster;
+
+ private JmfCameraCapture capture;
+ private NyARParam ap;
+ public SingleQrTest() throws NyARException, NyARException
+ {
+ setBounds(0, 0, 640 + 64, 720 + 64);
+ // キャプチャの準備
+ capture = new JmfCameraCapture(320, 240, 30f, JmfCameraCapture.PIXEL_FORMAT_RGB);
+ capture.setCaptureListener(this);
+
+ // キャプチャイメージ用のラスタを準備
+ this._raster = new JmfNyARRaster_RGB(320, 240);
+
+ // AR用カメラパラメタファイルをロード
+ ap = new NyARParam();
+ ap.loadARParamFromFile(camera_file);
+ ap.changeScreenSize(320, 240);
+
+
+ }
+
+ private NyARBinRaster _binraster1 = new NyARBinRaster(320, 240);
+
+ private NyARGrayscaleRaster _gsraster1 = new NyARGrayscaleRaster(320, 240);
+ private INyARRasterThresholdAnalyzer _tha=new NyARRasterThresholdAnalyzer_DiffHistgram();
+
+ private LabelingBufferdImage _bimg = new LabelingBufferdImage(320, 240);
+
+
+ public void onUpdateBuffer(Buffer i_buffer)
+ {
+
+ try {
+ // キャプチャしたバッファをラスタにセット
+ _raster.setBuffer(i_buffer);
+
+ Graphics g = getGraphics();
+ // キャプチャ画像
+ BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());
+ Image img = b2i.createImage(i_buffer);
+ this.getGraphics().drawImage(img, 32, 32, this);
+
+ // 画像1
+ INyARRasterFilter_RgbToGs filter_rgb2gs = new NyARRasterFilter_RgbAve();
+// INyARRasterFilter_RgbToGs filter_rgb2gs = new NyARRasterFilter_RgbMul();
+
+ filter_rgb2gs.doFilter(_raster, _gsraster1);
+ this._bimg.drawImage(this._gsraster1);
+ this.getGraphics().drawImage(this._bimg, 32 + 320, 32, 320 + 320 + 32, 240 + 32, 0, 240, 320, 0, this);
+ _tha.analyzeRaster(_gsraster1);
+ NyARRasterFilter_Threshold gs2bin=new NyARRasterFilter_Threshold(_tha.getThreshold());
+
+
+ // 画像2
+ gs2bin.doFilter(_gsraster1, _binraster1);
+ this._bimg.drawImage(_binraster1);
+ this.getGraphics().drawImage(this._bimg, 32, 32 + 240, 320 + 32, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+ // 画像3
+ NyARLabelingImage limage = new NyARLabelingImage(320, 240);
+ NyARLabeling_ARToolKit labeling = new NyARLabeling_ARToolKit();
+ labeling.attachDestination(limage);
+ labeling.labeling(_binraster1);
+ this._bimg.drawImage(this._gsraster1);
+
+ NyARSquareStack stack = new NyARSquareStack(100);
+ NyARQrCodeDetector detect = new NyARQrCodeDetector(ap.getDistortionFactor(), new NyARIntSize(320,240));
+// detect.bimg=this._bimg;
+
+ detect.detectMarker(_binraster1, stack);
+ for (int i = 0; i < stack.getLength(); i++) {
+ NyARSquare[] square_ptr = (NyARSquare[]) stack.getArray();
+ int d=square_ptr[i].direction;
+ int[] xp=new int[4];
+ int[] yp=new int[4];
+ for(int i2=0;i2<4;i2++){
+ xp[i2]=square_ptr[i].imvertex[(i2+d)%4].x;
+ yp[i2]=square_ptr[i].imvertex[(i2+d)%4].y;
+ }
+ Graphics g2=this._bimg.getGraphics();
+ g2.setColor(Color.RED);
+ g2.drawPolygon(xp, yp,3);
+ g2.setColor(Color.CYAN);
+ g2.drawRect(square_ptr[i].imvertex[d].x, square_ptr[i].imvertex[d].y,5,5);
+ }
+ this.getGraphics().drawImage(this._bimg, 32 + 320, 32 + 240, 320 + 32 + 320, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+ // 画像3
+ // threshold.debugDrawHistgramMap(_workraster, _workraster2);
+ // this._bimg2.setImage(this._workraster2);
+ // this.getGraphics().drawImage(this._bimg2, 32+320, 32+240,320+32+320,240+32+240,0,240,320,0, this);
+
+ // 画像4
+ // NyARRasterThresholdAnalyzer_SlidePTile threshold=new NyARRasterThresholdAnalyzer_SlidePTile(15);
+ // threshold.analyzeRaster(_gsraster1);
+ // filter_gs2bin=new NyARRasterFilter_AreaAverage();
+ // filter_gs2bin.doFilter(_gsraster1, _binraster1);
+ // this._bimg.drawImage(_binraster1);
+
+ // NyARRasterDetector_QrCodeEdge detector=new NyARRasterDetector_QrCodeEdge(10000);
+ // detector.analyzeRaster(_binraster1);
+
+ // this._bimg.overlayData(detector.geResult());
+
+ // this.getGraphics().drawImage(this._bimg, 32, 32+480,320+32,480+32+240,0,240,320,0, this);
+ // 画像5
+
+ /*
+ * threshold2.debugDrawHistgramMap(_workraster, _workraster2); this._bimg2.drawImage(this._workraster2); this.getGraphics().drawImage(this._bimg2,
+ * 32+320, 32+480,320+32+320,480+32+240,0,240,320,0, this);
+ */
+
+ // this.getGraphics().drawImage(this._bimg, 32, 32, this);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ private void startCapture()
+ {
+ try {
+ capture.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ try {
+ SingleQrTest mainwin = new SingleQrTest();
+ mainwin.setVisible(true);
+ mainwin.startCapture();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARRasterFilter_QrAreaAverage.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARRasterFilter_QrAreaAverage.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARRasterFilter_QrAreaAverage.java (revision 199)
@@ -0,0 +1,89 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.qrcode;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.rasterfilter.INyARRasterFilter_GsToBin;
+import jp.nyatla.nyartoolkit.core.types.*;
+
+/**
+ * 平均移動法を使った2値化フィルタ
+ *
+ */
+public class NyARRasterFilter_QrAreaAverage implements INyARRasterFilter_GsToBin
+{
+ private int _area = 8;
+
+ public void doFilter(NyARGrayscaleRaster i_input, NyARBinRaster i_output) throws NyARException
+ {
+ final NyARIntSize size = i_output.getSize();
+ final int[][] out_buf = (int[][]) i_output.getBufferReader().getBuffer();
+ final int[][] in_buf = (int[][]) i_input.getBufferReader().getBuffer();
+ assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);
+ assert (size.h % 8 == 0 && size.w % 8 == 0);//暫定実装なので。
+
+ final int area = this._area;
+ int y1 = area;
+ int x1 = area;
+ int y2 = size.h - area;
+ int x2 = size.w - area;
+
+ for (int y = y1; y < y2; y++) {
+ int sum, nn;
+ sum = nn = 0;
+ for (int yy = y - area; yy < y + area + 1; yy++) {
+ for (int xx = x1 - area; xx < x1 + area; xx++) {
+ sum += in_buf[yy][xx];
+ nn++;
+ }
+ }
+ int th;
+ boolean first = true;
+ th=0;
+ for (int x = area; x < x2; x++) {
+ if (!first) {
+ for (int yy = y - area; yy < y + area; yy++) {
+ sum += in_buf[yy][x + area];
+ sum -= in_buf[yy][x - area];
+ }
+ }
+ first = false;
+ th = (sum / nn);
+ int g = in_buf[y][x];
+ out_buf[y][x] = th < g ? 1 : 0;
+ }
+ }
+ return;
+ }
+
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/SingleQrSample.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/SingleQrSample.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/SingleQrSample.java (revision 199)
@@ -0,0 +1,241 @@
+/*
+ * PROJECT: NyARToolkit JOGL sample program.
+ * --------------------------------------------------------------------------------
+ * The MIT License
+ * Copyright (c) 2008 nyatla
+ * airmail(at)ebony.plala.or.jp
+ * http://nyatla.jp/nyartoolkit/
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.qrcode;
+
+import java.awt.event.*;
+import java.awt.*;
+import javax.media.Buffer;
+import javax.media.opengl.*;
+import com.sun.opengl.util.*;
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.transmat.*;
+import jp.nyatla.nyartoolkit.jmf.utils.*;
+import jp.nyatla.nyartoolkit.jogl.utils.*;
+/**
+ * QRコードをマーカーの代わりに使うサンプルプログラム。
+ * 頂点と方位は認識できるけど、QRコードのデコードはしてません。
+ *
+ */
+public class SingleQrSample implements GLEventListener, JmfCaptureListener
+{
+ private final String CARCODE_FILE = "../../Data/patt.hiro";
+
+ private final String PARAM_FILE = "../../Data/camera_para.dat";
+
+ private final static int SCREEN_X = 320;
+
+ private final static int SCREEN_Y = 240;
+
+ private Animator _animator;
+
+ private GLNyARRaster_RGB _cap_image;
+
+ private JmfCameraCapture _capture;
+
+ private GL _gl;
+ private NyARGLUtil _glnya;
+
+ //NyARToolkit関係
+ private NyARSingleQrDetector _nya;
+ private NyARParam _ar_param;
+
+ private double[] _camera_projection=new double[16];
+
+ /**
+ * 立方体を書く
+ *
+ */
+ void drawCube()
+ {
+ // Colour cube data.
+ int polyList = 0;
+ float fSize = 0.5f;//マーカーサイズに対して0.5倍なので、4cmの立方体
+ int f, i;
+ float[][] cube_vertices = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f } };
+ float[][] cube_vertex_colors = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };
+ int cube_num_faces = 6;
+ short[][] cube_faces = new short[][] { { 3, 2, 1, 0 }, { 2, 3, 7, 6 }, { 0, 1, 5, 4 }, { 3, 0, 4, 7 }, { 1, 2, 6, 5 }, { 4, 5, 6, 7 } };
+
+ if (polyList == 0) {
+ polyList = _gl.glGenLists(1);
+ _gl.glNewList(polyList, GL.GL_COMPILE);
+ _gl.glBegin(GL.GL_QUADS);
+ for (f = 0; f < cube_num_faces; f++)
+ for (i = 0; i < 4; i++) {
+ _gl.glColor3f(cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]);
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);
+ }
+ _gl.glEnd();
+ _gl.glColor3f(0.0f, 0.0f, 0.0f);
+ for (f = 0; f < cube_num_faces; f++) {
+ _gl.glBegin(GL.GL_LINE_LOOP);
+ for (i = 0; i < 4; i++)
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);
+ _gl.glEnd();
+ }
+ _gl.glEndList();
+ }
+
+ _gl.glPushMatrix(); // Save world coordinate system.
+ _gl.glTranslatef(0.0f, 0.0f, 0.5f); // Place base of cube on marker surface.
+ _gl.glRotatef(0.0f, 0.0f, 0.0f, 1.0f); // Rotate about z axis.
+ _gl.glDisable(GL.GL_LIGHTING); // Just use colours.
+ _gl.glCallList(polyList); // Draw the cube.
+ _gl.glPopMatrix(); // Restore world coordinate system.
+
+ }
+
+ public SingleQrSample()
+ {
+ Frame frame = new Frame("SingleQrSample");
+
+ // 3Dを描画するコンポーネント
+ GLCanvas canvas = new GLCanvas();
+ frame.add(canvas);
+ canvas.addGLEventListener(this);
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e)
+ {
+ System.exit(0);
+ }
+ });
+
+ frame.setVisible(true);
+ Insets ins = frame.getInsets();
+ frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);
+ canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);
+ }
+
+ public void init(GLAutoDrawable drawable)
+ {
+ _gl = drawable.getGL();
+ _gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ //NyARToolkitの準備
+ try {
+ //キャプチャの準備
+ _capture = new JmfCameraCapture(SCREEN_X, SCREEN_Y, 15f, JmfCameraCapture.PIXEL_FORMAT_RGB);
+ _capture.setCaptureListener(this);
+ //NyARToolkitの準備
+ _ar_param = new NyARParam();
+ NyARCode ar_code = new NyARCode(16, 16);
+ _ar_param.loadARParamFromFile(PARAM_FILE);
+ _ar_param.changeScreenSize(SCREEN_X, SCREEN_Y);
+ _nya = new NyARSingleQrDetector(_ar_param,80);
+ _nya.setContinueMode(false);//ここをtrueにすると、transMatContinueモード(History計算)になります。
+ ar_code.loadARPattFromFile(CARCODE_FILE);
+ //NyARToolkit用の支援クラス
+ _glnya = new NyARGLUtil(_gl);
+ //GL対応のRGBラスタオブジェクト
+ _cap_image = new GLNyARRaster_RGB(_ar_param);
+ //キャプチャ開始
+ _capture.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ //カメラパラメータの計算
+ _glnya.toCameraFrustumRH(_ar_param,_camera_projection);
+
+ _animator = new Animator(drawable);
+ _animator.start();
+ return;
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
+ {
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ _gl.glViewport(0, 0, width, height);
+
+ //視体積の設定
+ _gl.glMatrixMode(GL.GL_PROJECTION);
+ _gl.glLoadIdentity();
+ //見る位置
+ _gl.glMatrixMode(GL.GL_MODELVIEW);
+ _gl.glLoadIdentity();
+ }
+ private NyARTransMatResult __display_transmat_result=new NyARTransMatResult();
+ private double[] __display_wk=new double[16];
+
+ public void display(GLAutoDrawable drawable)
+ {
+ NyARTransMatResult transmat_result=__display_transmat_result;
+ try {
+ if (!_cap_image.hasData()) {
+ return;
+ }
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.
+ //画像チェックしてマーカー探して、背景を書く
+ boolean is_marker_exist;
+ synchronized (_cap_image) {
+ is_marker_exist = _nya.detectMarkerLite(_cap_image, 0);
+ //背景を書く
+ _glnya.drawBackGround(_cap_image, 1.0);
+ }
+ //マーカーがあれば、立方体を描画
+ if (is_marker_exist) {
+ //マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。
+ // Projection transformation.
+ _gl.glMatrixMode(GL.GL_PROJECTION);
+ _gl.glLoadMatrixd(_camera_projection, 0);
+ _gl.glMatrixMode(GL.GL_MODELVIEW);
+ // Viewing transformation.
+ _gl.glLoadIdentity();
+ //変換行列を取得
+ _nya.getTransmationMatrix(transmat_result);
+ //変換行列をOpenGL形式に変換
+ _glnya.toCameraViewRH(transmat_result, __display_wk);
+ _gl.glLoadMatrixd(__display_wk, 0);
+
+ // All other lighting and geometry goes here.
+ drawCube();
+ }
+ Thread.sleep(1);//タスク実行権限を一旦渡す
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+ public void onUpdateBuffer(Buffer i_buffer)
+ {
+ try {
+ synchronized (_cap_image) {
+ _cap_image.setBuffer(i_buffer, true);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)
+ {
+ }
+
+ public static void main(String[] args)
+ {
+ new SingleQrSample();
+ }
+}
Index: trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARSingleQrDetector.java
===================================================================
--- trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARSingleQrDetector.java (revision 0)
+++ trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARSingleQrDetector.java (revision 199)
@@ -0,0 +1,156 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.qrcode;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.core.param.NyARParam;
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;
+import jp.nyatla.nyartoolkit.core.rasterfilter.*;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.transmat.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core2.rasterfilter.rgb2gs.*;
+
+/**
+ * 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。
+ *
+ */
+public class NyARSingleQrDetector
+{
+ private static final int AR_SQUARE_MAX = 100;
+
+ private boolean _is_continue = false;
+ private INyARSquareDetector _square_detect;
+
+ private final NyARSquareStack _square_list = new NyARSquareStack(AR_SQUARE_MAX);
+
+ protected INyARTransMat _transmat;
+
+ private double _marker_width;
+
+ // 検出結果の保存用
+ private NyARSquare _detected_square;
+
+
+ /**
+ * 検出するARCodeとカメラパラメータから、1個のARCodeを検出するNyARSingleDetectMarkerインスタンスを作ります。
+ *
+ * @param i_param
+ * カメラパラメータを指定します。
+ * @param i_marker_width
+ * ARコードの物理サイズを、ミリメートルで指定します。
+ * @throws NyARException
+ */
+ public NyARSingleQrDetector(NyARParam i_param, double i_marker_width) throws NyARException
+ {
+ final NyARIntSize scr_size=i_param.getScreenSize();
+ // 解析オブジェクトを作る
+ this._square_detect = new NyARQrCodeDetector(i_param.getDistortionFactor(),scr_size);
+ this._transmat = new NyARTransMat(i_param);
+ this._marker_width = i_marker_width;
+ //2値画像バッファを作る
+ this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);
+ //中間のグレースケール画像のバッファを作る
+ this._gs_raster=new NyARGrayscaleRaster(scr_size.w,scr_size.h);
+ }
+ private NyARBinRaster _bin_raster;
+ private NyARGrayscaleRaster _gs_raster;
+ //画処理フィルター
+ private INyARRasterFilter_RgbToGs _rgb2gs_filter=new NyARRasterFilter_RgbAve();
+ private INyARRasterFilter_GsToBin _gstobin_filter=new NyARRasterFilter_QrAreaAverage();
+
+ /**
+ * i_imageにマーカー検出処理を実行し、結果を記録します。
+ *
+ * @param i_raster
+ * マーカーを検出するイメージを指定します。イメージサイズは、カメラパラメータ
+ * と一致していなければなりません。
+ * @return マーカーが検出できたかを真偽値で返します。
+ * @throws NyARException
+ */
+ public boolean detectMarkerLite(INyARRgbRaster i_raster,int i_threshold) throws NyARException
+ {
+ //サイズチェック
+ if(!this._bin_raster.getSize().isEqualSize(i_raster.getSize())){
+ throw new NyARException();
+ }
+ //グレースケールに変換
+ this._rgb2gs_filter.doFilter(i_raster, this._gs_raster);
+ //2値イメージに変換
+ this._gstobin_filter.doFilter(this._gs_raster, this._bin_raster);
+
+ this._detected_square = null;
+ NyARSquareStack l_square_list = this._square_list;
+ // スクエアコードを探す
+ this._square_detect.detectMarker(this._bin_raster, l_square_list);
+ //変換する
+
+
+ int number_of_square = l_square_list.getLength();
+ // コードは見つかった?
+ if (number_of_square < 1) {
+ return false;
+ }
+ this._detected_square=(NyARSquare)l_square_list.getItem(0);
+ return true;
+ }
+
+ /**
+ * 検出したマーカーの変換行列を計算して、o_resultへ値を返します。
+ * 直前に実行したdetectMarkerLiteが成功していないと使えません。
+ *
+ * @param o_result
+ * 変換行列を受け取るオブジェクトを指定します。
+ * @throws NyARException
+ */
+ public void getTransmationMatrix(NyARTransMatResult o_result) throws NyARException
+ {
+ // 一番一致したマーカーの位置とかその辺を計算
+ if (this._is_continue) {
+ this._transmat.transMatContinue(this._detected_square,this._detected_square.direction,this._marker_width, o_result);
+ } else {
+ this._transmat.transMat(this._detected_square,this._detected_square.direction,this._marker_width, o_result);
+ }
+ return;
+ }
+ /**
+ * getTransmationMatrixの計算モードを設定します。 初期値はTRUEです。
+ *
+ * @param i_is_continue
+ * TRUEなら、transMatCont互換の計算をします。 FALSEなら、transMat互換の計算をします。
+ */
+ public void setContinueMode(boolean i_is_continue)
+ {
+ this._is_continue = i_is_continue;
+ }
+}
Index: trunk/readme.ja.txt
===================================================================
--- trunk/readme.ja.txt (revision 162)
+++ trunk/readme.ja.txt (revision 199)
@@ -1,7 +1,7 @@
ARToolKit Java class library NyARToolkit.
Copyright (C)2008 R.Iizuka
-version 2.0.0
+version 2.1.0
http://nyatla.jp/nyartoolkit/
airmail(at)ebony.plala.or.jp
@@ -10,13 +10,14 @@
-・NyARToolkit/2.0
+・NyARToolkit/2.1
NyARToolkitは、Pure Javaで実装したARToolKitクラスライブラリです。
ARToolKit 2.72.1をベースに構築されています。
-NyARToolkit/1.xと比較し、構造的な最適化がされ、可読性が向上しています。
+NyARToolkit/2.0系は、NyARToolkit/1.xと比較して構造的な最適化がされており、
+可読性と分離性が向上しています。
Index: trunk/src.utils/jogl/.classpath
===================================================================
--- trunk/src.utils/jogl/.classpath (revision 162)
+++ trunk/src.utils/jogl/.classpath (revision 199)
@@ -4,8 +4,8 @@
<classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/>
<classpathentry path="/NyARToolKit" combineaccessrules="false" kind="src"/>
<classpathentry path="/NyARToolkit.utils.jmf" combineaccessrules="false" kind="src"/>
- <classpathentry path="C:/Program Files/Java/jogl/lib/gluegen-rt.jar" kind="lib"/>
- <classpathentry path="C:/Program Files/Java/jogl/lib/jogl.jar" kind="lib"/>
<classpathentry path="C:/Program Files/JMF2.1.1e/lib/jmf.jar" kind="lib"/>
+ <classpathentry path="C:/Program Files/Java/jre1.6.0_03/lib/gluegen-rt.jar" kind="lib"/>
+ <classpathentry path="C:/Program Files/Java/jre1.6.0_03/lib/jogl.jar" kind="lib"/>
<classpathentry path="" kind="output"/>
</classpath>
Index: trunk/src.utils/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARDetectMarker.java
===================================================================
--- trunk/src.utils/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARDetectMarker.java (revision 162)
+++ trunk/src.utils/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARDetectMarker.java (revision 199)
@@ -1,95 +0,0 @@
-/*
- * PROJECT: NyARToolkit JOGL utilities.
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- * Hirokazu Kato
- * Mark Billinghurst
- * HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * The NyARToolkit is Java version ARToolkit class library.
- * Copyright (C)2008 R.Iizuka
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this framework; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * For further information please contact.
- * http://nyatla.jp/nyatoolkit/
- * <airmail(at)ebony.plala.or.jp>
- *
- */
-package jp.nyatla.nyartoolkit.jogl.utils;
-
-import jp.nyatla.nyartoolkit.NyARException;
-import jp.nyatla.nyartoolkit.core.NyARCode;
-import jp.nyatla.nyartoolkit.core.param.NyARParam;
-import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;
-import jp.nyatla.nyartoolkit.detector.NyARDetectMarker;
-
-/**
- * NyARSingleDetectMarkerにOpenGL向け関数を追加したもの
- */
-public class GLNyARDetectMarker extends NyARDetectMarker
-{
- private NyARTransMatResult trans_mat_result = new NyARTransMatResult();
-
- private double view_scale_factor = 0.025;
-
- public GLNyARDetectMarker(NyARParam i_param, NyARCode[] i_code, double[] i_marker_width, int i_number_of_code) throws NyARException
- {
- super(i_param, i_code, i_marker_width, i_number_of_code);
- }
-
- public void setScaleFactor(double i_new_value)
- {
- view_scale_factor = i_new_value;
- }
-
- /**
- * @param i_index
- * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
- * @param o_result
- * 結果値を格納する配列を指定してください。double[16]以上が必要です。
- * @throws NyARException
- */
- public void getCameraViewRH(int i_index, double[] o_result) throws NyARException
- {
- // 座標を計算
- this.getTransmationMatrix(i_index, this.trans_mat_result);
- // 行列変換
- final NyARTransMatResult mat = this.trans_mat_result;
- o_result[0 + 0 * 4] = mat.m00;
- o_result[0 + 1 * 4] = mat.m01;
- o_result[0 + 2 * 4] = mat.m02;
- o_result[0 + 3 * 4] = mat.m03;
- o_result[1 + 0 * 4] = -mat.m10;
- o_result[1 + 1 * 4] = -mat.m11;
- o_result[1 + 2 * 4] = -mat.m12;
- o_result[1 + 3 * 4] = -mat.m13;
- o_result[2 + 0 * 4] = -mat.m20;
- o_result[2 + 1 * 4] = -mat.m21;
- o_result[2 + 2 * 4] = -mat.m22;
- o_result[2 + 3 * 4] = -mat.m23;
- o_result[3 + 0 * 4] = 0.0;
- o_result[3 + 1 * 4] = 0.0;
- o_result[3 + 2 * 4] = 0.0;
- o_result[3 + 3 * 4] = 1.0;
- if (view_scale_factor != 0.0) {
- o_result[12] *= view_scale_factor;
- o_result[13] *= view_scale_factor;
- o_result[14] *= view_scale_factor;
- }
- return;
- }
-}
Index: trunk/src.utils/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARSingleDetectMarker.java
===================================================================
--- trunk/src.utils/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARSingleDetectMarker.java (revision 162)
+++ trunk/src.utils/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARSingleDetectMarker.java (revision 199)
@@ -1,103 +0,0 @@
-/*
- * PROJECT: NyARToolkit JOGL utilities.
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- * Hirokazu Kato
- * Mark Billinghurst
- * HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * The NyARToolkit is Java version ARToolkit class library.
- * Copyright (C)2008 R.Iizuka
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this framework; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * For further information please contact.
- * http://nyatla.jp/nyatoolkit/
- * <airmail(at)ebony.plala.or.jp>
- *
- */
-package jp.nyatla.nyartoolkit.jogl.utils;
-
-import jp.nyatla.nyartoolkit.NyARException;
-import jp.nyatla.nyartoolkit.core.NyARCode;
-import jp.nyatla.nyartoolkit.core.param.NyARParam;
-import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;
-import jp.nyatla.nyartoolkit.detector.NyARSingleDetectMarker;
-
-
-/**
- * NyARSingleDetectMarkerにOpenGL向け関数を追加したもの
- */
-public class GLNyARSingleDetectMarker extends NyARSingleDetectMarker
-{
- private NyARTransMatResult trans_mat_result = new NyARTransMatResult();
-
- private double view_scale_factor = 0.025;// #define VIEW_SCALEFACTOR 0.025 // 1.0 ARToolKit unit becomes 0.025 of my OpenGL units.
-
- public GLNyARSingleDetectMarker(NyARParam i_param, NyARCode i_code, double i_marker_width) throws NyARException
- {
- super(i_param, i_code, i_marker_width);
- }
-
- public void setScaleFactor(double i_new_value)
- {
- view_scale_factor = i_new_value;
- }
-
- // public static void arglCameraViewRH(const double para[3][4], GLdouble m_modelview[16], const double scale)
- public double[] getCameraViewRH() throws NyARException
- {
- double[] result = new double[16];
- getCameraViewRH(result);
- return result;
- }
-
- /**
- *
- * @param o_result
- * 結果値を格納する配列を指定してください。double[16]以上が必要です。
- * @throws NyARException
- */
- public void getCameraViewRH(double[] o_result) throws NyARException
- {
- // 座標を計算
- this.getTransmationMatrix(this.trans_mat_result);
- // 行列変換
- final NyARTransMatResult mat = this.trans_mat_result;
- o_result[0 + 0 * 4] = mat.m00; // R1C1
- o_result[0 + 1 * 4] = mat.m01; // R1C2
- o_result[0 + 2 * 4] = mat.m02;
- o_result[0 + 3 * 4] = mat.m03;
- o_result[1 + 0 * 4] = -mat.m10; // R2
- o_result[1 + 1 * 4] = -mat.m11;
- o_result[1 + 2 * 4] = -mat.m12;
- o_result[1 + 3 * 4] = -mat.m13;
- o_result[2 + 0 * 4] = -mat.m20; // R3
- o_result[2 + 1 * 4] = -mat.m21;
- o_result[2 + 2 * 4] = -mat.m22;
- o_result[2 + 3 * 4] = -mat.m23;
- o_result[3 + 0 * 4] = 0.0;
- o_result[3 + 1 * 4] = 0.0;
- o_result[3 + 2 * 4] = 0.0;
- o_result[3 + 3 * 4] = 1.0;
- if (view_scale_factor != 0.0) {
- o_result[12] *= view_scale_factor;
- o_result[13] *= view_scale_factor;
- o_result[14] *= view_scale_factor;
- }
- return;
- }
-}
Index: trunk/src.utils/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARParam.java
===================================================================
--- trunk/src.utils/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARParam.java (revision 162)
+++ trunk/src.utils/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARParam.java (revision 199)
@@ -1,127 +0,0 @@
-/*
- * PROJECT: NyARToolkit JOGL utilities.
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- * Hirokazu Kato
- * Mark Billinghurst
- * HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * The NyARToolkit is Java version ARToolkit class library.
- * Copyright (C)2008 R.Iizuka
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this framework; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * For further information please contact.
- * http://nyatla.jp/nyatoolkit/
- * <airmail(at)ebony.plala.or.jp>
- *
- */
-package jp.nyatla.nyartoolkit.jogl.utils;
-
-import jp.nyatla.nyartoolkit.core.*;
-import jp.nyatla.nyartoolkit.core.param.NyARParam;
-
-/**
- * NyARParamにOpenGL向け関数を追加したもの
- */
-public class GLNyARParam extends NyARParam
-{
- private double view_distance_min = 0.1;//#define VIEW_DISTANCE_MIN 0.1 // Objects closer to the camera than this will not be displayed.
-
- private double view_distance_max = 100.0;//#define VIEW_DISTANCE_MAX 100.0 // Objects further away from the camera than this will not be displayed.
-
- private double[] m_projection = null;
-
- public void setViewDistanceMin(double i_new_value)
- {
- m_projection = null;//キャッシュ済変数初期化
- view_distance_min = i_new_value;
- }
-
- public void setViewDistanceMax(double i_new_value)
- {
- m_projection = null;//キャッシュ済変数初期化
- view_distance_max = i_new_value;
- }
-
- /**
- * void arglCameraFrustumRH(const ARParam *cparam, const double focalmin, const double focalmax, GLdouble m_projection[16])
- * 関数の置き換え
- * @param focalmin
- * @param focalmax
- * @return
- */
- public double[] getCameraFrustumRH()
- {
- //既に値がキャッシュされていたらそれを使う
- if (m_projection != null) {
- return m_projection;
- }
- //無ければ計算
- m_projection = new double[16];
- NyARMat trans_mat = new NyARMat(3, 4);
- NyARMat icpara_mat = new NyARMat(3, 4);
- double[][] p = new double[3][3], q = new double[4][4];
-
- int i, j;
-
- final int width = this._screen_size.w;
- final int height = this._screen_size.h;
-
- this.getPerspectiveProjectionMatrix().decompMat(icpara_mat, trans_mat);
-
- double[][] icpara = icpara_mat.getArray();
- double[][] trans = trans_mat.getArray();
- for (i = 0; i < 4; i++) {
- icpara[1][i] = (height - 1) * (icpara[2][i]) - icpara[1][i];
- }
-
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 3; j++) {
- p[i][j] = icpara[i][j] / icpara[2][2];
- }
- }
- q[0][0] = (2.0 * p[0][0] / (width - 1));
- q[0][1] = (2.0 * p[0][1] / (width - 1));
- q[0][2] = -((2.0 * p[0][2] / (width - 1)) - 1.0);
- q[0][3] = 0.0;
-
- q[1][0] = 0.0;
- q[1][1] = -(2.0 * p[1][1] / (height - 1));
- q[1][2] = -((2.0 * p[1][2] / (height - 1)) - 1.0);
- q[1][3] = 0.0;
-
- q[2][0] = 0.0;
- q[2][1] = 0.0;
- q[2][2] = (view_distance_max + view_distance_min) / (view_distance_min - view_distance_max);
- q[2][3] = 2.0 * view_distance_max * view_distance_min / (view_distance_min - view_distance_max);
-
- q[3][0] = 0.0;
- q[3][1] = 0.0;
- q[3][2] = -1.0;
- q[3][3] = 0.0;
-
- for (i = 0; i < 4; i++) { // Row.
- // First 3 columns of the current row.
- for (j = 0; j < 3; j++) { // Column.
- m_projection[i + j * 4] = q[i][0] * trans[0][j] + q[i][1] * trans[1][j] + q[i][2] * trans[2][j];
- }
- // Fourth column of the current row.
- m_projection[i + 3 * 4] = q[i][0] * trans[0][3] + q[i][1] * trans[1][3] + q[i][2] * trans[2][3] + q[i][3];
- }
- return m_projection;
- }
-}
Index: trunk/src.utils/jogl/jp/nyatla/nyartoolkit/jogl/utils/NyARGLUtil.java
===================================================================
--- trunk/src.utils/jogl/jp/nyatla/nyartoolkit/jogl/utils/NyARGLUtil.java (revision 162)
+++ trunk/src.utils/jogl/jp/nyatla/nyartoolkit/jogl/utils/NyARGLUtil.java (revision 199)
@@ -37,6 +37,10 @@
import javax.media.opengl.GL;
import javax.media.opengl.glu.GLU;
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.NyARMat;
+import jp.nyatla.nyartoolkit.core.param.NyARParam;
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;
import jp.nyatla.nyartoolkit.core.types.*;
/**
* NyARToolkit用のJOGL支援関数群
@@ -125,4 +129,121 @@
ByteBuffer buf = ByteBuffer.wrap(i_raster.getGLRgbArray());
gl_.glDrawPixels(rsize.w,rsize.h, i_raster.getGLPixelFlag(), GL.GL_UNSIGNED_BYTE, buf);
}
+
+ private double view_scale_factor = 0.025;
+ private double view_distance_min = 0.1;//#define VIEW_DISTANCE_MIN 0.1 // Objects closer to the camera than this will not be displayed.
+ private double view_distance_max = 100.0;//#define VIEW_DISTANCE_MAX 100.0 // Objects further away from the camera than this will not be displayed.
+
+ public void setScaleFactor(double i_new_value)
+ {
+ this.view_scale_factor = i_new_value;
+ }
+
+ public void setViewDistanceMin(double i_new_value)
+ {
+ this.view_distance_min = i_new_value;
+ }
+
+ public void setViewDistanceMax(double i_new_value)
+ {
+ this.view_distance_max = i_new_value;
+ }
+
+ /**
+ * void arglCameraFrustumRH(const ARParam *cparam, const double focalmin, const double focalmax, GLdouble m_projection[16])
+ * 関数の置き換え
+ * NyARParamからOpenGLのProjectionを作成します。
+ * @param i_arparam
+ * @param o_gl_projection
+ * double[16]を指定して下さい。
+ */
+ public void toCameraFrustumRH(NyARParam i_arparam,double[] o_gl_projection)
+ {
+ NyARMat trans_mat = new NyARMat(3, 4);
+ NyARMat icpara_mat = new NyARMat(3, 4);
+ double[][] p = new double[3][3], q = new double[4][4];
+ int i, j;
+
+ final NyARIntSize size=i_arparam.getScreenSize();
+ final int width = size.w;
+ final int height = size.h;
+
+ i_arparam.getPerspectiveProjectionMatrix().decompMat(icpara_mat, trans_mat);
+
+ double[][] icpara = icpara_mat.getArray();
+ double[][] trans = trans_mat.getArray();
+ for (i = 0; i < 4; i++) {
+ icpara[1][i] = (height - 1) * (icpara[2][i]) - icpara[1][i];
+ }
+
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 3; j++) {
+ p[i][j] = icpara[i][j] / icpara[2][2];
+ }
+ }
+ q[0][0] = (2.0 * p[0][0] / (width - 1));
+ q[0][1] = (2.0 * p[0][1] / (width - 1));
+ q[0][2] = -((2.0 * p[0][2] / (width - 1)) - 1.0);
+ q[0][3] = 0.0;
+
+ q[1][0] = 0.0;
+ q[1][1] = -(2.0 * p[1][1] / (height - 1));
+ q[1][2] = -((2.0 * p[1][2] / (height - 1)) - 1.0);
+ q[1][3] = 0.0;
+
+ q[2][0] = 0.0;
+ q[2][1] = 0.0;
+ q[2][2] = (view_distance_max + view_distance_min) / (view_distance_min - view_distance_max);
+ q[2][3] = 2.0 * view_distance_max * view_distance_min / (view_distance_min - view_distance_max);
+
+ q[3][0] = 0.0;
+ q[3][1] = 0.0;
+ q[3][2] = -1.0;
+ q[3][3] = 0.0;
+
+ for (i = 0; i < 4; i++) { // Row.
+ // First 3 columns of the current row.
+ for (j = 0; j < 3; j++) { // Column.
+ o_gl_projection[i + j * 4] = q[i][0] * trans[0][j] + q[i][1] * trans[1][j] + q[i][2] * trans[2][j];
+ }
+ // Fourth column of the current row.
+ o_gl_projection[i + 3 * 4] = q[i][0] * trans[0][3] + q[i][1] * trans[1][3] + q[i][2] * trans[2][3] + q[i][3];
+ }
+ return;
+ }
+
+
+
+ /**
+ * NyARTransMatResultをOpenGLの行列へ変換します。
+ * @param i_ny_result
+ * @param o_gl_result
+ * @throws NyARException
+ */
+ public void toCameraViewRH(NyARTransMatResult i_ny_result, double[] o_gl_result) throws NyARException
+ {
+ o_gl_result[0 + 0 * 4] = i_ny_result.m00;
+ o_gl_result[0 + 1 * 4] = i_ny_result.m01;
+ o_gl_result[0 + 2 * 4] = i_ny_result.m02;
+ o_gl_result[0 + 3 * 4] = i_ny_result.m03;
+ o_gl_result[1 + 0 * 4] = -i_ny_result.m10;
+ o_gl_result[1 + 1 * 4] = -i_ny_result.m11;
+ o_gl_result[1 + 2 * 4] = -i_ny_result.m12;
+ o_gl_result[1 + 3 * 4] = -i_ny_result.m13;
+ o_gl_result[2 + 0 * 4] = -i_ny_result.m20;
+ o_gl_result[2 + 1 * 4] = -i_ny_result.m21;
+ o_gl_result[2 + 2 * 4] = -i_ny_result.m22;
+ o_gl_result[2 + 3 * 4] = -i_ny_result.m23;
+ o_gl_result[3 + 0 * 4] = 0.0;
+ o_gl_result[3 + 1 * 4] = 0.0;
+ o_gl_result[3 + 2 * 4] = 0.0;
+ o_gl_result[3 + 3 * 4] = 1.0;
+ if (view_scale_factor != 0.0) {
+ o_gl_result[12] *= view_scale_factor;
+ o_gl_result[13] *= view_scale_factor;
+ o_gl_result[14] *= view_scale_factor;
+ }
+ return;
+ }
+
}
Index: trunk/src/jp/nyatla/nyartoolkit/core/rasterreader/INyARBufferReader.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/rasterreader/INyARBufferReader.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/rasterreader/INyARBufferReader.java (revision 199)
@@ -33,6 +33,15 @@
public interface INyARBufferReader
{
+ // ID規約
+ // 00-07(8)型番号
+ // 08-15(8)ビットフォーマットID
+ // 00:24bit/01:32bit/02:16bit
+ // 16-27(8)型ID
+ // 00:無効/01:byte[]/02:int[][]/03:short[]
+ // 24-31(8)予約
+ //
+
/**
* RGB24フォーマットで、全ての画素が0
*/
@@ -54,6 +63,18 @@
public static final int BUFFERFORMAT_BYTE1D_B8G8R8X8_32 = 0x00010101;
/**
+ * byte[]で、RGB565の16ビット(little/big endian)で画素が格納されている。
+ */
+ public static final int BUFFERFORMAT_BYTE1D_R5G6B5_16LE = 0x00010201;
+ public static final int BUFFERFORMAT_BYTE1D_R5G6B5_16BE = 0x00010202;
+ /**
+ * short[]で、RGB565の16ビット(little/big endian)で画素が格納されている。
+ */
+ public static final int BUFFERFORMAT_WORD1D_R5G6B5_16LE = 0x00030201;
+ public static final int BUFFERFORMAT_WORD1D_R5G6B5_16BE = 0x00030202;
+
+
+ /**
* int[][]で特に値範囲を定めない
*/
public static final int BUFFERFORMAT_INT2D = 0x00020000;
Index: trunk/src/jp/nyatla/nyartoolkit/core/NyARVertexCounter.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/NyARVertexCounter.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core/NyARVertexCounter.java (revision 199)
@@ -0,0 +1,72 @@
+package jp.nyatla.nyartoolkit.core;
+
+/**
+ * get_vertex関数を切り離すためのクラス
+ *
+ */
+final public class NyARVertexCounter
+{
+ public final int[] vertex = new int[10];// 6まで削れる
+
+ public int number_of_vertex;
+
+ private double thresh;
+
+ private int[] x_coord;
+
+ private int[] y_coord;
+
+ public boolean getVertex(int[] i_x_coord, int[] i_y_coord, int st, int ed, double i_thresh)
+ {
+ this.number_of_vertex = 0;
+ this.thresh = i_thresh;
+ this.x_coord = i_x_coord;
+ this.y_coord = i_y_coord;
+ return get_vertex(st, ed);
+ }
+
+ /**
+ * static int get_vertex( int x_coord[], int y_coord[], int st, int ed,double thresh, int vertex[], int *vnum) 関数の代替関数
+ *
+ * @param x_coord
+ * @param y_coord
+ * @param st
+ * @param ed
+ * @param thresh
+ * @return
+ */
+ private boolean get_vertex(int st, int ed)
+ {
+ //メモ:座標値は65536を超えなければint32で扱って大丈夫なので変更。
+ //dmaxは4乗なのでやるとしてもint64じゃないとマズイ
+ int v1 = 0;
+ final int[] lx_coord = this.x_coord;
+ final int[] ly_coord = this.y_coord;
+ final int a = ly_coord[ed] - ly_coord[st];
+ final int b = lx_coord[st] - lx_coord[ed];
+ final int c = lx_coord[ed] * ly_coord[st] - ly_coord[ed] * lx_coord[st];
+ double dmax = 0;
+ for (int i = st + 1; i < ed; i++) {
+ final double d = a * lx_coord[i] + b * ly_coord[i] + c;
+ if (d * d > dmax) {
+ dmax = d * d;
+ v1 = i;
+ }
+ }
+ if (dmax / (double)(a * a + b * b) > thresh) {
+ if (!get_vertex(st, v1)) {
+ return false;
+ }
+ if (number_of_vertex > 5) {
+ return false;
+ }
+ vertex[number_of_vertex] = v1;// vertex[(*vnum)] = v1;
+ number_of_vertex++;// (*vnum)++;
+
+ if (!get_vertex(v1, ed)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
\ No newline at end of file
Index: trunk/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA.java (revision 199)
@@ -0,0 +1,75 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core.pca2d;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.NyARMat;
+import jp.nyatla.nyartoolkit.core.NyARVec;
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;
+/**
+ * NyARMatrixを利用した主成分分析
+ * ARToolKitと同じ処理をします。
+ */
+public class NyARPca2d_MatrixPCA implements INyARPca2d
+{
+ private final NyARMat __pca_input = new NyARMat(1, 2);
+ private final NyARMat __pca_evec = new NyARMat(2, 2);
+ private final NyARVec __pca_ev = new NyARVec(2);
+ private final NyARVec __pca_mean = new NyARVec(2);
+
+ public void pca(double[] i_x,double[] i_y,int i_number_of_point,NyARDoubleMatrix22 o_evec, NyARDoublePoint2d o_ev,NyARDoublePoint2d o_mean) throws NyARException
+ {
+ final NyARMat input = this.__pca_input;// 次処理で初期化される。
+ // pcaの準備
+ input.realloc(i_number_of_point, 2);
+ final double[][] input_array=input.getArray();
+ for(int i=0;i<i_number_of_point;i++){
+ input_array[i][0]=i_x[i];
+ input_array[i][1]=i_y[i];
+ }
+ // 主成分分析
+ input.matrixPCA(this.__pca_evec, this.__pca_ev, this.__pca_mean);
+ final double[] mean_array = this.__pca_mean.getArray();
+ final double[][] evec_array = this.__pca_evec.getArray();
+ final double[] ev_array=this.__pca_ev.getArray();
+ o_evec.m00=evec_array[0][0];
+ o_evec.m01=evec_array[0][1];
+ o_evec.m10=evec_array[1][0];
+ o_evec.m11=evec_array[1][1];
+ o_ev.x=ev_array[0];
+ o_ev.x=ev_array[1];
+ o_mean.x=mean_array[0];
+ o_mean.y=mean_array[1];
+ return;
+ }
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA_O2.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA_O2.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA_O2.java (revision 199)
@@ -0,0 +1,215 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core.pca2d;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.types.matrix.*;
+
+/**
+ * ARToolkitのPCA関数を二次元に特化させて単純化したもの
+ *
+ */
+public class NyARPca2d_MatrixPCA_O2 implements INyARPca2d
+{
+ private static final double PCA_EPS = 1e-6; // #define EPS 1e-6
+
+ private static final int PCA_MAX_ITER = 100; // #define MAX_ITER 100
+
+ private static final double PCA_VZERO = 1e-16; // #define VZERO 1e-16
+
+ /**
+ * static int QRM( ARMat *a, ARVec *dv )の代替関数
+ *
+ * @param a
+ * @param dv
+ * @throws NyARException
+ */
+ private static void PCA_QRM(NyARDoubleMatrix22 o_matrix, NyARDoublePoint2d dv) throws NyARException
+ {
+ double w, t, s, x, y, c;
+ double ev1;
+ double dv_x,dv_y;
+ double mat00,mat01,mat10,mat11;
+ // <this.vecTridiagonalize2d(i_mat, dv, ev);>
+ dv_x = o_matrix.m00;// this.m[dim - 2][dim - 2];// d.v[dim-2]=a.m[dim-2][dim-2];//d->v[dim-2]=a->m[(dim-2)*dim+(dim-2)];
+ ev1 = o_matrix.m01;// this.m[dim - 2][dim - 1];// e.v[dim-2+i_e_start]=a.m[dim-2][dim-1];//e->v[dim-2] = a->m[(dim-2)*dim+(dim-1)];
+ dv_y = o_matrix.m11;// this.m[dim - 1][dim - 1];// d.v[dim-1]=a_array[dim-1][dim-1];//d->v[dim-1] =a->m[(dim-1)*dim+(dim-1)];
+ // 単位行列にする。
+ mat00 = mat11 = 1;
+ mat01 = mat10 = 0;
+ // </this.vecTridiagonalize2d(i_mat, dv, ev);>
+
+ // int j = 1;
+ // // while(j>0 && fabs(ev->v[j])>EPS*(fabs(dv->v[j-1])+fabs(dv->v[j])))
+ // while (j > 0 && Math.abs(ev1) > PCA_EPS * (Math.abs(dv.x) + Math.abs(dv.y))) {
+ // j--;
+ // }
+ // if (j == 0) {
+ int iter = 0;
+ do {
+ iter++;
+ if (iter > PCA_MAX_ITER) {
+ break;
+ }
+ w = (dv_x - dv_y) / 2;// w = (dv->v[h-1] -dv->v[h]) / 2;//ここ?
+ t = ev1 * ev1;// t = ev->v[h] * ev->v[h];
+ s = Math.sqrt(w * w + t);
+ if (w < 0) {
+ s = -s;
+ }
+ x = dv_x - dv_y + t / (w + s);// x = dv->v[j] -dv->v[h] +t/(w+s);
+ y = ev1;// y = ev->v[j+1];
+
+ if (Math.abs(x) >= Math.abs(y)) {
+ if (Math.abs(x) > PCA_VZERO) {
+ t = -y / x;
+ c = 1 / Math.sqrt(t * t + 1);
+ s = t * c;
+ } else {
+ c = 1.0;
+ s = 0.0;
+ }
+ } else {
+ t = -x / y;
+ s = 1.0 / Math.sqrt(t * t + 1);
+ c = t * s;
+ }
+ w = dv_x - dv_y;// w = dv->v[k] -dv->v[k+1];
+ t = (w * s + 2 * c * ev1) * s;// t = (w * s +2 * c *ev->v[k+1]) *s;
+ dv_x -= t;// dv->v[k] -= t;
+ dv_y += t;// dv->v[k+1] += t;
+ ev1 += s * (c * w - 2 * s * ev1);// ev->v[k+1]+= s * (c* w- 2* s *ev->v[k+1]);
+
+ x = mat00;// x = a->m[k*dim+i];
+ y = mat10;// y = a->m[(k+1)*dim+i];
+ mat00 = c * x - s * y;// a->m[k*dim+i] = c * x - s* y;
+ mat10 = s * x + c * y;// a->m[(k+1)*dim+i] = s* x + c * y;
+
+ x = mat01;// x = a->m[k*dim+i];
+ y = mat11;// y = a->m[(k+1)*dim+i];
+ mat01 = c * x - s * y;// a->m[k*dim+i] = c * x - s* y;
+ mat11 = s * x + c * y;// a->m[(k+1)*dim+i] = s* x + c * y;
+ } while (Math.abs(ev1) > PCA_EPS * (Math.abs(dv_x) + Math.abs(dv_y)));
+ // }
+
+ t = dv_x;// t = dv->v[h];
+ if (dv_y > t) {// if( dv->v[i] > t ) {
+ t = dv_y;// t = dv->v[h];
+ dv_y = dv_x;// dv->v[h] = dv->v[k];
+ dv_x = t;// dv->v[k] = t;
+ // 行の入れ替え
+ o_matrix.m00 = mat10;
+ o_matrix.m01 = mat11;
+ o_matrix.m10 = mat00;
+ o_matrix.m11 = mat01;
+
+ } else {
+ // 行の入れ替えはなし
+ o_matrix.m00 = mat00;
+ o_matrix.m01 = mat01;
+ o_matrix.m10 = mat10;
+ o_matrix.m11 = mat11;
+ }
+ dv.x=dv_x;
+ dv.y=dv_y;
+ return;
+ }
+
+ /**
+ * static int PCA( ARMat *input, ARMat *output, ARVec *ev )
+ *
+ * @param output
+ * @param o_ev
+ * @throws NyARException
+ */
+ private void PCA_PCA(double[] i_x,double[] i_y,int i_number_of_data,NyARDoubleMatrix22 o_matrix, NyARDoublePoint2d o_ev,NyARDoublePoint2d o_mean) throws NyARException
+ {
+ // double[] mean_array=mean.getArray();
+ // mean.zeroClear();
+
+ //PCA_EXの処理
+ double sx = 0;
+ double sy = 0;
+ for (int i = 0; i < i_number_of_data; i++) {
+ sx += i_x[i];
+ sy += i_y[i];
+ }
+ sx = sx / i_number_of_data;
+ sy = sy / i_number_of_data;
+
+ //PCA_CENTERとPCA_xt_by_xを一緒に処理
+ final double srow = Math.sqrt((double) i_number_of_data);
+ double w00, w11, w10;
+ w00 = w11 = w10 = 0.0;// *out = 0.0;
+ for (int i = 0; i < i_number_of_data; i++) {
+ final double x = (i_x[i] - sx) / srow;
+ final double y = (i_y[i] - sy) / srow;
+ w00 += (x * x);// *out += *in1 * *in2;
+ w10 += (x * y);// *out += *in1 * *in2;
+ w11 += (y * y);// *out += *in1 * *in2;
+ }
+ o_matrix.m00=w00;
+ o_matrix.m01=o_matrix.m10=w10;
+ o_matrix.m11=w11;
+
+ //PCA_PCAの処理
+ PCA_QRM(o_matrix, o_ev);
+ // m2 = o_output.m;// m2 = output->m;
+ if (o_ev.x < PCA_VZERO) {// if( ev->v[i] < VZERO ){
+ o_ev.x = 0.0;// ev->v[i] = 0.0;
+ o_matrix.m00 = 0.0;// *(m2++) = 0.0;
+ o_matrix.m01 = 0.0;// *(m2++) = 0.0;
+ }
+
+ if (o_ev.y < PCA_VZERO) {// if( ev->v[i] < VZERO ){
+ o_ev.y = 0.0;// ev->v[i] = 0.0;
+ o_matrix.m10 = 0.0;// *(m2++) = 0.0;
+ o_matrix.m11 = 0.0;// *(m2++) = 0.0;
+ }
+ o_mean.x=sx;
+ o_mean.y=sy;
+ // }
+ return;
+ }
+ public void pca(double[] i_x,double[] i_y,int i_number_of_point,NyARDoubleMatrix22 o_evec, NyARDoublePoint2d o_ev,NyARDoublePoint2d o_mean) throws NyARException
+ {
+ PCA_PCA(i_x,i_y,i_number_of_point,o_evec, o_ev,o_mean);
+
+ final double sum = o_ev.x + o_ev.y;
+ // For順変更禁止
+ o_ev.x /= sum;// ev->v[i] /= sum;
+ o_ev.y /= sum;// ev->v[i] /= sum;
+ return;
+ }
+
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core/pca2d/INyARPca2d.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/pca2d/INyARPca2d.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core/pca2d/INyARPca2d.java (revision 199)
@@ -0,0 +1,65 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core.pca2d;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;
+
+public interface INyARPca2d
+{
+ /**
+ * 通常のPCA
+ * @param i_x
+ * @param i_y
+ * @param i_start
+ * @param i_number_of_point
+ * @param o_evec
+ * @param o_ev
+ * @param o_mean
+ * @throws NyARException
+ */
+ public void pca(double[] i_x,double[] i_y,int i_number_of_point,NyARDoubleMatrix22 o_evec, NyARDoublePoint2d o_ev,NyARDoublePoint2d o_mean) throws NyARException;
+ /**
+ * カメラ歪み補正つきのPCA
+ * @param i_x
+ * @param i_y
+ * @param i_start
+ * @param i_number_of_point
+ * @param i_factor
+ * @param o_evec
+ * @param o_mean
+ * @throws NyARException
+ */
+// public void pcaWithDistortionFactor(int[] i_x,int[] i_y,int i_start,int i_number_of_point,INyARCameraDistortionFactor i_factor,NyARDoubleMatrix22 o_evec,NyARDoublePoint2d o_ev, NyARDoublePoint2d o_mean) throws NyARException;
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core/transmat/optimize/NyARRotTransOptimize_Base.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/transmat/optimize/NyARRotTransOptimize_Base.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core/transmat/optimize/NyARRotTransOptimize_Base.java (revision 199)
@@ -0,0 +1,222 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core.transmat.optimize;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.transmat.fitveccalc.NyARFitVecCalculator;
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.NyARRotMatrix;
+import jp.nyatla.nyartoolkit.core.types.matrix.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+
+/**
+ * 処理構造がわかる程度に展開したNyARRotTransOptimize
+ *
+ */
+public class NyARRotTransOptimize_Base implements INyARRotTransOptimize
+{
+ private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT = 5;// #define AR_GET_TRANS_MAT_MAX_LOOP_COUNT 5
+
+ private final static double AR_GET_TRANS_MAT_MAX_FIT_ERROR = 1.0;// #define AR_GET_TRANS_MAT_MAX_FIT_ERROR 1.0
+
+ private final NyARPerspectiveProjectionMatrix _projection_mat_ref;
+
+ public NyARRotTransOptimize_Base(NyARPerspectiveProjectionMatrix i_projection_mat_ref)
+ {
+ this._projection_mat_ref = i_projection_mat_ref;
+ return;
+ }
+
+ final public double optimize(NyARRotMatrix io_rotmat, NyARDoublePoint3d io_transvec, NyARFitVecCalculator i_calculator) throws NyARException
+ {
+ final NyARDoublePoint2d[] fit_vertex = i_calculator.getFitSquare();
+ final NyARDoublePoint3d[] offset_square = i_calculator.getOffsetVertex().vertex;
+
+ double err = -1;
+ /* ループを抜けるタイミングをARToolKitと合わせるために変なことしてます。 */
+ for (int i = 0;; i++) {
+ // <arGetTransMat3>
+ err = modifyMatrix(io_rotmat, io_transvec, offset_square, fit_vertex);
+ i_calculator.calculateTransfer(io_rotmat, io_transvec);
+ err = modifyMatrix(io_rotmat, io_transvec, offset_square, fit_vertex);
+ // //</arGetTransMat3>
+ if (err < AR_GET_TRANS_MAT_MAX_FIT_ERROR || i == AR_GET_TRANS_MAT_MAX_LOOP_COUNT - 1) {
+ break;
+ }
+ i_calculator.calculateTransfer(io_rotmat, io_transvec);
+ }
+ return err;
+ }
+ private double[] __createRotationMap_b_map=new double[6];
+ private double[] __createRotationMap_c_map=new double[6];
+ private double[] __createRotationMap_f=new double[3];
+ private void createRotationMap(NyARDoublePoint3d i_angle,double i_factor,NyARDoubleMatrix33[] i_rot_matrix)
+ {
+ double sina,cosa,sinb,cosb,sinc,cosc;
+ double CACA,SASA,SACA,SASB,CASB,SACACB,CACACB,SASACB;
+
+
+ final double[] f=this.__createRotationMap_f;
+ final double[] b_map=this.__createRotationMap_b_map;
+ final double[] c_map=this.__createRotationMap_c_map;
+ f[0]=-i_factor;
+ f[1]=0;
+ f[2]=i_factor;
+ double ang1,ang2;
+ //BとCのsinマップを先に作成
+ for(int i=0;i<3;i++)
+ {
+ ang1=i_angle.y + f[i];
+ b_map[i] =Math.sin(ang1);
+ b_map[i+3]=Math.cos(ang1);
+ ang2=i_angle.z + f[i];
+ c_map[i] =Math.sin(ang2);
+ c_map[i+3]=Math.cos(ang2);
+ }
+ int idx=0;
+ int t1,t2,t3;
+ for (t1 = 0; t1 < 3; t1++){
+ ang1=i_angle.x + f[t1];
+ sina = Math.sin(ang1);
+ cosa = Math.cos(ang1);
+ CACA = cosa * cosa;
+ SASA = sina * sina;
+ SACA = sina * cosa;
+
+ for (t2=0;t2<3;t2++){
+ sinb = b_map[t2];
+ cosb = b_map[t2+3];
+ SASB = sina * sinb;
+ CASB = cosa * sinb;
+ SACACB = SACA * cosb;
+ CACACB = CACA * cosb;
+ SASACB = SASA * cosb;
+ for (t3=0;t3<3;t3++) {
+ sinc = c_map[t3];
+ cosc = c_map[t3+3];
+ final NyARDoubleMatrix33 mat_ptr=i_rot_matrix[idx];
+ mat_ptr.m00 = CACACB * cosc + SASA * cosc + SACACB * sinc - SACA * sinc;
+ mat_ptr.m01 = -CACACB * sinc - SASA * sinc + SACACB * cosc - SACA * cosc;
+ mat_ptr.m02 = CASB;
+ mat_ptr.m10 = SACACB * cosc - SACA * cosc + SASACB * sinc + CACA * sinc;
+ mat_ptr.m11 = -SACACB * sinc + SACA * sinc + SASACB * cosc + CACA * cosc;
+ mat_ptr.m12 = SASB;
+ mat_ptr.m20 = -CASB * cosc - SASB * sinc;
+ mat_ptr.m21 = CASB * sinc - SASB * cosc;
+ mat_ptr.m22 = cosb;
+ idx++;
+ }
+ }
+ }
+ return;
+ }
+ private final void getNewMatrix(NyARDoubleMatrix33 i_rot, NyARDoublePoint3d i_trans, NyARDoubleMatrix34 o_combo)
+ {
+ double cp0,cp1,cp2,cp3;
+ NyARPerspectiveProjectionMatrix cp=this._projection_mat_ref;
+
+ cp3=cp.m03;
+ cp0=cp.m00;cp1=cp.m01;cp2=cp.m02;
+ o_combo.m00=cp0 * i_rot.m00 + cp1 * i_rot.m10 + cp2 * i_rot.m20;
+ o_combo.m01=cp0 * i_rot.m01 + cp1 * i_rot.m11 + cp2 * i_rot.m21;
+ o_combo.m02=cp0 * i_rot.m02 + cp1 * i_rot.m12 + cp2 * i_rot.m22;
+ o_combo.m03=cp0 * i_trans.x + cp1 * i_trans.y + cp2 * i_trans.z +cp3;
+
+ cp0=cp.m10;cp1=cp.m11;cp2=cp.m12;
+ o_combo.m10=cp0 * i_rot.m00 + cp1 * i_rot.m10 + cp2 * i_rot.m20;
+ o_combo.m11=cp0 * i_rot.m01 + cp1 * i_rot.m11 + cp2 * i_rot.m21;
+ o_combo.m12=cp0 * i_rot.m02 + cp1 * i_rot.m12 + cp2 * i_rot.m22;
+ o_combo.m13=cp0 * i_trans.x + cp1 * i_trans.y + cp2 * i_trans.z +cp3;
+
+ cp0=cp.m20;cp1=cp.m21;cp2=cp.m22;
+ o_combo.m20=cp0 * i_rot.m00 + cp1 * i_rot.m10 + cp2 * i_rot.m20;
+ o_combo.m21=cp0 * i_rot.m01 + cp1 * i_rot.m11 + cp2 * i_rot.m21;
+ o_combo.m22=cp0 * i_rot.m02 + cp1 * i_rot.m12 + cp2 * i_rot.m22;
+ o_combo.m23=cp0 * i_trans.x + cp1 * i_trans.y + cp2 * i_trans.z +cp3;
+ return;
+ }
+ private final NyARDoublePoint3d __modifyMatrix_angle = new NyARDoublePoint3d();
+ private final NyARDoubleMatrix34 __modifyMatrix_combo=new NyARDoubleMatrix34();
+ private final NyARDoubleMatrix33[] __modifyMatrix_next_rot_matrix=NyARDoubleMatrix33.createArray(27);
+ public final double modifyMatrix(NyARRotMatrix io_rot, NyARDoublePoint3d trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d) throws NyARException
+ {
+ final NyARDoublePoint3d angle = this.__modifyMatrix_angle;
+ final NyARDoubleMatrix34 combo=this.__modifyMatrix_combo;
+ final NyARDoubleMatrix33[] next_rot_matrix=this.__modifyMatrix_next_rot_matrix;
+ double factor;
+ double hx, hy, h, x, y;
+ double err, minerr = 0;
+ int i,i2;
+ int best_idx=0;
+
+ io_rot.getAngle(angle);// arGetAngle( rot, &a, &b, &c );
+ factor = 10.0 * Math.PI / 180.0;
+ for (int j = 0; j < 10; j++){
+ minerr = 1000000000.0;
+ //評価用の角度マップ作成
+ createRotationMap(angle,factor,next_rot_matrix);
+ //評価して一番宜しいIDを保存
+ best_idx=(1+1*3+1*9);
+ for(i2=0;i2<27;i2++){
+ this.getNewMatrix(next_rot_matrix[i2],trans,combo);
+ err = 0.0;
+ for (i = 0; i < 4; i++) {
+ hx = combo.m00 * i_vertex3d[i].x + combo.m01 * i_vertex3d[i].y + combo.m02 * i_vertex3d[i].z + combo.m03;
+ hy = combo.m10 * i_vertex3d[i].x + combo.m11 *i_vertex3d[i].y + combo.m12 * i_vertex3d[i].z + combo.m13;
+ h = combo.m20 * i_vertex3d[i].x + combo.m21 * i_vertex3d[i].y + combo.m22 * i_vertex3d[i].z + combo.m23;
+ x = i_vertex2d[i].x-(hx / h);
+ y = i_vertex2d[i].y-(hy / h);
+ err += x*x+y*y;
+ }
+ if (err < minerr){
+ minerr = err;
+ best_idx=i2;
+ }
+
+ }
+ if (best_idx==(1+1*3+1*9)){
+ factor *= 0.5;
+ }else{
+ angle.z+=factor*(best_idx%3-1);
+ angle.y+=factor*((best_idx/3)%3-1);
+ angle.x+=factor*((best_idx/9)%3-1);
+ }
+ }
+ io_rot.setAngle(angle.x,angle.y,angle.z);
+ /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */
+ return minerr / 4;
+ }
+
+
+
+
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core/transmat/optimize/NyARRotTransOptimize_O2.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/transmat/optimize/NyARRotTransOptimize_O2.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core/transmat/optimize/NyARRotTransOptimize_O2.java (revision 199)
@@ -0,0 +1,265 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core.transmat.optimize;
+
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.transmat.fitveccalc.NyARFitVecCalculator;
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.NyARRotMatrix;
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;
+/**
+ * 基本姿勢と実画像を一致するように、角度を微調整→平行移動量を再計算
+ * を繰り返して、変換行列を最適化する。
+ *
+ */
+public class NyARRotTransOptimize_O2 implements INyARRotTransOptimize
+{
+ private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT = 5;// #define AR_GET_TRANS_MAT_MAX_LOOP_COUNT 5
+ private final static double AR_GET_TRANS_MAT_MAX_FIT_ERROR = 1.0;// #define AR_GET_TRANS_MAT_MAX_FIT_ERROR 1.0
+ private final NyARPerspectiveProjectionMatrix _projection_mat_ref;
+ public NyARRotTransOptimize_O2(NyARPerspectiveProjectionMatrix i_projection_mat_ref)
+ {
+ this._projection_mat_ref=i_projection_mat_ref;
+ return;
+ }
+
+ final public double optimize(NyARRotMatrix io_rotmat,NyARDoublePoint3d io_transvec,NyARFitVecCalculator i_calculator) throws NyARException
+ {
+ final NyARDoublePoint2d[] fit_vertex=i_calculator.getFitSquare();
+ final NyARDoublePoint3d[] offset_square=i_calculator.getOffsetVertex().vertex;
+
+ double err = -1;
+ /*ループを抜けるタイミングをARToolKitと合わせるために変なことしてます。*/
+ for (int i = 0;; i++) {
+ // <arGetTransMat3>
+ err = modifyMatrix(io_rotmat,io_transvec,offset_square,fit_vertex);
+ i_calculator.calculateTransfer(io_rotmat, io_transvec);
+ err = modifyMatrix(io_rotmat,io_transvec,offset_square,fit_vertex);
+ // //</arGetTransMat3>
+ if (err < AR_GET_TRANS_MAT_MAX_FIT_ERROR || i == AR_GET_TRANS_MAT_MAX_LOOP_COUNT-1) {
+ break;
+ }
+ i_calculator.calculateTransfer(io_rotmat, io_transvec);
+ }
+ return err;
+ }
+
+ private final double[][] __modifyMatrix_double1D = new double[8][3];
+ private final NyARDoublePoint3d __modifyMatrix_angle = new NyARDoublePoint3d();
+ /**
+ * arGetRot計算を階層化したModifyMatrix 896
+ *
+ * @param nyrot
+ * @param trans
+ * @param i_vertex3d
+ * [m][3]
+ * @param i_vertex2d
+ * [n][2]
+ * @return
+ * @throws NyARException
+ */
+ private double modifyMatrix(NyARRotMatrix io_rot,NyARDoublePoint3d trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d) throws NyARException
+ {
+ double factor;
+ double a2, b2, c2;
+ double h, x, y;
+ double err, minerr = 0;
+ int t1, t2, t3;
+ int best_idx=0;
+
+ factor = 10.0 * Math.PI / 180.0;
+ double rot0, rot1, rot2;
+ double combo00, combo01, combo02, combo03, combo10, combo11, combo12, combo13, combo20, combo21, combo22, combo23;
+ double combo02_2, combo02_5, combo02_8, combo02_11;
+ double combo22_2, combo22_5, combo22_8, combo22_11;
+ double combo12_2, combo12_5, combo12_8, combo12_11;
+ // vertex展開
+ final double VX00, VX01, VX02, VX10, VX11, VX12, VX20, VX21, VX22, VX30, VX31, VX32;
+ VX00 = i_vertex3d[0].x;
+ VX01 = i_vertex3d[0].y;
+ VX02 = i_vertex3d[0].z;
+ VX10 = i_vertex3d[1].x;
+ VX11 = i_vertex3d[1].y;
+ VX12 = i_vertex3d[1].z;
+ VX20 = i_vertex3d[2].x;
+ VX21 = i_vertex3d[2].y;
+ VX22 = i_vertex3d[2].z;
+ VX30 = i_vertex3d[3].x;
+ VX31 = i_vertex3d[3].y;
+ VX32 = i_vertex3d[3].z;
+ final double P2D00, P2D01, P2D10, P2D11, P2D20, P2D21, P2D30, P2D31;
+ P2D00 = i_vertex2d[0].x;
+ P2D01 = i_vertex2d[0].y;
+ P2D10 = i_vertex2d[1].x;
+ P2D11 = i_vertex2d[1].y;
+ P2D20 = i_vertex2d[2].x;
+ P2D21 = i_vertex2d[2].y;
+ P2D30 = i_vertex2d[3].x;
+ P2D31 = i_vertex2d[3].y;
+ final NyARPerspectiveProjectionMatrix prjmat = this._projection_mat_ref;
+ final double CP0 = prjmat.m00,CP1 = prjmat.m01,CP2 = prjmat.m02,CP4 = prjmat.m10,CP5 = prjmat.m11,CP6 = prjmat.m12,CP8 = prjmat.m20,CP9 = prjmat.m21,CP10 = prjmat.m22;
+ combo03 = CP0 * trans.x + CP1 * trans.y + CP2 * trans.z + prjmat.m03;
+ combo13 = CP4 * trans.x + CP5 * trans.y + CP6 * trans.z + prjmat.m13;
+ combo23 = CP8 * trans.x + CP9 * trans.y + CP10 * trans.z + prjmat.m23;
+ double CACA, SASA, SACA, CA, SA;
+ double CACACB, SACACB, SASACB, CASB, SASB;
+ double SACASC, SACACBSC, SACACBCC, SACACC;
+ final double[][] double1D = this.__modifyMatrix_double1D;
+
+ final NyARDoublePoint3d angle = this.__modifyMatrix_angle;
+ final double[] a_factor = double1D[1];
+ final double[] sinb = double1D[2];
+ final double[] cosb = double1D[3];
+ final double[] b_factor = double1D[4];
+ final double[] sinc = double1D[5];
+ final double[] cosc = double1D[6];
+ final double[] c_factor = double1D[7];
+ double w, w2;
+ double wsin, wcos;
+
+ io_rot.getAngle(angle);// arGetAngle( rot, &a, &b, &c );
+ a2 = angle.x;
+ b2 = angle.y;
+ c2 = angle.z;
+
+ // comboの3行目を先に計算
+ for (int i = 0; i < 10; i++) {
+ minerr = 1000000000.0;
+ // sin-cosテーブルを計算(これが外に出せるとは…。)
+ for (int j = 0; j < 3; j++) {
+ w2 = factor * (j - 1);
+ w = a2 + w2;
+ a_factor[j] = w;
+ w = b2 + w2;
+ b_factor[j] = w;
+ sinb[j] = Math.sin(w);
+ cosb[j] = Math.cos(w);
+ w = c2 + w2;
+ c_factor[j] = w;
+ sinc[j] = Math.sin(w);
+ cosc[j] = Math.cos(w);
+ }
+ //
+ for (t1 = 0; t1 < 3; t1++) {
+ SA = Math.sin(a_factor[t1]);
+ CA = Math.cos(a_factor[t1]);
+ // Optimize
+ CACA = CA * CA;
+ SASA = SA * SA;
+ SACA = SA * CA;
+ for (t2 = 0; t2 < 3; t2++) {
+ wsin = sinb[t2];
+ wcos = cosb[t2];
+ CACACB = CACA * wcos;
+ SACACB = SACA * wcos;
+ SASACB = SASA * wcos;
+ CASB = CA * wsin;
+ SASB = SA * wsin;
+ // comboの計算1
+ combo02 = CP0 * CASB + CP1 * SASB + CP2 * wcos;
+ combo12 = CP4 * CASB + CP5 * SASB + CP6 * wcos;
+ combo22 = CP8 * CASB + CP9 * SASB + CP10 * wcos;
+
+ combo02_2 = combo02 * VX02 + combo03;
+ combo02_5 = combo02 * VX12 + combo03;
+ combo02_8 = combo02 * VX22 + combo03;
+ combo02_11 = combo02 * VX32 + combo03;
+ combo12_2 = combo12 * VX02 + combo13;
+ combo12_5 = combo12 * VX12 + combo13;
+ combo12_8 = combo12 * VX22 + combo13;
+ combo12_11 = combo12 * VX32 + combo13;
+ combo22_2 = combo22 * VX02 + combo23;
+ combo22_5 = combo22 * VX12 + combo23;
+ combo22_8 = combo22 * VX22 + combo23;
+ combo22_11 = combo22 * VX32 + combo23;
+ for (t3 = 0; t3 < 3; t3++) {
+ wsin = sinc[t3];
+ wcos = cosc[t3];
+ SACASC = SACA * wsin;
+ SACACC = SACA * wcos;
+ SACACBSC = SACACB * wsin;
+ SACACBCC = SACACB * wcos;
+
+ rot0 = CACACB * wcos + SASA * wcos + SACACBSC - SACASC;
+ rot1 = SACACBCC - SACACC + SASACB * wsin + CACA * wsin;
+ rot2 = -CASB * wcos - SASB * wsin;
+ combo00 = CP0 * rot0 + CP1 * rot1 + CP2 * rot2;
+ combo10 = CP4 * rot0 + CP5 * rot1 + CP6 * rot2;
+ combo20 = CP8 * rot0 + CP9 * rot1 + CP10 * rot2;
+
+ rot0 = -CACACB * wsin - SASA * wsin + SACACBCC - SACACC;
+ rot1 = -SACACBSC + SACASC + SASACB * wcos + CACA * wcos;
+ rot2 = CASB * wsin - SASB * wcos;
+ combo01 = CP0 * rot0 + CP1 * rot1 + CP2 * rot2;
+ combo11 = CP4 * rot0 + CP5 * rot1 + CP6 * rot2;
+ combo21 = CP8 * rot0 + CP9 * rot1 + CP10 * rot2;
+ //
+ err = 0.0;
+ h = combo20 * VX00 + combo21 * VX01 + combo22_2;
+ x = P2D00 - (combo00 * VX00 + combo01 * VX01 + combo02_2) / h;
+ y = P2D01 - (combo10 * VX00 + combo11 * VX01 + combo12_2) / h;
+ err += x * x + y * y;
+ h = combo20 * VX10 + combo21 * VX11 + combo22_5;
+ x = P2D10 - (combo00 * VX10 + combo01 * VX11 + combo02_5) / h;
+ y = P2D11 - (combo10 * VX10 + combo11 * VX11 + combo12_5) / h;
+ err += x * x + y * y;
+ h = combo20 * VX20 + combo21 * VX21 + combo22_8;
+ x = P2D20 - (combo00 * VX20 + combo01 * VX21 + combo02_8) / h;
+ y = P2D21 - (combo10 * VX20 + combo11 * VX21 + combo12_8) / h;
+ err += x * x + y * y;
+ h = combo20 * VX30 + combo21 * VX31 + combo22_11;
+ x = P2D30 - (combo00 * VX30 + combo01 * VX31 + combo02_11) / h;
+ y = P2D31 - (combo10 * VX30 + combo11 * VX31 + combo12_11) / h;
+ err += x * x + y * y;
+ if (err < minerr) {
+ minerr = err;
+ a2 = a_factor[t1];
+ b2 = b_factor[t2];
+ c2 = c_factor[t3];
+ best_idx=t1+t2*3+t3*9;
+ }
+ }
+ }
+ }
+ if (best_idx==(1+3+9)) {
+ factor *= 0.5;
+ }
+ }
+ io_rot.setAngle(a2, b2, c2);
+ /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */
+ return minerr /4;
+ }
+
+
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMatResult.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMatResult.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMatResult.java (revision 199)
@@ -32,8 +32,6 @@
package jp.nyatla.nyartoolkit.core.transmat;
-import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.NyARRotMatrix;
-import jp.nyatla.nyartoolkit.core.types.*;
import jp.nyatla.nyartoolkit.core.types.matrix.*;
/**
@@ -42,39 +40,5 @@
*/
public class NyARTransMatResult extends NyARDoubleMatrix34
{
- private boolean has_value = false;
-
-
- /**
- * パラメータで変換行列を更新します。
- *
- * @param i_rot
- * @param i_off
- * @param i_trans
- */
- public void updateMatrixValue(NyARRotMatrix i_rot, NyARDoublePoint3d i_off, NyARDoublePoint3d i_trans)
- {
- this.m00=i_rot.m00;
- this.m01=i_rot.m01;
- this.m02=i_rot.m02;
- this.m03=i_rot.m00 * i_off.x + i_rot.m01 * i_off.y + i_rot.m02 * i_off.z + i_trans.x;
-
- this.m10 = i_rot.m10;
- this.m11 = i_rot.m11;
- this.m12 = i_rot.m12;
- this.m13 = i_rot.m10 * i_off.x + i_rot.m11 * i_off.y + i_rot.m12 * i_off.z + i_trans.y;
-
- this.m20 = i_rot.m20;
- this.m21 = i_rot.m21;
- this.m22 = i_rot.m22;
- this.m23 = i_rot.m20 * i_off.x + i_rot.m21 * i_off.y + i_rot.m22 * i_off.z + i_trans.z;
-
- this.has_value = true;
- return;
- }
-
- public boolean hasValue()
- {
- return this.has_value;
- }
+ public boolean has_value = false;
}
Index: trunk/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMat.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMat.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMat.java (revision 199)
@@ -35,8 +35,8 @@
import jp.nyatla.nyartoolkit.core.NyARSquare;
import jp.nyatla.nyartoolkit.core.param.*;
import jp.nyatla.nyartoolkit.core.transmat.fitveccalc.NyARFitVecCalculator;
-import jp.nyatla.nyartoolkit.core.transmat.optimize.NyARRotTransOptimize;
-import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.NyARRotMatrix;
+import jp.nyatla.nyartoolkit.core.transmat.optimize.*;
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;
import jp.nyatla.nyartoolkit.core.types.*;
@@ -49,20 +49,29 @@
{
private final static double AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR = 1.0;
- private final NyARRotMatrix _rotmatrix;
private final NyARDoublePoint2d _center=new NyARDoublePoint2d(0,0);
- private final NyARFitVecCalculator _calculator;
private final NyARTransOffset _offset=new NyARTransOffset();
- private final NyARRotTransOptimize _mat_optimize;
+ protected NyARRotMatrix _rotmatrix;
+ protected NyARFitVecCalculator _calculator;
+ protected INyARRotTransOptimize _mat_optimize;
-
+ /**
+ * 派生クラスで自分でメンバオブジェクトを指定したい場合はこちらを使う。
+ *
+ */
+ protected NyARTransMat()
+ {
+ //_calculator,_rotmatrix,_mat_optimizeをコンストラクタの終了後に
+ //作成して割り当ててください。
+ return;
+ }
public NyARTransMat(NyARParam i_param) throws NyARException
{
final NyARCameraDistortionFactor dist=i_param.getDistortionFactor();
final NyARPerspectiveProjectionMatrix pmat=i_param.getPerspectiveProjectionMatrix();
this._calculator=new NyARFitVecCalculator(pmat,dist);
- this._rotmatrix = new NyARRotMatrix(pmat);
- this._mat_optimize=new NyARRotTransOptimize(pmat);
+ this._rotmatrix = new NyARRotMatrix_ARToolKit(pmat);
+ this._mat_optimize=new NyARRotTransOptimize_O2(pmat);
}
public void setCenter(double i_x, double i_y)
@@ -137,7 +146,7 @@
this._mat_optimize.optimize(this._rotmatrix,trans,this._calculator);
// マトリクスの保存
- o_result_conv.updateMatrixValue(this._rotmatrix, this._offset.point, trans);
+ this.updateMatrixValue(this._rotmatrix, this._offset.point, trans,o_result_conv);
return;
}
/**
@@ -159,7 +168,7 @@
final NyARDoublePoint3d trans=this.__transMat_trans;
// io_result_convが初期値なら、transMatで計算する。
- if (!io_result_conv.hasValue()) {
+ if (!io_result_conv.has_value) {
this.transMat(i_square, i_direction, i_width, io_result_conv);
return;
}
@@ -183,7 +192,7 @@
final double err=this._mat_optimize.optimize(this._rotmatrix,trans,this._calculator);
//計算結果を保存
- io_result_conv.updateMatrixValue(this._rotmatrix, this._offset.point, trans);
+ this.updateMatrixValue(this._rotmatrix, this._offset.point, trans,io_result_conv);
// エラー値が許容範囲でなければTransMatをやり直し
if (err > AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR) {
@@ -196,9 +205,36 @@
//エラー値が低かったら値を差換え
if (err2 < err) {
// 良い値が取れたら、差換え
- io_result_conv.updateMatrixValue(this._rotmatrix, this._offset.point, trans);
+ this.updateMatrixValue(this._rotmatrix, this._offset.point, trans,io_result_conv);
}
}
return;
}
+ /**
+ * パラメータで変換行列を更新します。
+ *
+ * @param i_rot
+ * @param i_off
+ * @param i_trans
+ */
+ public void updateMatrixValue(NyARRotMatrix i_rot, NyARDoublePoint3d i_off, NyARDoublePoint3d i_trans,NyARTransMatResult o_result)
+ {
+ o_result.m00=i_rot.m00;
+ o_result.m01=i_rot.m01;
+ o_result.m02=i_rot.m02;
+ o_result.m03=i_rot.m00 * i_off.x + i_rot.m01 * i_off.y + i_rot.m02 * i_off.z + i_trans.x;
+
+ o_result.m10 = i_rot.m10;
+ o_result.m11 = i_rot.m11;
+ o_result.m12 = i_rot.m12;
+ o_result.m13 = i_rot.m10 * i_off.x + i_rot.m11 * i_off.y + i_rot.m12 * i_off.z + i_trans.y;
+
+ o_result.m20 = i_rot.m20;
+ o_result.m21 = i_rot.m21;
+ o_result.m22 = i_rot.m22;
+ o_result.m23 = i_rot.m20 * i_off.x + i_rot.m21 * i_off.y + i_rot.m22 * i_off.z + i_trans.z;
+
+ o_result.has_value = true;
+ return;
+ }
}
Index: trunk/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix.java (revision 199)
@@ -35,85 +35,18 @@
import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;
import jp.nyatla.nyartoolkit.core.types.*;
import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix33;
-import jp.nyatla.nyartoolkit.core.param.*;
/**
* 回転行列計算用の、3x3行列
*
*/
-public class NyARRotMatrix extends NyARDoubleMatrix33
+public abstract class NyARRotMatrix extends NyARDoubleMatrix33
{
/**
- * インスタンスを準備します。
- *
- * @param i_param
+ * NyARTransMatResultの内容からNyARRotMatrixを復元します。
+ * @param i_prev_result
*/
- public NyARRotMatrix(NyARPerspectiveProjectionMatrix i_matrix) throws NyARException
- {
- this.__initRot_vec1=new NyARRotVector(i_matrix);
- this.__initRot_vec2=new NyARRotVector(i_matrix);
- return;
- }
- final private NyARRotVector __initRot_vec1;
- final private NyARRotVector __initRot_vec2;
-
-
-
- public final void initRotByPrevResult(NyARTransMatResult i_prev_result)
- {
-
- this.m00=i_prev_result.m00;
- this.m01=i_prev_result.m01;
- this.m02=i_prev_result.m02;
-
- this.m10=i_prev_result.m10;
- this.m11=i_prev_result.m11;
- this.m12=i_prev_result.m12;
-
- this.m20=i_prev_result.m20;
- this.m21=i_prev_result.m21;
- this.m22=i_prev_result.m22;
- return;
- }
-
-
- public final void initRotBySquare(final NyARLinear[] i_linear,final NyARDoublePoint2d[] i_sqvertex) throws NyARException
- {
- final NyARRotVector vec1=this.__initRot_vec1;
- final NyARRotVector vec2=this.__initRot_vec2;
-
- //向かい合った辺から、2本のベクトルを計算
-
- //軸1
- vec1.exteriorProductFromLinear(i_linear[0], i_linear[2]);
- vec1.checkVectorByVertex(i_sqvertex[0], i_sqvertex[1]);
-
- //軸2
- vec2.exteriorProductFromLinear(i_linear[1], i_linear[3]);
- vec2.checkVectorByVertex(i_sqvertex[3], i_sqvertex[0]);
-
- //回転の最適化?
- NyARRotVector.checkRotation(vec1,vec2);
-
- this.m00 =vec1.v1;
- this.m10 =vec1.v2;
- this.m20 =vec1.v3;
- this.m01 =vec2.v1;
- this.m11 =vec2.v2;
- this.m21 =vec2.v3;
-
- //最後の軸を計算
- final double w02 = vec1.v2 * vec2.v3 - vec1.v3 * vec2.v2;
- final double w12 = vec1.v3 * vec2.v1 - vec1.v1 * vec2.v3;
- final double w22 = vec1.v1 * vec2.v2 - vec1.v2 * vec2.v1;
- final double w = Math.sqrt(w02 * w02 + w12 * w12 + w22 * w22);
- this.m02 = w02/w;
- this.m12 = w12/w;
- this.m22 = w22/w;
- return;
- }
-
-
-
+ public abstract void initRotByPrevResult(NyARTransMatResult i_prev_result);
+ public abstract void initRotBySquare(final NyARLinear[] i_linear,final NyARDoublePoint2d[] i_sqvertex) throws NyARException;
/**
* int arGetAngle( double rot[3][3], double *wa, double *wb, double *wc )
* Optimize:2008.04.20:STEP[481→433]
@@ -121,182 +54,25 @@
* @param o_angle
* @return
*/
- public final void getAngle(final NyARDoublePoint3d o_angle)
- {
- double a,b,c;
- double sina, cosa, sinb,cosb,sinc, cosc;
-
- if (this.m22 > 1.0) {// <Optimize/>if( rot[2][2] > 1.0 ) {
- this.m22 = 1.0;// <Optimize/>rot[2][2] = 1.0;
- } else if (this.m22 < -1.0) {// <Optimize/>}else if( rot[2][2] < -1.0 ) {
- this.m22 = -1.0;// <Optimize/>rot[2][2] = -1.0;
- }
- cosb =this.m22;// <Optimize/>cosb = rot[2][2];
- b = Math.acos(cosb);
- sinb =Math.sin(b);
- final double rot02=this.m02;
- final double rot12=this.m12;
- if (b >= 0.000001 || b <= -0.000001) {
- cosa = rot02 / sinb;// <Optimize/>cosa = rot[0][2] / sinb;
- sina = rot12 / sinb;// <Optimize/>sina = rot[1][2] / sinb;
- if (cosa > 1.0) {
- /* printf("cos(alph) = %f\n", cosa); */
- cosa = 1.0;
- sina = 0.0;
- }
- if (cosa < -1.0) {
- /* printf("cos(alph) = %f\n", cosa); */
- cosa = -1.0;
- sina = 0.0;
- }
- if (sina > 1.0) {
- /* printf("sin(alph) = %f\n", sina); */
- sina = 1.0;
- cosa = 0.0;
- }
- if (sina < -1.0) {
- /* printf("sin(alph) = %f\n", sina); */
- sina = -1.0;
- cosa = 0.0;
- }
- a = Math.acos(cosa);
- if (sina < 0) {
- a = -a;
- }
- // <Optimize>
- // sinc = (rot[2][1]*rot[0][2]-rot[2][0]*rot[1][2])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);
- // cosc = -(rot[0][2]*rot[2][0]+rot[1][2]*rot[2][1])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);
- final double tmp = (rot02 * rot02 + rot12 * rot12);
- sinc = (this.m21 * rot02 - this.m20 * rot12) / tmp;
- cosc = -(rot02 * this.m20 + rot12 * this.m21) / tmp;
- // </Optimize>
-
- if (cosc > 1.0) {
- /* printf("cos(r) = %f\n", cosc); */
- cosc = 1.0;
- sinc = 0.0;
- }
- if (cosc < -1.0) {
- /* printf("cos(r) = %f\n", cosc); */
- cosc = -1.0;
- sinc = 0.0;
- }
- if (sinc > 1.0) {
- /* printf("sin(r) = %f\n", sinc); */
- sinc = 1.0;
- cosc = 0.0;
- }
- if (sinc < -1.0) {
- /* printf("sin(r) = %f\n", sinc); */
- sinc = -1.0;
- cosc = 0.0;
- }
- c = Math.acos(cosc);
- if (sinc < 0) {
- c = -c;
- }
- } else {
- a = b = 0.0;
- cosa = cosb = 1.0;
- sina = sinb = 0.0;
- cosc=this.m00;//cosc = rot[0];// <Optimize/>cosc = rot[0][0];
- sinc=this.m01;//sinc = rot[1];// <Optimize/>sinc = rot[1][0];
- if (cosc > 1.0) {
- /* printf("cos(r) = %f\n", cosc); */
- cosc = 1.0;
- sinc = 0.0;
- }
- if (cosc < -1.0) {
- /* printf("cos(r) = %f\n", cosc); */
- cosc = -1.0;
- sinc = 0.0;
- }
- if (sinc > 1.0) {
- /* printf("sin(r) = %f\n", sinc); */
- sinc = 1.0;
- cosc = 0.0;
- }
- if (sinc < -1.0) {
- /* printf("sin(r) = %f\n", sinc); */
- sinc = -1.0;
- cosc = 0.0;
- }
- c = Math.acos(cosc);
- if (sinc < 0) {
- c = -c;
- }
- }
- o_angle.x = a;// wa.value=a;//*wa = a;
- o_angle.y = b;// wb.value=b;//*wb = b;
- o_angle.z = c;// wc.value=c;//*wc = c;
- return;
- }
+ public abstract void getAngle(final NyARDoublePoint3d o_angle);
/**
* 回転角から回転行列を計算してセットします。
* @param i_x
* @param i_y
* @param i_z
*/
- public final void setAngle(final double i_x, final double i_y, final double i_z)
- {
- final double sina = Math.sin(i_x);
- final double cosa = Math.cos(i_x);
- final double sinb = Math.sin(i_y);
- final double cosb = Math.cos(i_y);
- final double sinc = Math.sin(i_z);
- final double cosc = Math.cos(i_z);
- // Optimize
- final double CACA = cosa * cosa;
- final double SASA = sina * sina;
- final double SACA = sina * cosa;
- final double SASB = sina * sinb;
- final double CASB = cosa * sinb;
- final double SACACB = SACA * cosb;
-
- this.m00 = CACA * cosb * cosc + SASA * cosc + SACACB * sinc - SACA * sinc;
- this.m01 = -CACA * cosb * sinc - SASA * sinc + SACACB * cosc - SACA * cosc;
- this.m02 = CASB;
- this.m10 = SACACB * cosc - SACA * cosc + SASA * cosb * sinc + CACA * sinc;
- this.m11 = -SACACB * sinc + SACA * sinc + SASA * cosb * cosc + CACA * cosc;
- this.m12 = SASB;
- this.m20 = -CASB * cosc - SASB * sinc;
- this.m21 = CASB * sinc - SASB * cosc;
- this.m22 = cosb;
- return;
- }
+ public abstract void setAngle(final double i_x, final double i_y, final double i_z);
/**
* i_in_pointを変換行列で座標変換する。
* @param i_in_point
* @param i_out_point
- */
- public final void getPoint3d(final NyARDoublePoint3d i_in_point,final NyARDoublePoint3d i_out_point)
- {
- final double x=i_in_point.x;
- final double y=i_in_point.y;
- final double z=i_in_point.z;
- i_out_point.x=this.m00 * x + this.m01 * y + this.m02 * z;
- i_out_point.y=this.m10 * x + this.m11 * y + this.m12 * z;
- i_out_point.z=this.m20 * x + this.m21 * y + this.m22 * z;
- return;
- }
+ */
+ public abstract void getPoint3d(final NyARDoublePoint3d i_in_point,final NyARDoublePoint3d i_out_point);
/**
* 複数の頂点を一括して変換する
* @param i_in_point
* @param i_out_point
* @param i_number_of_vertex
*/
- public final void getPoint3dBatch(final NyARDoublePoint3d[] i_in_point,NyARDoublePoint3d[] i_out_point,int i_number_of_vertex)
- {
- for(int i=i_number_of_vertex-1;i>=0;i--){
- final NyARDoublePoint3d out_ptr=i_out_point[i];
- final NyARDoublePoint3d in_ptr=i_in_point[i];
- final double x=in_ptr.x;
- final double y=in_ptr.y;
- final double z=in_ptr.z;
- out_ptr.x=this.m00 * x + this.m01 * y + this.m02 * z;
- out_ptr.y=this.m10 * x + this.m11 * y + this.m12 * z;
- out_ptr.z=this.m20 * x + this.m21 * y + this.m22 * z;
- }
- return;
- }
+ public abstract void getPoint3dBatch(final NyARDoublePoint3d[] i_in_point,NyARDoublePoint3d[] i_out_point,int i_number_of_vertex);
}
Index: trunk/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix_ARToolKit.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix_ARToolKit.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix_ARToolKit.java (revision 199)
@@ -0,0 +1,301 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core.transmat.rotmatrix;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+/**
+ * 回転行列計算用の、3x3行列
+ *
+ */
+public class NyARRotMatrix_ARToolKit extends NyARRotMatrix
+{
+ /**
+ * インスタンスを準備します。
+ *
+ * @param i_param
+ */
+ public NyARRotMatrix_ARToolKit(NyARPerspectiveProjectionMatrix i_matrix) throws NyARException
+ {
+ this.__initRot_vec1=new NyARRotVector(i_matrix);
+ this.__initRot_vec2=new NyARRotVector(i_matrix);
+ return;
+ }
+ final private NyARRotVector __initRot_vec1;
+ final private NyARRotVector __initRot_vec2;
+
+
+
+ public final void initRotByPrevResult(NyARTransMatResult i_prev_result)
+ {
+
+ this.m00=i_prev_result.m00;
+ this.m01=i_prev_result.m01;
+ this.m02=i_prev_result.m02;
+
+ this.m10=i_prev_result.m10;
+ this.m11=i_prev_result.m11;
+ this.m12=i_prev_result.m12;
+
+ this.m20=i_prev_result.m20;
+ this.m21=i_prev_result.m21;
+ this.m22=i_prev_result.m22;
+ return;
+ }
+
+
+ public final void initRotBySquare(final NyARLinear[] i_linear,final NyARDoublePoint2d[] i_sqvertex) throws NyARException
+ {
+ final NyARRotVector vec1=this.__initRot_vec1;
+ final NyARRotVector vec2=this.__initRot_vec2;
+
+ //向かい合った辺から、2本のベクトルを計算
+
+ //軸1
+ vec1.exteriorProductFromLinear(i_linear[0], i_linear[2]);
+ vec1.checkVectorByVertex(i_sqvertex[0], i_sqvertex[1]);
+
+ //軸2
+ vec2.exteriorProductFromLinear(i_linear[1], i_linear[3]);
+ vec2.checkVectorByVertex(i_sqvertex[3], i_sqvertex[0]);
+
+ //回転の最適化?
+ NyARRotVector.checkRotation(vec1,vec2);
+
+ this.m00 =vec1.v1;
+ this.m10 =vec1.v2;
+ this.m20 =vec1.v3;
+ this.m01 =vec2.v1;
+ this.m11 =vec2.v2;
+ this.m21 =vec2.v3;
+
+ //最後の軸を計算
+ final double w02 = vec1.v2 * vec2.v3 - vec1.v3 * vec2.v2;
+ final double w12 = vec1.v3 * vec2.v1 - vec1.v1 * vec2.v3;
+ final double w22 = vec1.v1 * vec2.v2 - vec1.v2 * vec2.v1;
+ final double w = Math.sqrt(w02 * w02 + w12 * w12 + w22 * w22);
+ this.m02 = w02/w;
+ this.m12 = w12/w;
+ this.m22 = w22/w;
+ return;
+ }
+
+
+
+ /**
+ * int arGetAngle( double rot[3][3], double *wa, double *wb, double *wc )
+ * Optimize:2008.04.20:STEP[481→433]
+ * 3x3変換行列から、回転角を復元して返します。
+ * @param o_angle
+ * @return
+ */
+ public final void getAngle(final NyARDoublePoint3d o_angle)
+ {
+ double a,b,c;
+ double sina, cosa, sinb,cosb,sinc, cosc;
+
+ if (this.m22 > 1.0) {// <Optimize/>if( rot[2][2] > 1.0 ) {
+ this.m22 = 1.0;// <Optimize/>rot[2][2] = 1.0;
+ } else if (this.m22 < -1.0) {// <Optimize/>}else if( rot[2][2] < -1.0 ) {
+ this.m22 = -1.0;// <Optimize/>rot[2][2] = -1.0;
+ }
+ cosb =this.m22;// <Optimize/>cosb = rot[2][2];
+ b = Math.acos(cosb);
+ sinb =Math.sin(b);
+ final double rot02=this.m02;
+ final double rot12=this.m12;
+ if (b >= 0.000001 || b <= -0.000001) {
+ cosa = rot02 / sinb;// <Optimize/>cosa = rot[0][2] / sinb;
+ sina = rot12 / sinb;// <Optimize/>sina = rot[1][2] / sinb;
+ if (cosa > 1.0) {
+ /* printf("cos(alph) = %f\n", cosa); */
+ cosa = 1.0;
+ sina = 0.0;
+ }
+ if (cosa < -1.0) {
+ /* printf("cos(alph) = %f\n", cosa); */
+ cosa = -1.0;
+ sina = 0.0;
+ }
+ if (sina > 1.0) {
+ /* printf("sin(alph) = %f\n", sina); */
+ sina = 1.0;
+ cosa = 0.0;
+ }
+ if (sina < -1.0) {
+ /* printf("sin(alph) = %f\n", sina); */
+ sina = -1.0;
+ cosa = 0.0;
+ }
+ a = Math.acos(cosa);
+ if (sina < 0) {
+ a = -a;
+ }
+ // <Optimize>
+ // sinc = (rot[2][1]*rot[0][2]-rot[2][0]*rot[1][2])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);
+ // cosc = -(rot[0][2]*rot[2][0]+rot[1][2]*rot[2][1])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);
+ final double tmp = (rot02 * rot02 + rot12 * rot12);
+ sinc = (this.m21 * rot02 - this.m20 * rot12) / tmp;
+ cosc = -(rot02 * this.m20 + rot12 * this.m21) / tmp;
+ // </Optimize>
+
+ if (cosc > 1.0) {
+ /* printf("cos(r) = %f\n", cosc); */
+ cosc = 1.0;
+ sinc = 0.0;
+ }
+ if (cosc < -1.0) {
+ /* printf("cos(r) = %f\n", cosc); */
+ cosc = -1.0;
+ sinc = 0.0;
+ }
+ if (sinc > 1.0) {
+ /* printf("sin(r) = %f\n", sinc); */
+ sinc = 1.0;
+ cosc = 0.0;
+ }
+ if (sinc < -1.0) {
+ /* printf("sin(r) = %f\n", sinc); */
+ sinc = -1.0;
+ cosc = 0.0;
+ }
+ c = Math.acos(cosc);
+ if (sinc < 0) {
+ c = -c;
+ }
+ } else {
+ a = b = 0.0;
+ cosa = cosb = 1.0;
+ sina = sinb = 0.0;
+ cosc=this.m00;//cosc = rot[0];// <Optimize/>cosc = rot[0][0];
+ sinc=this.m01;//sinc = rot[1];// <Optimize/>sinc = rot[1][0];
+ if (cosc > 1.0) {
+ /* printf("cos(r) = %f\n", cosc); */
+ cosc = 1.0;
+ sinc = 0.0;
+ }
+ if (cosc < -1.0) {
+ /* printf("cos(r) = %f\n", cosc); */
+ cosc = -1.0;
+ sinc = 0.0;
+ }
+ if (sinc > 1.0) {
+ /* printf("sin(r) = %f\n", sinc); */
+ sinc = 1.0;
+ cosc = 0.0;
+ }
+ if (sinc < -1.0) {
+ /* printf("sin(r) = %f\n", sinc); */
+ sinc = -1.0;
+ cosc = 0.0;
+ }
+ c = Math.acos(cosc);
+ if (sinc < 0) {
+ c = -c;
+ }
+ }
+ o_angle.x = a;// wa.value=a;//*wa = a;
+ o_angle.y = b;// wb.value=b;//*wb = b;
+ o_angle.z = c;// wc.value=c;//*wc = c;
+ return;
+ }
+ /**
+ * 回転角から回転行列を計算してセットします。
+ * @param i_x
+ * @param i_y
+ * @param i_z
+ */
+ public final void setAngle(final double i_x, final double i_y, final double i_z)
+ {
+ final double sina = Math.sin(i_x);
+ final double cosa = Math.cos(i_x);
+ final double sinb = Math.sin(i_y);
+ final double cosb = Math.cos(i_y);
+ final double sinc = Math.sin(i_z);
+ final double cosc = Math.cos(i_z);
+ // Optimize
+ final double CACA = cosa * cosa;
+ final double SASA = sina * sina;
+ final double SACA = sina * cosa;
+ final double SASB = sina * sinb;
+ final double CASB = cosa * sinb;
+ final double SACACB = SACA * cosb;
+
+ this.m00 = CACA * cosb * cosc + SASA * cosc + SACACB * sinc - SACA * sinc;
+ this.m01 = -CACA * cosb * sinc - SASA * sinc + SACACB * cosc - SACA * cosc;
+ this.m02 = CASB;
+ this.m10 = SACACB * cosc - SACA * cosc + SASA * cosb * sinc + CACA * sinc;
+ this.m11 = -SACACB * sinc + SACA * sinc + SASA * cosb * cosc + CACA * cosc;
+ this.m12 = SASB;
+ this.m20 = -CASB * cosc - SASB * sinc;
+ this.m21 = CASB * sinc - SASB * cosc;
+ this.m22 = cosb;
+ return;
+ }
+ /**
+ * i_in_pointを変換行列で座標変換する。
+ * @param i_in_point
+ * @param i_out_point
+ */
+ public final void getPoint3d(final NyARDoublePoint3d i_in_point,final NyARDoublePoint3d i_out_point)
+ {
+ final double x=i_in_point.x;
+ final double y=i_in_point.y;
+ final double z=i_in_point.z;
+ i_out_point.x=this.m00 * x + this.m01 * y + this.m02 * z;
+ i_out_point.y=this.m10 * x + this.m11 * y + this.m12 * z;
+ i_out_point.z=this.m20 * x + this.m21 * y + this.m22 * z;
+ return;
+ }
+ /**
+ * 複数の頂点を一括して変換する
+ * @param i_in_point
+ * @param i_out_point
+ * @param i_number_of_vertex
+ */
+ public final void getPoint3dBatch(final NyARDoublePoint3d[] i_in_point,NyARDoublePoint3d[] i_out_point,int i_number_of_vertex)
+ {
+ for(int i=i_number_of_vertex-1;i>=0;i--){
+ final NyARDoublePoint3d out_ptr=i_out_point[i];
+ final NyARDoublePoint3d in_ptr=i_in_point[i];
+ final double x=in_ptr.x;
+ final double y=in_ptr.y;
+ final double z=in_ptr.z;
+ out_ptr.x=this.m00 * x + this.m01 * y + this.m02 * z;
+ out_ptr.y=this.m10 * x + this.m11 * y + this.m12 * z;
+ out_ptr.z=this.m20 * x + this.m21 * y + this.m22 * z;
+ }
+ return;
+ }
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core/NyARMat.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/NyARMat.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/NyARMat.java (revision 199)
@@ -47,7 +47,7 @@
*/
protected double[][] m;
- private int clm, row;
+ protected int clm, row;
/**
* デフォルトコンストラクタは機能しません。
Index: trunk/src/jp/nyatla/nyartoolkit/core/raster/NyARGlayscaleRaster.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/raster/NyARGlayscaleRaster.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/raster/NyARGlayscaleRaster.java (revision 199)
@@ -1,54 +0,0 @@
-/*
- * PROJECT: NyARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- * Hirokazu Kato
- * Mark Billinghurst
- * HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * The NyARToolkit is Java version ARToolkit class library.
- * Copyright (C)2008 R.Iizuka
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this framework; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * For further information please contact.
- * http://nyatla.jp/nyatoolkit/
- * <airmail(at)ebony.plala.or.jp>
- *
- */
-package jp.nyatla.nyartoolkit.core.raster;
-
-import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;
-import jp.nyatla.nyartoolkit.core.rasterreader.NyARBufferReader;
-import jp.nyatla.nyartoolkit.core.types.*;
-
-public final class NyARGlayscaleRaster extends NyARRaster_BasicClass
-{
-
- protected int[][] _ref_buf;
- private INyARBufferReader _buffer_reader;
-
- public NyARGlayscaleRaster(int i_width, int i_height)
- {
- super(new NyARIntSize(i_width,i_height));
- this._ref_buf = new int[i_height][i_width];
- this._buffer_reader=new NyARBufferReader(this._ref_buf,INyARBufferReader.BUFFERFORMAT_INT2D_GLAY_8);
- }
- public INyARBufferReader getBufferReader()
- {
- return this._buffer_reader;
- }
-}
Index: trunk/src/jp/nyatla/nyartoolkit/core/raster/NyARGrayscaleRaster.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/raster/NyARGrayscaleRaster.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core/raster/NyARGrayscaleRaster.java (revision 199)
@@ -0,0 +1,54 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core.raster;
+
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;
+import jp.nyatla.nyartoolkit.core.rasterreader.NyARBufferReader;
+import jp.nyatla.nyartoolkit.core.types.*;
+
+public final class NyARGrayscaleRaster extends NyARRaster_BasicClass
+{
+
+ protected int[][] _ref_buf;
+ private INyARBufferReader _buffer_reader;
+
+ public NyARGrayscaleRaster(int i_width, int i_height)
+ {
+ super(new NyARIntSize(i_width,i_height));
+ this._ref_buf = new int[i_height][i_width];
+ this._buffer_reader=new NyARBufferReader(this._ref_buf,INyARBufferReader.BUFFERFORMAT_INT2D_GLAY_8);
+ }
+ public INyARBufferReader getBufferReader()
+ {
+ return this._buffer_reader;
+ }
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core/param/NyARCameraDistortionFactor.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/param/NyARCameraDistortionFactor.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/param/NyARCameraDistortionFactor.java (revision 199)
@@ -32,7 +32,6 @@
package jp.nyatla.nyartoolkit.core.param;
import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;
-import jp.nyatla.utils.DoubleValue;
/**
* カメラの歪み成分を格納するクラスと、補正関数群
@@ -44,13 +43,21 @@
* p=(1-fd^2)
* xd=px+x0,yd=py+y0
*/
-final public class NyARCameraDistortionFactor
+public class NyARCameraDistortionFactor implements INyARCameraDistortionFactor
{
private static final int PD_LOOP = 3;
private double _f0;//x0
private double _f1;//y0
private double _f2;//100000000.0*f
private double _f3;//s
+ public void copyFrom(NyARCameraDistortionFactor i_ref)
+ {
+ this._f0=i_ref._f0;
+ this._f1=i_ref._f1;
+ this._f2=i_ref._f2;
+ this._f3=i_ref._f3;
+ return;
+ }
/**
* 配列の値をファクタ値としてセットする。
* @param i_factor
@@ -131,20 +138,20 @@
/**
* int arParamObserv2Ideal( const double dist_factor[4], const double ox,const double oy,double *ix, double *iy );
*
- * @param ox
- * @param oy
* @param ix
* @param iy
+ * @param ix
+ * @param iy
* @return
*/
- public void observ2Ideal(double ox, double oy, DoubleValue ix, DoubleValue iy)
+ public void observ2Ideal(double ix, double iy, NyARDoublePoint2d o_point)
{
double z02, z0, p, q, z, px, py, opttmp_1;
final double d0 = this._f0;
final double d1 = this._f1;
- px = ox - d0;
- py = oy - d1;
+ px = ix - d0;
+ py = iy - d1;
p = this._f2 / 100000000.0;
z02 = px * px + py * py;
q = z0 = Math.sqrt(z02);// Optimize//q = z0 = Math.sqrt(px*px+ py*py);
@@ -167,14 +174,13 @@
z02 = px * px + py * py;
z0 = Math.sqrt(z02);// Optimize//z0 = Math.sqrt(px*px+ py*py);
}
- ix.value = px / this._f3 + d0;
- iy.value = py / this._f3 + d1;
+ o_point.x = px / this._f3 + d0;
+ o_point.y = py / this._f3 + d1;
return;
}
/**
* 指定範囲のobserv2Idealをまとめて実行して、結果をo_idealに格納します。
- *
* @param i_x_coord
* @param i_y_coord
* @param i_start
@@ -184,7 +190,7 @@
* @param o_ideal
* 出力バッファ[i_num][2]であること。
*/
- public void observ2IdealBatch(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num, double[][] o_ideal)
+ public void observ2IdealBatch(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num, double[] o_x_coord,double[] o_y_coord)
{
double z02, z0, q, z, px, py, opttmp_1;
final double d0 = this._f0;
@@ -217,8 +223,8 @@
z02 = px * px + py * py;
z0 = Math.sqrt(z02);// Optimize//z0 = Math.sqrt(px*px+ py*py);
}
- o_ideal[j][0] = px / d3 + d0;
- o_ideal[j][1] = py / d3 + d1;
+ o_x_coord[j] = px / d3 + d0;
+ o_y_coord[j] = py / d3 + d1;
}
return;
}
Index: trunk/src/jp/nyatla/nyartoolkit/core/param/INyARCameraDistortionFactor.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/param/INyARCameraDistortionFactor.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core/param/INyARCameraDistortionFactor.java (revision 199)
@@ -0,0 +1,43 @@
+package jp.nyatla.nyartoolkit.core.param;
+
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;
+
+public interface INyARCameraDistortionFactor
+{
+ /**
+ * int arParamIdeal2Observ( const double dist_factor[4], const double ix,const double iy,double *ox, double *oy ) 関数の代替関数
+ *
+ * @param i_in
+ * @param o_out
+ */
+ public void ideal2Observ(final NyARDoublePoint2d i_in, NyARDoublePoint2d o_out);
+ /**
+ * ideal2Observをまとめて実行します。
+ * @param i_in
+ * @param o_out
+ */
+ public void ideal2ObservBatch(final NyARDoublePoint2d[] i_in, NyARDoublePoint2d[] o_out, int i_size);
+ /**
+ * int arParamObserv2Ideal( const double dist_factor[4], const double ox,const double oy,double *ix, double *iy );
+ *
+ * @param ix
+ * @param iy
+ * @param ix
+ * @param iy
+ * @return
+ */
+ public void observ2Ideal(double ix, double iy, NyARDoublePoint2d o_point);
+ /**
+ * 指定範囲のobserv2Idealをまとめて実行して、結果をo_idealに格納します。
+ * @param i_x_coord
+ * @param i_y_coord
+ * @param i_start
+ * coord開始点
+ * @param i_num
+ * 計算数
+ * @param o_ideal
+ * 出力バッファ[i_num][2]であること。
+ */
+ public void observ2IdealBatch(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num, double[] o_x_coord,double[] o_y_coord);
+
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core/param/NyARObserv2IdealMap.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/param/NyARObserv2IdealMap.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core/param/NyARObserv2IdealMap.java (revision 199)
@@ -0,0 +1,83 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core.param;
+
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;
+import jp.nyatla.nyartoolkit.core.types.*;
+/**
+ * 歪み成分マップを使用するINyARCameraDistortionFactor
+ */
+final public class NyARObserv2IdealMap
+{
+ private int _stride;
+ private double[] _mapx;
+ private double[] _mapy;
+ public NyARObserv2IdealMap(NyARCameraDistortionFactor i_distfactor,NyARIntSize i_screen_size)
+ {
+ NyARDoublePoint2d opoint=new NyARDoublePoint2d();
+ this._mapx=new double[i_screen_size.w*i_screen_size.h];
+ this._mapy=new double[i_screen_size.w*i_screen_size.h];
+ this._stride=i_screen_size.w;
+ int ptr=i_screen_size.h*i_screen_size.w-1;
+ //歪みマップを構築
+ for(int i=i_screen_size.h-1;i>=0;i--)
+ {
+ for(int i2=i_screen_size.w-1;i2>=0;i2--)
+ {
+ i_distfactor.observ2Ideal(i2,i, opoint);
+ this._mapx[ptr]=opoint.x;
+ this._mapy[ptr]=opoint.y;
+ ptr--;
+ }
+ }
+ return;
+ }
+ public void observ2Ideal(double ix, double iy, NyARDoublePoint2d o_point)
+ {
+ int idx=(int)ix+(int)iy*this._stride;
+ o_point.x=this._mapx[idx];
+ o_point.y=this._mapy[idx];
+ return;
+ }
+ public void observ2IdealBatch(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num, double[] o_x_coord,double[] o_y_coord)
+ {
+ int idx;
+ int ptr=0;
+ for (int j = 0; j < i_num; j++) {
+ idx=i_x_coord[i_start + j]+i_y_coord[i_start + j]*this._stride;
+ o_x_coord[ptr]=this._mapx[idx];
+ o_y_coord[ptr]=this._mapy[idx];
+ ptr++;
+ }
+ return;
+ }
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core/NyARSquareStack.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/NyARSquareStack.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/NyARSquareStack.java (revision 199)
@@ -31,7 +31,6 @@
*/
package jp.nyatla.nyartoolkit.core;
-import jp.nyatla.nyartoolkit.NyARException;
import jp.nyatla.utils.*;
public class NyARSquareStack extends NyObjectStack
Index: trunk/src/jp/nyatla/nyartoolkit/core/NyARSquareDetector.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/NyARSquareDetector.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/NyARSquareDetector.java (revision 199)
@@ -35,11 +35,13 @@
import jp.nyatla.nyartoolkit.core.raster.*;
import jp.nyatla.nyartoolkit.core.types.*;
import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.pca2d.NyARPca2d_MatrixPCA_O2;
+import jp.nyatla.nyartoolkit.core.types.matrix.*;
+import jp.nyatla.nyartoolkit.core.pca2d.*;
-
/**
* イメージから正方形候補を検出するクラス。
* このクラスは、arDetectMarker2.cとの置き換えになります。
@@ -48,9 +50,7 @@
public class NyARSquareDetector implements INyARSquareDetector
{
private static final double VERTEX_FACTOR = 1.0;// 線検出のファクタ
-
private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000
-
private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70
private final int _width;
private final int _height;
@@ -60,7 +60,10 @@
private final NyARLabelingImage _limage;
private final OverlapChecker _overlap_checker = new OverlapChecker();
- private final NyARCameraDistortionFactor _dist_factor_ref;
+ private final NyARObserv2IdealMap _dist_factor;
+
+ private final double[] _xpos;
+ private final double[] _ypos;
/**
* 最大i_squre_max個のマーカーを検出するクラスを作成する。
@@ -71,7 +74,9 @@
{
this._width = i_size.w;
this._height = i_size.h;
- this._dist_factor_ref = i_dist_factor_ref;
+ //歪み計算テーブルを作ると、8*width/height*2の領域を消費します。
+ //領域を取りたくない場合は、i_dist_factor_refの値をそのまま使ってください。
+ this._dist_factor = new NyARObserv2IdealMap(i_dist_factor_ref,i_size);
this._labeling = new NyARLabeling_ARToolKit();
this._limage = new NyARLabelingImage(this._width, this._height);
this._labeling.attachDestination(this._limage);
@@ -83,6 +88,10 @@
this._max_coord = number_of_coord;
this._xcoord = new int[number_of_coord * 2];
this._ycoord = new int[number_of_coord * 2];
+ this._pca=new NyARPca2d_MatrixPCA_O2();
+ this._xpos=new double[this._width+this._height];//最大辺長はthis._width+this._height
+ this._ypos=new double[this._width+this._height];//最大辺長はthis._width+this._height
+ return;
}
private final int _max_coord;
@@ -99,9 +108,9 @@
private final int[] __detectMarker_mkvertex = new int[5];
/**
- * ARMarkerInfo2 *arDetectMarker2( ARInt16 *limage, int label_num, int *label_ref,int *warea, double *wpos, int *wclip,int area_max, int area_min, double
- * factor, int *marker_num ) 関数の代替品 ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。 関数はo_marker_listに重なりを除外したマーカーリストを作成します。
- *
+ * arDetectMarker2を基にした関数
+ * この関数はNyARSquare要素のうち、directionを除くパラメータを取得して返します。
+ * directionの確定は行いません。
* @param i_raster
* 解析する2値ラスタイメージを指定します。
* @param o_square_stack
@@ -197,7 +206,7 @@
o_square_stack.pop();// 頂点の取得が出来なかったので破棄
continue;
}
-
+ // マーカーを検出
if (!getSquareLine(mkvertex, xcoord, ycoord, square_ptr)) {
// 矩形が成立しなかった。
o_square_stack.pop();
@@ -328,14 +337,10 @@
return true;
}
- private final NyARMat __getSquareLine_input = new NyARMat(1, 2);
-
- private final NyARMat __getSquareLine_evec = new NyARMat(2, 2);
-
- private final NyARVec __getSquareLine_ev = new NyARVec(2);
-
- private final NyARVec __getSquareLine_mean = new NyARVec(2);
-
+ private final INyARPca2d _pca;
+ private final NyARDoubleMatrix22 __getSquareLine_evec=new NyARDoubleMatrix22();
+ private final NyARDoublePoint2d __getSquareLine_mean=new NyARDoublePoint2d();
+ private final NyARDoublePoint2d __getSquareLine_ev=new NyARDoublePoint2d();
/**
* arGetLine(int x_coord[], int y_coord[], int coord_num,int vertex[], double line[4][3], double v[4][2]) arGetLine2(int x_coord[], int y_coord[], int
* coord_num,int vertex[], double line[4][3], double v[4][2], double *dist_factor) の2関数の合成品です。 マーカーのvertex,lineを計算して、結果をo_squareに保管します。
@@ -348,13 +353,11 @@
private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square) throws NyARException
{
final NyARLinear[] l_line = o_square.line;
- final NyARVec ev = this.__getSquareLine_ev; // matrixPCAの戻り値を受け取る
- final NyARVec mean = this.__getSquareLine_mean;// matrixPCAの戻り値を受け取る
- final double[] mean_array = mean.getArray();
- final NyARCameraDistortionFactor dist_factor=this._dist_factor_ref;
- final NyARMat input = this.__getSquareLine_input;// 次処理で初期化される。
- final NyARMat evec = this.__getSquareLine_evec;// アウトパラメータを受け取るから初期化不要//new NyARMat(2,2);
- final double[][] evec_array = evec.getArray();
+ final NyARDoubleMatrix22 evec=this.__getSquareLine_evec;
+ final NyARDoublePoint2d mean=this.__getSquareLine_mean;
+ final NyARDoublePoint2d ev=this.__getSquareLine_ev;
+
+
for (int i = 0; i < 4; i++) {
final double w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;
final int st = (int) (i_mkvertex[i] + w1);
@@ -364,17 +367,15 @@
// nが2以下でmatrix.PCAを計算することはできないので、エラー
return false;
}
- // pcaの準備
- input.realloc(n, 2);
- // バッチ取得
- dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st, n, input.getArray());
-
- // 主成分分析
- input.matrixPCA(evec, ev, mean);
+ //配列作成
+ this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st, n,this._xpos,this._ypos);
+
+ //主成分分析する。
+ this._pca.pca(this._xpos,this._ypos,n,evec, ev,mean);
final NyARLinear l_line_i = l_line[i];
- l_line_i.run = evec_array[0][1];// line[i][0] = evec->m[1];
- l_line_i.rise = -evec_array[0][0];// line[i][1] = -evec->m[0];
- l_line_i.intercept = -(l_line_i.run * mean_array[0] + l_line_i.rise * mean_array[1]);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);
+ l_line_i.run = evec.m01;// line[i][0] = evec->m[1];
+ l_line_i.rise = -evec.m00;// line[i][1] = -evec->m[0];
+ l_line_i.intercept = -(l_line_i.run * mean.x + l_line_i.rise * mean.y);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);
}
final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;
@@ -396,77 +397,11 @@
}
}
-/**
- * get_vertex関数を切り離すためのクラス
- *
- */
-final class NyARVertexCounter
-{
- public final int[] vertex = new int[10];// 5まで削れる
- public int number_of_vertex;
- private double thresh;
-
- private int[] x_coord;
-
- private int[] y_coord;
-
- public boolean getVertex(int[] i_x_coord, int[] i_y_coord, int st, int ed, double i_thresh)
- {
- this.number_of_vertex = 0;
- this.thresh = i_thresh;
- this.x_coord = i_x_coord;
- this.y_coord = i_y_coord;
- return get_vertex(st, ed);
- }
-
- /**
- * static int get_vertex( int x_coord[], int y_coord[], int st, int ed,double thresh, int vertex[], int *vnum) 関数の代替関数
- *
- * @param x_coord
- * @param y_coord
- * @param st
- * @param ed
- * @param thresh
- * @return
- */
- private boolean get_vertex(int st, int ed)
- {
- int v1 = 0;
- final int[] lx_coord = this.x_coord;
- final int[] ly_coord = this.y_coord;
- final double a = ly_coord[ed] - ly_coord[st];
- final double b = lx_coord[st] - lx_coord[ed];
- final double c = lx_coord[ed] * ly_coord[st] - ly_coord[ed] * lx_coord[st];
- double dmax = 0;
- for (int i = st + 1; i < ed; i++) {
- final double d = a * lx_coord[i] + b * ly_coord[i] + c;
- if (d * d > dmax) {
- dmax = d * d;
- v1 = i;
- }
- }
- if (dmax / (a * a + b * b) > thresh) {
- if (!get_vertex(st, v1)) {
- return false;
- }
- if (number_of_vertex > 5) {
- return false;
- }
- vertex[number_of_vertex] = v1;// vertex[(*vnum)] = v1;
- number_of_vertex++;// (*vnum)++;
-
- if (!get_vertex(v1, ed)) {
- return false;
- }
- }
- return true;
- }
-}
-
/**
- * ラベル同士の重なり(内包関係)を調べるクラスです。 ラベルリストに内包するラベルを蓄積し、それにターゲットのラベルが内包されているか を確認します。
+ * ラベル同士の重なり(内包関係)を調べるクラスです。
+ * ラベルリストに内包するラベルを蓄積し、それにターゲットのラベルが内包されているか を確認します。
*/
class OverlapChecker
{
Index: trunk/src/jp/nyatla/nyartoolkit/core/types/NyARLinear.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/types/NyARLinear.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/types/NyARLinear.java (revision 199)
@@ -36,4 +36,11 @@
public double rise;//y軸の増加量
public double run;//x軸の増加量
public double intercept;//切片
+ public final void copyFrom(NyARLinear i_source)
+ {
+ this.rise=i_source.rise;
+ this.run=i_source.run;
+ this.intercept=i_source.intercept;
+ return;
+ }
}
Index: trunk/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix33.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix33.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix33.java (revision 199)
@@ -31,6 +31,7 @@
*/
package jp.nyatla.nyartoolkit.core.types.matrix;
+
public class NyARDoubleMatrix33 implements INyARDoubleMatrix
{
public double m00;
@@ -42,6 +43,15 @@
public double m20;
public double m21;
public double m22;
+ public static NyARDoubleMatrix33[] createArray(int i_number)
+ {
+ NyARDoubleMatrix33[] ret=new NyARDoubleMatrix33[i_number];
+ for(int i=0;i<i_number;i++)
+ {
+ ret[i]=new NyARDoubleMatrix33();
+ }
+ return ret;
+ }
/**
* 遅いからあんまり使わないでね。
*/
Index: trunk/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix22.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix22.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix22.java (revision 199)
@@ -0,0 +1,62 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core.types.matrix;
+
+public class NyARDoubleMatrix22 implements INyARDoubleMatrix
+{
+ public double m00;
+ public double m01;
+ public double m10;
+ public double m11;
+ /**
+ * 遅いからあんまり使わないでね。
+ */
+ public void setValue(double[] i_value)
+ {
+ this.m00=i_value[0];
+ this.m01=i_value[1];
+ this.m10=i_value[3];
+ this.m11=i_value[4];
+ return;
+ }
+ /**
+ * 遅いからあんまり使わないでね。
+ */
+ public void getValue(double[] o_value)
+ {
+ o_value[0]=this.m00;
+ o_value[1]=this.m01;
+ o_value[3]=this.m10;
+ o_value[4]=this.m11;
+ return;
+ }
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core/types/NyARIntPoint.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/types/NyARIntPoint.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/types/NyARIntPoint.java (revision 199)
@@ -36,5 +36,18 @@
public int x;
public int y;
-
+ /**
+ * 配列ファクトリ
+ * @param i_number
+ * @return
+ */
+ public static NyARIntPoint[] createArray(int i_number)
+ {
+ NyARIntPoint[] ret=new NyARIntPoint[i_number];
+ for(int i=0;i<i_number;i++)
+ {
+ ret[i]=new NyARIntPoint();
+ }
+ return ret;
+ }
}
Index: trunk/src/jp/nyatla/nyartoolkit/core/rasterfilter/INyARRasterFilter_RgbToGs.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/rasterfilter/INyARRasterFilter_RgbToGs.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/rasterfilter/INyARRasterFilter_RgbToGs.java (revision 199)
@@ -41,5 +41,5 @@
*/
public interface INyARRasterFilter_RgbToGs
{
- public void doFilter(INyARRgbRaster i_input, NyARGlayscaleRaster i_output) throws NyARException;
+ public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException;
}
Index: trunk/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2bin/NyARRasterFilter_ARToolkitThreshold.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2bin/NyARRasterFilter_ARToolkitThreshold.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2bin/NyARRasterFilter_ARToolkitThreshold.java (revision 199)
@@ -92,36 +92,37 @@
int x;
for (int y =i_size.h-1; y>=0 ; y--){
//端数分
+ final int[] row_ptr=i_out[y];
for (x = size_w-1;x>=x_mod_end;x--) {
w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x]=w<=th?0:1;
+ row_ptr[x]=w<=th?0:1;
bp -= 3;
}
//タイリング
for (;x>=0;x-=8) {
w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x]=w<=th?0:1;
+ row_ptr[x]=w<=th?0:1;
bp -= 3;
w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x-1]=w<=th?0:1;
+ row_ptr[x-1]=w<=th?0:1;
bp -= 3;
w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x-2]=w<=th?0:1;
+ row_ptr[x-2]=w<=th?0:1;
bp -= 3;
w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x-3]=w<=th?0:1;
+ row_ptr[x-3]=w<=th?0:1;
bp -= 3;
w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x-4]=w<=th?0:1;
+ row_ptr[x-4]=w<=th?0:1;
bp -= 3;
w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x-5]=w<=th?0:1;
+ row_ptr[x-5]=w<=th?0:1;
bp -= 3;
w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x-6]=w<=th?0:1;
+ row_ptr[x-6]=w<=th?0:1;
bp -= 3;
w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x-7]=w<=th?0:1;
+ row_ptr[x-7]=w<=th?0:1;
bp -= 3;
}
}
@@ -136,37 +137,39 @@
int w;
int x;
for (int y =i_size.h-1; y>=0 ; y--){
+ final int[] row_ptr=i_out[y];
+
//端数分
for (x = size_w-1;x>=x_mod_end;x--) {
w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x]=w<=th?0:1;
+ row_ptr[x]=w<=th?0:1;
bp -= 4;
}
//タイリング
for (;x>=0;x-=8) {
w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x]=w<=th?0:1;
+ row_ptr[x]=w<=th?0:1;
bp -= 4;
w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x-1]=w<=th?0:1;
+ row_ptr[x-1]=w<=th?0:1;
bp -= 4;
w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x-2]=w<=th?0:1;
+ row_ptr[x-2]=w<=th?0:1;
bp -= 4;
w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x-3]=w<=th?0:1;
+ row_ptr[x-3]=w<=th?0:1;
bp -= 4;
w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x-4]=w<=th?0:1;
+ row_ptr[x-4]=w<=th?0:1;
bp -= 4;
w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x-5]=w<=th?0:1;
+ row_ptr[x-5]=w<=th?0:1;
bp -= 4;
w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x-6]=w<=th?0:1;
+ row_ptr[x-6]=w<=th?0:1;
bp -= 4;
w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));
- i_out[y][x-7]=w<=th?0:1;
+ row_ptr[x-7]=w<=th?0:1;
bp -= 4;
}
}
@@ -179,6 +182,7 @@
case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:
case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:
case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8X8_32:
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_R5G6B5_16LE:
return true;
default:
return false;
Index: trunk/src/jp/nyatla/nyartoolkit/core/rasterfilter/INyARRasterFilter_GsToBin.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/rasterfilter/INyARRasterFilter_GsToBin.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/rasterfilter/INyARRasterFilter_GsToBin.java (revision 199)
@@ -36,5 +36,5 @@
public interface INyARRasterFilter_GsToBin
{
- public void doFilter(NyARGlayscaleRaster i_input, NyARBinRaster i_output) throws NyARException;
+ public void doFilter(NyARGrayscaleRaster i_input, NyARBinRaster i_output) throws NyARException;
}
Index: trunk/src/jp/nyatla/nyartoolkit/core/NyARSquare.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/NyARSquare.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/NyARSquare.java (revision 199)
@@ -35,14 +35,20 @@
/**
* ARMarkerInfoに相当するクラス。 矩形情報を保持します。
*
+ * directionは方角を表します。
+ * 決定しないときはDIRECTION_UNKNOWNを設定してください。
+ *
*/
public class NyARSquare
{
+ public final static int DIRECTION_UNKNOWN=-1;
+ public int direction;
public NyARLinear[] line = new NyARLinear[4];
public NyARDoublePoint2d[] sqvertex = new NyARDoublePoint2d[4];
public NyARIntPoint[] imvertex = new NyARIntPoint[4];
public NyARSquare()
{
+ this.direction=DIRECTION_UNKNOWN;
for(int i=0;i<4;i++){
this.sqvertex[i]=new NyARDoublePoint2d();
this.imvertex[i]=new NyARIntPoint();
Index: trunk/src/jp/nyatla/nyartoolkit/core/labeling/NyARLabelingImage.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/labeling/NyARLabelingImage.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/labeling/NyARLabelingImage.java (revision 199)
@@ -137,9 +137,9 @@
int sx=getTopClipTangentX(label);
int sy=label.clip_t;
- int coord_num = 1;// marker_info2->coord_num = 1;
- o_coord_x[0] = sx;// marker_info2->x_coord[0] = sx;
- o_coord_y[0] = sy;// marker_info2->y_coord[0] = sy;
+ int coord_num = 1;
+ o_coord_x[0] = sx;
+ o_coord_y[0] = sy;
int dir = 5;
int[][] limage=this._ref_buf;
@@ -148,8 +148,7 @@
for (;;) {
dir = (dir + 5) % 8;
for (i = 0; i < 8; i++) {
- if (limage[r + ydir[dir]][c + xdir[dir]] > 0) {// if(
- // p1[ydir[dir]*xsize+xdir[dir]] > 0 ){
+ if (limage[r + ydir[dir]][c + xdir[dir]] > 0) {
break;
}
dir = (dir + 1) % 8;
@@ -159,18 +158,17 @@
throw new NyARException();// return(-1);
}
// xcoordとycoordをc,rにも保存
- c = c + xdir[dir];// marker_info2->x_coord[marker_info2->coord_num]=marker_info2->x_coord[marker_info2->coord_num-1]
- // + xdir[dir];
- r = r + ydir[dir];// marker_info2->y_coord[marker_info2->coord_num]=marker_info2->y_coord[marker_info2->coord_num-1]+ ydir[dir];
- o_coord_x[coord_num] = c;// marker_info2->x_coord[marker_info2->coord_num]=marker_info2->x_coord[marker_info2->coord_num-1]+ xdir[dir];
- o_coord_y[coord_num] = r;// marker_info2->y_coord[marker_info2->coord_num]=marker_info2->y_coord[marker_info2->coord_num-1]+ ydir[dir];
+ c = c + xdir[dir];
+ r = r + ydir[dir];
+ o_coord_x[coord_num] = c;
+ o_coord_y[coord_num] = r;
// 終了条件判定
if (c == sx && r == sy){
coord_num++;
break;
}
coord_num++;
- if (coord_num == i_array_size) {// if( marker_info2.coord_num ==Config.AR_CHAIN_MAX-1 ){
+ if (coord_num == i_array_size) {
//輪郭が末端に達した
return coord_num;
}
Index: trunk/src/jp/nyatla/nyartoolkit/core/labeling/NyARLabelingLabelStack.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core/labeling/NyARLabelingLabelStack.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core/labeling/NyARLabelingLabelStack.java (revision 199)
@@ -31,7 +31,6 @@
*/
package jp.nyatla.nyartoolkit.core.labeling;
-import jp.nyatla.nyartoolkit.NyARException;
import jp.nyatla.utils.*;
/**
Index: trunk/src/jp/nyatla/nyartoolkit/core2/types/matrix/NyARFixedFloat24Matrix33.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/types/matrix/NyARFixedFloat24Matrix33.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/types/matrix/NyARFixedFloat24Matrix33.java (revision 199)
@@ -0,0 +1,76 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core2.types.matrix;
+
+import jp.nyatla.nyartoolkit.core.types.matrix.*;
+
+
+public class NyARFixedFloat24Matrix33 extends NyARI64Matrix33
+{
+ public void copyFrom(NyARDoubleMatrix33 i_matrix)
+ {
+ this.m00=(long)i_matrix.m00*0x1000000;
+ this.m01=(long)i_matrix.m01*0x1000000;
+ this.m02=(long)i_matrix.m02*0x1000000;
+ this.m10=(long)i_matrix.m10*0x1000000;
+ this.m11=(long)i_matrix.m11*0x1000000;
+ this.m12=(long)i_matrix.m12*0x1000000;
+ this.m20=(long)i_matrix.m20*0x1000000;
+ this.m21=(long)i_matrix.m21*0x1000000;
+ this.m22=(long)i_matrix.m22*0x1000000;
+ return;
+ }
+ public void copyTo(NyARDoubleMatrix33 i_to)
+ {
+ i_to.m00=(double)this.m00/0x1000000;
+ i_to.m01=(double)this.m01/0x1000000;
+ i_to.m02=(double)this.m02/0x1000000;
+ i_to.m10=(double)this.m10/0x1000000;
+ i_to.m11=(double)this.m11/0x1000000;
+ i_to.m12=(double)this.m12/0x1000000;
+ i_to.m20=(double)this.m20/0x1000000;
+ i_to.m21=(double)this.m21/0x1000000;
+ i_to.m22=(double)this.m22/0x1000000;
+ return;
+ }
+
+ public static NyARFixedFloat24Matrix33[] createArray(int i_number)
+ {
+ NyARFixedFloat24Matrix33[] ret=new NyARFixedFloat24Matrix33[i_number];
+ for(int i=0;i<i_number;i++)
+ {
+ ret[i]=new NyARFixedFloat24Matrix33();
+ }
+ return ret;
+ }
+
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core2/types/matrix/NyARFixedFloat16Matrix33.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/types/matrix/NyARFixedFloat16Matrix33.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/types/matrix/NyARFixedFloat16Matrix33.java (revision 199)
@@ -0,0 +1,61 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core2.types.matrix;
+
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix33;
+
+
+public class NyARFixedFloat16Matrix33 extends NyARI64Matrix33
+{
+ public void copyFrom(NyARDoubleMatrix33 i_matrix)
+ {
+ this.m00=(long)i_matrix.m00*0x10000;
+ this.m01=(long)i_matrix.m01*0x10000;
+ this.m02=(long)i_matrix.m02*0x10000;
+ this.m10=(long)i_matrix.m10*0x10000;
+ this.m11=(long)i_matrix.m11*0x10000;
+ this.m12=(long)i_matrix.m12*0x10000;
+ this.m20=(long)i_matrix.m20*0x10000;
+ this.m21=(long)i_matrix.m21*0x10000;
+ this.m22=(long)i_matrix.m22*0x10000;
+ return;
+ }
+ public static NyARFixedFloat16Matrix33[] createArray(int i_number)
+ {
+ NyARFixedFloat16Matrix33[] ret=new NyARFixedFloat16Matrix33[i_number];
+ for(int i=0;i<i_number;i++)
+ {
+ ret[i]=new NyARFixedFloat16Matrix33();
+ }
+ return ret;
+ }
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core2/types/matrix/NyARI64Matrix22.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/types/matrix/NyARI64Matrix22.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/types/matrix/NyARI64Matrix22.java (revision 199)
@@ -0,0 +1,9 @@
+package jp.nyatla.nyartoolkit.core2.types.matrix;
+
+public class NyARI64Matrix22
+{
+ public long m00;
+ public long m01;
+ public long m10;
+ public long m11;
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core2/types/matrix/NyARI64Matrix33.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/types/matrix/NyARI64Matrix33.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/types/matrix/NyARI64Matrix33.java (revision 199)
@@ -0,0 +1,55 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core2.types.matrix;
+
+
+public class NyARI64Matrix33
+{
+ public long m00;
+ public long m01;
+ public long m02;
+ public long m10;
+ public long m11;
+ public long m12;
+ public long m20;
+ public long m21;
+ public long m22;
+ public static NyARI64Matrix33[] createArray(int i_number)
+ {
+ NyARI64Matrix33[] ret=new NyARI64Matrix33[i_number];
+ for(int i=0;i<i_number;i++)
+ {
+ ret[i]=new NyARI64Matrix33();
+ }
+ return ret;
+ }
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARFixedFloat16Point2d.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARFixedFloat16Point2d.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARFixedFloat16Point2d.java (revision 199)
@@ -0,0 +1,45 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core2.types;
+
+public class NyARFixedFloat16Point2d extends NyARI64Point2d
+{
+ public static NyARFixedFloat16Point2d[] createArray(int i_number)
+ {
+ NyARFixedFloat16Point2d[] ret=new NyARFixedFloat16Point2d[i_number];
+ for(int i=0;i<i_number;i++)
+ {
+ ret[i]=new NyARFixedFloat16Point2d();
+ }
+ return ret;
+ }
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARFixedFloat16Point3d.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARFixedFloat16Point3d.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARFixedFloat16Point3d.java (revision 199)
@@ -0,0 +1,67 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core2.types;
+
+import jp.nyatla.nyartoolkit.core.types.*;
+
+public class NyARFixedFloat16Point3d extends NyARI64Point3d
+{
+ /**
+ * 配列ファクトリ
+ * @param i_number
+ * @return
+ */
+ public static NyARFixedFloat16Point3d[] createArray(int i_number)
+ {
+ NyARFixedFloat16Point3d[] ret=new NyARFixedFloat16Point3d[i_number];
+ for(int i=0;i<i_number;i++)
+ {
+ ret[i]=new NyARFixedFloat16Point3d();
+ }
+ return ret;
+ }
+ public void copyTo(NyARDoublePoint3d i_to)
+ {
+ i_to.x=(double)this.x/0x10000;
+ i_to.y=(double)this.y/0x10000;
+ i_to.z=(double)this.z/0x10000;
+ return;
+ }
+ public void copyFrom(NyARDoublePoint3d i_from)
+ {
+ this.x=(long)(i_from.x*0x10000);
+ this.y=(long)(i_from.y*0x10000);
+ this.z=(long)(i_from.z*0x10000);
+ return;
+ }
+
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARI64Linear.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARI64Linear.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARI64Linear.java (revision 199)
@@ -0,0 +1,55 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core2.types;
+
+public class NyARI64Linear
+{
+ public long rise;//y軸の増加量
+ public long run;//x軸の増加量
+ public long intercept;//切片
+ public final void copyFrom(NyARI64Linear i_source)
+ {
+ this.rise=i_source.rise;
+ this.run=i_source.run;
+ this.intercept=i_source.intercept;
+ return;
+ }
+ public static NyARI64Linear[] createArray(int i_number)
+ {
+ NyARI64Linear[] ret=new NyARI64Linear[i_number];
+ for(int i=0;i<i_number;i++)
+ {
+ ret[i]=new NyARI64Linear();
+ }
+ return ret;
+ }
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARI64Point2d.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARI64Point2d.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARI64Point2d.java (revision 199)
@@ -0,0 +1,53 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core2.types;
+
+public class NyARI64Point2d
+{
+ public long x;
+
+ public long y;
+ /**
+ * 配列ファクトリ
+ * @param i_number
+ * @return
+ */
+ public static NyARI64Point2d[] createArray(int i_number)
+ {
+ NyARI64Point2d[] ret=new NyARI64Point2d[i_number];
+ for(int i=0;i<i_number;i++)
+ {
+ ret[i]=new NyARI64Point2d();
+ }
+ return ret;
+ }
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARI64Point3d.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARI64Point3d.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/types/NyARI64Point3d.java (revision 199)
@@ -0,0 +1,53 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core2.types;
+
+public class NyARI64Point3d
+{
+ public long x;
+ public long y;
+ public long z;
+ /**
+ * 配列ファクトリ
+ * @param i_number
+ * @return
+ */
+ public static NyARI64Point3d[] createArray(int i_number)
+ {
+ NyARI64Point3d[] ret=new NyARI64Point3d[i_number];
+ for(int i=0;i<i_number;i++)
+ {
+ ret[i]=new NyARI64Point3d();
+ }
+ return ret;
+ }
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core2/rasteranalyzer/threshold/NyARRasterThresholdAnalyzer_DiffHistgram.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/rasteranalyzer/threshold/NyARRasterThresholdAnalyzer_DiffHistgram.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/rasteranalyzer/threshold/NyARRasterThresholdAnalyzer_DiffHistgram.java (revision 199)
@@ -0,0 +1,156 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core2.rasteranalyzer.threshold;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;
+import jp.nyatla.nyartoolkit.core.types.*;
+
+/**
+ * 微分ヒストグラム法による閾値検出
+ *
+ */
+public class NyARRasterThresholdAnalyzer_DiffHistgram implements INyARRasterThresholdAnalyzer
+{
+ private int _threshold;
+
+ public NyARRasterThresholdAnalyzer_DiffHistgram()
+ {
+ }
+
+ private int createHistgram(int[][] in_buf,NyARIntSize i_size, int[] o_histgram) throws NyARException
+ {
+ int[][] fil1={
+ {-1,-2,-1},
+ { 0, 0, 0},
+ { 1, 2, 1}};
+
+ // ヒストグラムを作成
+ for (int i = 0; i < 256; i++) {
+ o_histgram[i] = 0;
+ }
+ int sam;
+ int sam1,sam2;
+ for (int y = 1; y < i_size.h-1; y++) {
+ for (int x = 1; x < i_size.w-1; x++) {
+ int v = in_buf[y][x];
+ sam1=sam2=0;
+ for(int yy=0;yy<3;yy++){
+ for(int xx=0;xx<3;xx++){
+ int v2=in_buf[y+yy-1][x+xx-1];
+ sam1+=v2*fil1[xx][yy];
+ sam2+=v2*fil1[yy][xx];
+ }
+ }
+ sam=sam1*sam1+sam2*sam2;
+ o_histgram[v]+=sam;
+ }
+ }
+ int th=0;
+ int max=o_histgram[0];
+ for(int i=1;i<256;i++){
+ if(max<o_histgram[i]){
+ th=i;
+ max=o_histgram[i];
+ }
+ }
+ return th;
+ }
+
+ public void analyzeRaster(INyARRaster i_input) throws NyARException
+ {
+ final INyARBufferReader buffer_reader=i_input.getBufferReader();
+ assert (buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT2D_GLAY_8));
+ int[] histgram = new int[256];
+ this._threshold = createHistgram((int[][])buffer_reader.getBuffer(),i_input.getSize(), histgram);
+ }
+
+ /**
+ * デバック用の関数です。 ヒストグラムをラスタに書き出します。
+ *
+ * @param i_output
+ * 書き出し先のラスタオブジェクト 256ピクセル以上の幅があること。
+ */
+ public void debugDrawHistgramMap(INyARRaster i_input, INyARRaster i_output) throws NyARException
+ {
+ INyARBufferReader in_buffer_reader=i_input.getBufferReader();
+ INyARBufferReader out_buffer_reader=i_output.getBufferReader();
+ assert (in_buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT2D_GLAY_8));
+ assert (out_buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT2D_GLAY_8));
+ NyARIntSize size = i_output.getSize();
+
+ int[][] out_buf = (int[][]) out_buffer_reader.getBuffer();
+ // 0で塗りつぶし
+ for (int y = 0; y < size.h; y++) {
+ for (int x = 0; x < size.w; x++) {
+ out_buf[y][x] = 0;
+ }
+ }
+ // ヒストグラムを計算
+ int[] histgram = new int[256];
+ int threshold = createHistgram((int[][])in_buffer_reader.getBuffer(),i_input.getSize(), histgram);
+
+ // ヒストグラムの最大値を出す
+ int max_v = 0;
+ for (int i = 0; i < 255; i++) {
+ if (max_v < histgram[i]) {
+ max_v = histgram[i];
+ }
+ }
+ // 目盛り
+ for (int i = 0; i < size.h; i++) {
+ out_buf[i][0] = 128;
+ out_buf[i][128] = 128;
+ out_buf[i][255] = 128;
+ }
+ // スケーリングしながら描画
+ for (int i = 0; i < 255; i++) {
+ out_buf[histgram[i] * (size.h - 1) / max_v][i] = 255;
+ }
+ // 値
+ for (int i = 0; i < size.h; i++) {
+ out_buf[i][threshold] = 255;
+ }
+ return;
+ }
+
+ public int getThreshold()
+ {
+ return this._threshold;
+ }
+
+ public int getThreshold(int i_x, int i_y)
+ {
+ return this._threshold;
+ }
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/NyARRasterFilter_Edge.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/NyARRasterFilter_Edge.java (revision 0)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/NyARRasterFilter_Edge.java (revision 199)
@@ -0,0 +1,69 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core2.rasterfilter;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.rasterfilter.INyARRasterFilter;
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;
+
+/**
+ * エッジ検出フィルタ 入力 BUFFERFORMAT_INT2D 出力 BUFFERFORMAT_INT2D
+ */
+public class NyARRasterFilter_Edge implements INyARRasterFilter
+{
+ public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException
+ {
+ INyARBufferReader in_buffer_reader=i_input.getBufferReader();
+ INyARBufferReader out_buffer_reader=i_output.getBufferReader();
+ assert (in_buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT2D_GLAY_8));
+ assert (out_buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT2D_GLAY_8));
+ assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);
+
+ int[][] out_buf = (int[][]) out_buffer_reader.getBuffer();
+ int[][] in_buf = (int[][]) in_buffer_reader.getBuffer();
+
+ int bp = 0;
+ NyARIntSize size = i_output.getSize();
+ for (int y = 1; y < size.h; y++) {
+ int prev = 128;
+ for (int x = 1; x < size.w; x++) {
+ int w = in_buf[y][x];
+ out_buf[y][x] = (Math.abs(w - prev) + Math.abs(w - in_buf[y - 1][x])) / 2;
+ prev = w;
+ bp += 3;
+ }
+ }
+ return;
+ }
+}
Index: trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/gs2bin/NyARRasterFilter_AreaAverage.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/gs2bin/NyARRasterFilter_AreaAverage.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/gs2bin/NyARRasterFilter_AreaAverage.java (revision 199)
@@ -44,7 +44,7 @@
{
private int _area = 8;
- public void doFilter(NyARGlayscaleRaster i_input, NyARBinRaster i_output) throws NyARException
+ public void doFilter(NyARGrayscaleRaster i_input, NyARBinRaster i_output) throws NyARException
{
final NyARIntSize size = i_output.getSize();
final int[][] out_buf = (int[][]) i_output.getBufferReader().getBuffer();
Index: trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/gs2bin/NyARRasterFilter_Threshold.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/gs2bin/NyARRasterFilter_Threshold.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/gs2bin/NyARRasterFilter_Threshold.java (revision 199)
@@ -47,9 +47,10 @@
public NyARRasterFilter_Threshold(int i_threshold)
{
this._threshold = i_threshold;
+ return;
}
- public void doFilter(NyARGlayscaleRaster i_input, NyARBinRaster i_output) throws NyARException
+ public void doFilter(NyARGrayscaleRaster i_input, NyARBinRaster i_output) throws NyARException
{
assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);
@@ -66,4 +67,9 @@
}
return;
}
+ public void setThreshold(int i_threshold)
+ {
+ this._threshold = i_threshold;
+ return;
+ }
}
Index: trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/rgb2gs/NyARRasterFilter_RgbAve.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/rgb2gs/NyARRasterFilter_RgbAve.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/rgb2gs/NyARRasterFilter_RgbAve.java (revision 199)
@@ -40,7 +40,7 @@
public class NyARRasterFilter_RgbAve implements INyARRasterFilter_RgbToGs
{
- public void doFilter(INyARRgbRaster i_input, NyARGlayscaleRaster i_output) throws NyARException
+ public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException
{
INyARBufferReader in_buffer_reader=i_input.getBufferReader();
INyARBufferReader out_buffer_reader=i_output.getBufferReader();
Index: trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/rgb2gs/NyARRasterFilter_RgbMul.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/rgb2gs/NyARRasterFilter_RgbMul.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/rgb2gs/NyARRasterFilter_RgbMul.java (revision 199)
@@ -40,14 +40,14 @@
public class NyARRasterFilter_RgbMul implements INyARRasterFilter_RgbToGs
{
- public void doFilter(INyARRgbRaster i_input, NyARGlayscaleRaster i_output) throws NyARException
+ public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException
{
INyARBufferReader in_buffer_reader=i_input.getBufferReader();
INyARBufferReader out_buffer_reader=i_output.getBufferReader();
assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);
- int[][] out_buf = (int[][]) in_buffer_reader.getBuffer();
- byte[] in_buf = (byte[]) out_buffer_reader.getBuffer();
+ int[][] out_buf = (int[][]) out_buffer_reader.getBuffer();
+ byte[] in_buf = (byte[]) in_buffer_reader.getBuffer();
NyARIntSize size = i_output.getSize();
switch (in_buffer_reader.getBufferType()) {
Index: trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/rgb2gs/NyARRasterFilter_RgbOr.java
===================================================================
--- trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/rgb2gs/NyARRasterFilter_RgbOr.java (revision 162)
+++ trunk/src/jp/nyatla/nyartoolkit/core2/rasterfilter/rgb2gs/NyARRasterFilter_RgbOr.java (revision 199)
@@ -40,7 +40,7 @@
public class NyARRasterFilter_RgbOr implements INyARRasterFilter_RgbToGs
{
- public void doFilter(INyARRgbRaster i_input, NyARGlayscaleRaster i_output) throws NyARException
+ public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException
{
INyARBufferReader in_buffer_reader=i_input.getBufferReader();
INyARBufferReader out_buffer_reader=i_output.getBufferReader();
Index: trunk/src/jp/nyatla/utils/j2se/LabelingBufferdImage.java
===================================================================
--- trunk/src/jp/nyatla/utils/j2se/LabelingBufferdImage.java (revision 162)
+++ trunk/src/jp/nyatla/utils/j2se/LabelingBufferdImage.java (revision 199)
@@ -42,8 +42,8 @@
import jp.nyatla.nyartoolkit.core.rasterreader.*;
import jp.nyatla.nyartoolkit.core.raster.*;
import jp.nyatla.nyartoolkit.core.types.stack.*;
+import jp.nyatla.nyartoolkit.core.labeling.*;
-
/**
* bitmapとして利用可能なラベリングイメージです。
*
@@ -63,9 +63,8 @@
public final static int COLOR_8_MONO = 5;// 16階調モノクロモード
- private int[] _rgb_table;
+ private int[] _rgb_table_125;
- private int _number_of_color;
/**
* i_width x i_heightの大きさのイメージを作成します。
@@ -73,23 +72,19 @@
* @param i_width
* @param i_height
*/
- public LabelingBufferdImage(int i_width, int i_height, int i_color_mode)
+ public LabelingBufferdImage(int i_width, int i_height)
{
super(i_width, i_height, ColorSpace.TYPE_RGB);
// RGBテーブルを作成
- switch (i_color_mode) {
- case COLOR_125_COLOR:
- this._rgb_table = new int[125];
- this._number_of_color = 125;
- for (int i = 0; i < 5; i++) {
- for (int i2 = 0; i2 < 5; i2++) {
- for (int i3 = 0; i3 < 5; i3++) {
- this._rgb_table[((i * 5) + i2) * 5 + i3] = ((((i * 63) << 8) | (i2 * 63)) << 8) | (i3 * 63);
- }
+ this._rgb_table_125 = new int[125];
+ for (int i = 0; i < 5; i++) {
+ for (int i2 = 0; i2 < 5; i2++) {
+ for (int i3 = 0; i3 < 5; i3++) {
+ this._rgb_table_125[((i * 5) + i2) * 5 + i3] = ((((i * 63) << 8) | (i2 * 63)) << 8) | (i3 * 63);
}
}
- break;
- case COLOR_256_MONO:
+ }
+/* case COLOR_256_MONO:
this._rgb_table = new int[256];
this._number_of_color = 256;
for (int i = 0; i < 256; i++) {
@@ -120,12 +115,12 @@
this._rgb_table[i] = (m << 16) | (m << 8) | m;
}
break;
- }
+ }*/
}
- public void drawImage(NyARGlayscaleRaster i_raster) throws NyARException
+ public void drawImage(NyARGrayscaleRaster i_raster) throws NyARException
{
assert (i_raster.getBufferReader().getBufferType() == INyARBufferReader.BUFFERFORMAT_INT2D_GLAY_8);
@@ -142,12 +137,16 @@
limg = (int[][]) i_raster.getBufferReader().getBuffer();
for (int i = 0; i < h; i++) {
for (int i2 = 0; i2 < w; i2++) {
- this.setRGB(i2, i, this._rgb_table[limg[i][i2] % this._number_of_color]);
+ this.setRGB(i2, i,limg[i][i2]);
}
}
return;
}
-
+ /**
+ * バイナリラスタ
+ * @param i_raster
+ * @throws NyARException
+ */
public void drawImage(NyARBinRaster i_raster) throws NyARException
{
assert (i_raster.getBufferReader().getBufferType() == INyARBufferReader.BUFFERFORMAT_INT2D_BIN_8);
@@ -170,7 +169,56 @@
}
return;
}
+
+ /**
+ * ラベリングイメージを書く
+ * @param i_raster
+ * @throws NyARException
+ */
+ public void drawLabel(NyARLabelingImage i_image) throws NyARException
+ {
+ int w = this.getWidth();
+ int h = this.getHeight();
+ // サイズをチェック
+ NyARIntSize size = i_image.getSize();
+ if (size.h > h || size.w > w) {
+ throw new NyARException();
+ }
+ int[] index_array=i_image.getIndexArray();
+ int[][] limg;
+ // イメージの描画
+ limg = (int[][]) i_image.getBufferReader().getBuffer();
+ for (int i = 0; i < h; i++) {
+ for (int i2 = 0; i2 < w; i2++) {
+ int t=limg[i][i2]-1;
+ if(t<0){
+ t=0;
+ }else{
+ t=index_array[t];
+ }
+ this.setRGB(i2, i,_rgb_table_125[t% _rgb_table_125.length]);
+ }
+ }
+ return;
+ }
+ /**
+ *
+ * @param i_stack
+ */
+
+ public void overlayData(NyARLabelingLabel i_label)
+ {
+ Graphics g = this.getGraphics();
+ g.setColor(Color.red);
+ g.drawRect(i_label.clip_l,i_label.clip_t,i_label.clip_r-i_label.clip_l,i_label.clip_b-i_label.clip_t);
+ return;
+ }
+ /**
+ *
+ * @param i_stack
+ */
+
public void overlayData(NyARIntPointStack i_stack)
{
int count = i_stack.getLength();