--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+\r
+\r
+\r
+/**\r
+ * イメージからマーカー情報を検出するクラス。\r
+ * このクラスは、arDetectMarker2.cとの置き換えになります。\r
+ * ラベリング済みのラスタデータからマーカー位置を検出して、結果を保持します。\r
+ *\r
+ */\r
+public class NyARDetectMarker {\r
+ private static final int AR_AREA_MAX=100000;//#define AR_AREA_MAX 100000\r
+ private static final int AR_AREA_MIN=70;//#define AR_AREA_MIN 70\r
+\r
+// private final NyARMarker[] marker_holder; //マーカーデータの保持配列\r
+// private final NyARMarker[] marker_info2_array;//マーカーデータのインデックス配列\r
+// private int marker_num;\r
+ private int width,height;\r
+ /**\r
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
+ * @param i_width\r
+ * @param i_height\r
+ */\r
+ public NyARDetectMarker(int i_width,int i_height)\r
+ {\r
+ this.width =i_width;\r
+ this.height=i_height;\r
+ \r
+// this.marker_holder=new NyARMarker[i_squre_max];\r
+// this.marker_info2_array=new NyARMarker[i_squre_max];\r
+// //先にマーカーホルダにオブジェクトを作っておく\r
+// for(int i=0;i<i_squre_max;i++){\r
+// this.marker_holder[i]=new NyARMarker();\r
+// }\r
+ }\r
+ private static final int AR_CHAIN_MAX=10000;\r
+ private final int[] wk_arGetContour_xdir={0, 1, 1, 1, 0,-1,-1,-1};\r
+ private final int[] wk_arGetContour_ydir={-1,-1, 0, 1, 1, 1, 0,-1};\r
+ private final int[] wk_arGetContour_xcoord=new int[AR_CHAIN_MAX];\r
+ private final int[] wk_arGetContour_ycoord=new int[AR_CHAIN_MAX];\r
+ /**\r
+ * int arGetContour( ARInt16 *limage, int *label_ref,int label, int clip[4], ARMarkerInfo2 *marker_info2 )\r
+ * 関数の代替品\r
+ * detectMarker関数から使う関数です。o_markerにlabelとclipで示される1個のマーカーを格納します。\r
+ * marker_holder[i_holder_num]にオブジェクトが無ければまず新規に作成し、もし\r
+ * 既に存在すればそこにマーカー情報を上書きして記録します。\r
+ * Optimize:STEP[369->336]\r
+ * @param o_marker\r
+ * @param limage\r
+ * @param label_ref\r
+ * @param label\r
+ * @param clip\r
+ * @throws NyARException\r
+ */\r
+ private final void arGetContour(NyARMarker o_marker,int[][] limage, int[] label_ref,int i_labelnum, NyARLabel i_label) throws NyARException\r
+ {\r
+ final int[] xcoord=wk_arGetContour_xcoord;\r
+ final int[] ycoord=wk_arGetContour_ycoord;\r
+ final int[] xdir=wk_arGetContour_xdir; //static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};\r
+ final int[] ydir=wk_arGetContour_ydir;//static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};\r
+ //ShortPointer p1;//ARInt16 *p1;\r
+ int coord_num;\r
+ int sx=0, sy=0, dir;\r
+ int dmax, d, v1=0;\r
+ int i, j,w;\r
+\r
+ int[] limage_j;\r
+ j = i_label.clip2;\r
+ limage_j=limage[j];\r
+ final int clip1=i_label.clip1;\r
+ //p1=ShortPointer.wrap(limage,j*xsize+clip.get());//p1 = &(limage[j*xsize+clip[0]]);\r
+ for( i = i_label.clip0; i <= clip1; i++){//for( i = clip[0]; i <= clip[1]; i++, p1++ ) {\r
+ w=limage_j[i];\r
+ if(w > 0 && label_ref[w-1] == i_labelnum ) {//if( *p1 > 0 && label_ref[(*p1)-1] == label ) {\r
+ sx = i;\r
+ sy = j;\r
+ break;\r
+ }\r
+ }\r
+ if(i>clip1){//if( i > clip[1] ) {\r
+ System.out.println("??? 1");//printf();\r
+ throw new NyARException();//return(-1);\r
+ }\r
+\r
+// //マーカーホルダが既に確保済みかを調べる\r
+// if(marker_holder[i_holder_num]==null){\r
+// //確保していなければ確保\r
+// marker_holder[i_holder_num]=new NyARMarker();\r
+// }\r
+\r
+\r
+ coord_num=1;//marker_info2->coord_num = 1;\r
+ xcoord[0]=sx;//marker_info2->x_coord[0] = sx;\r
+ ycoord[0]=sy;//marker_info2->y_coord[0] = sy;\r
+ dir = 5;\r
+ \r
+ int r,c;\r
+ c=xcoord[0];\r
+ r=ycoord[0];\r
+ dmax=0;\r
+ //本家はdmaxの作成とxcoordの作成を別のループでやってるけど、非効率なので統合\r
+ for(;;){\r
+ //xcoord[1]-xcoord[n]までのデータを作る。\r
+ \r
+// 1個前のxcoordとycoordはループ後半で格納される。\r
+// c=xcoord[coord_num-1];\r
+// r=ycoord[coord_num-1];\r
+ //p1 = &(limage[marker_info2->y_coord[marker_info2->coord_num-1] * xsize+ marker_info2->x_coord[marker_info2->coord_num-1]]);\r
+ dir = (dir+5)%8;\r
+ for(i=0;i<8;i++) {\r
+ if(limage[r+ydir[dir]][c+xdir[dir]]>0){//if( p1[ydir[dir]*xsize+xdir[dir]] > 0 ){\r
+ break;\r
+ }\r
+ dir = (dir+1)%8; \r
+ }\r
+ if( i == 8 ){\r
+ System.out.println("??? 2");//printf("??? 2\n");\r
+ throw new NyARException();//return(-1);\r
+ }\r
+// xcoordとycoordをc,rにも保存\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= r + ydir[dir];//marker_info2->y_coord[marker_info2->coord_num]= marker_info2->y_coord[marker_info2->coord_num-1] + ydir[dir];\r
+ xcoord[coord_num]=c;//marker_info2->x_coord[marker_info2->coord_num]= marker_info2->x_coord[marker_info2->coord_num-1] + xdir[dir];\r
+ ycoord[coord_num]=r;//marker_info2->y_coord[marker_info2->coord_num]= marker_info2->y_coord[marker_info2->coord_num-1] + ydir[dir];\r
+ if(c == sx && r == sy ){\r
+ break;\r
+ }\r
+ //dmaxの計算\r
+ d=(c-sx)*(c-sx)+(r-sy)*(r-sy);\r
+ if( d > dmax ) {\r
+ dmax = d;\r
+ v1 = coord_num;\r
+ }\r
+ //終了条件判定\r
+ coord_num++;\r
+ if(coord_num == AR_CHAIN_MAX-1){//if( marker_info2.coord_num == Config.AR_CHAIN_MAX-1 ){\r
+ System.out.println("??? 3");//printf("??? 3\n");\r
+ throw new NyARException();//return(-1);\r
+ }\r
+ }\r
+//\r
+// dmax = 0;\r
+// for(i=1;i<coord_num;i++) {// for(i=1;i<marker_info2->coord_num;i++) {\r
+// d = (xcoord[i]-sx)*(xcoord[i]-sx)+ (ycoord[i]-sy)*(ycoord[i]-sy);// d = (marker_info2->x_coord[i]-sx)*(marker_info2->x_coord[i]-sx)+ (marker_info2->y_coord[i]-sy)*(marker_info2->y_coord[i]-sy);\r
+// if( d > dmax ) {\r
+// dmax = d;\r
+// v1 = i;\r
+// }\r
+// }\r
+ //NyARMarkerへcoord情報をセット\r
+ //coordの並び替えと保存はNyARMarkerへ移動\r
+ o_marker.setCoordXY(v1,coord_num,xcoord,ycoord);\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * 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 )\r
+ * 関数の代替品\r
+ * ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。\r
+ * 関数はo_marker_listに重なりを除外したマーカーリストを作成します。\r
+ * \r
+ * @param i_labeling\r
+ * ラベリング済みの情報を持つラベリングオブジェクト\r
+ * @param i_factor\r
+ * 何かの閾値?\r
+ * @param o_marker_list\r
+ * 抽出したマーカーを格納するリスト\r
+ * @throws NyARException\r
+ */\r
+ public final void detectMarker(NyARLabeling i_labeling,double i_factor,NyARMarkerList o_marker_list) throws NyARException\r
+ {\r
+ int label_area;\r
+ int i;\r
+ int xsize, ysize;\r
+ NyARLabel[] labels=i_labeling.getLabel();\r
+// int[] warea =i_labeling.getArea();\r
+ int label_num =i_labeling.getLabelNum();\r
+// int[][] wclip =i_labeling.getClip();\r
+// double[] wpos =i_labeling.getPos();\r
+ int[][] limage=i_labeling.getLabelImg();\r
+ int[] label_ref =i_labeling.getLabelRef();\r
+\r
+ //マーカーホルダをリセット\r
+ o_marker_list.reset();\r
+// marker_num=0;\r
+ xsize =width;\r
+ ysize =height;\r
+// マーカーをmarker_holderに蓄積する。\r
+ NyARMarker current_marker=o_marker_list.getCurrentHolder();\r
+ NyARLabel label_pt;\r
+ for(i=0; i<label_num; i++ ){\r
+ label_pt=labels[i];\r
+ label_area=label_pt.area;\r
+ if(label_area < AR_AREA_MIN || label_area > AR_AREA_MAX ){\r
+ continue;\r
+ }\r
+ if( label_pt.clip0 == 1 || label_pt.clip1 == xsize-2 ){//if( wclip[i*4+0] == 1 || wclip[i*4+1] == xsize-2 ){\r
+ continue;\r
+ }\r
+ if( label_pt.clip2 == 1 || label_pt.clip3 == ysize-2 ){//if( wclip[i*4+2] == 1 || wclip[i*4+3] == ysize-2 ){\r
+ continue;\r
+ }\r
+ //ret = arGetContour( limage, label_ref, i+1,&(wclip[i*4]), &(marker_info2[marker_num2]));\r
+ arGetContour(current_marker,limage, label_ref, i+1,label_pt);\r
+\r
+ if(!current_marker.checkSquare(label_area,i_factor,label_pt.pos_x,label_pt.pos_y)){\r
+ //後半で整理するからここはいらない。// marker_holder[marker_num2]=null;\r
+ continue;\r
+ }\r
+// この3行はcheckSquareの最終段に含める。\r
+// marker_holder[marker_num2].area = warea[i];\r
+// marker_holder[marker_num2].pos[0] = wpos[i*2+0];\r
+// marker_holder[marker_num2].pos[1] = wpos[i*2+1];\r
+ //マーカー検出→次のホルダを取得\r
+ current_marker=o_marker_list.getNextHolder();\r
+ //マーカーリストが上限に達したか確認\r
+ if(current_marker==null){\r
+ break;\r
+ }\r
+ }\r
+ //マーカーリストを整理(重なり処理とかはマーカーリストに責務押し付け)\r
+ o_marker_list.updateMarkerArray();\r
+// 重なり処理かな?\r
+// double[] pos_j,pos_i;\r
+// for(i=0; i < marker_num2; i++ ){\r
+// pos_i=marker_holder[i].pos;\r
+// for(j=i+1; j < marker_num2; j++ ) {\r
+// pos_j=marker_holder[j].pos;\r
+// d = (pos_i[0] - pos_j[0])*(pos_i[0] - pos_j[0])+\r
+// (pos_i[1] - pos_j[1])*(pos_i[1] - pos_j[1]);\r
+// if(marker_holder[i].area >marker_holder[j].area ) {\r
+// if( d <marker_holder[i].area / 4 ) {\r
+// marker_holder[j].area = 0;\r
+// }\r
+// }else{\r
+// if( d < marker_holder[j].area / 4 ) {\r
+// marker_holder[i].area = 0;\r
+// }\r
+// }\r
+// }\r
+// }\r
+// みつかったマーカーを整理する。\r
+// エリアが0のマーカーを外した配列を作って、その数もついでに計算\r
+// for(i=0;i<marker_num2;i++){\r
+// if(marker_holder[i].area==0.0){\r
+// continue;\r
+// }\r
+// marker_info2_array[marker_num]=marker_holder[i];\r
+// marker_num++;\r
+// } \r
+// for( i=0; i < marker_num2; i++ ) {\r
+// if( marker_info2_array[i].area == 0.0 ) {\r
+// for( j=i+1; j < marker_num2; j++ ){\r
+// marker_info2_array[j-1] = marker_info2_array[j];\r
+// }\r
+// marker_num2--;\r
+// }\r
+// }\r
+// 発見したマーカー数をセット\r
+// marker_num=marker_num2;//*marker_num = marker_num2;\r
+// return( &(marker_info2[0]) );\r
+ return;\r
+ }\r
+\r
+}\r