OSDN Git Service

[リリース]NyARToolkit 0.6
[nyartoolkit-and/nyartoolkit-and.git] / src / jp / nyatla / nyartoolkit / core / NyARDetectSquare.java
1 /* \r
2  * PROJECT: NyARToolkit\r
3  * --------------------------------------------------------------------------------\r
4  * This work is based on the original ARToolKit developed by\r
5  *   Hirokazu Kato\r
6  *   Mark Billinghurst\r
7  *   HITLab, University of Washington, Seattle\r
8  * http://www.hitl.washington.edu/artoolkit/\r
9  *\r
10  * The NyARToolkit is Java version ARToolkit class library.\r
11  * Copyright (C)2008 R.Iizuka\r
12  *\r
13  * This program is free software; you can redistribute it and/or\r
14  * modify it under the terms of the GNU General Public License\r
15  * as published by the Free Software Foundation; either version 2\r
16  * of the License, or (at your option) any later version.\r
17  * \r
18  * This program is distributed in the hope that it will be useful,\r
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
21  * GNU General Public License for more details.\r
22  * \r
23  * You should have received a copy of the GNU General Public License\r
24  * along with this framework; if not, write to the Free Software\r
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
26  * \r
27  * For further information please contact.\r
28  *      http://nyatla.jp/nyatoolkit/\r
29  *      <airmail(at)ebony.plala.or.jp>\r
30  * \r
31  */\r
32 package jp.nyatla.nyartoolkit.core;\r
33 \r
34 import jp.nyatla.util.DoubleValue;\r
35 import jp.nyatla.nyartoolkit.NyARException;\r
36 import jp.nyatla.nyartoolkit.core.raster.*;\r
37 \r
38 \r
39 public class NyARDetectSquare{\r
40     private NyARLabeling labeling;\r
41     private NyARDetectMarker detect;\r
42 \r
43     private NyARSquare[] marker_info;\r
44     private int number_of_square;\r
45     private NyARParam param;\r
46 \r
47     /**\r
48      * 最大i_sqaure_max個のマーカー情報を抽出できるインスタンスを作る。\r
49      * @param i_sqaure_max\r
50      */\r
51     public NyARDetectSquare(int i_sqaure_max,NyARParam i_param)\r
52     {\r
53         param=i_param;\r
54         marker_info=new NyARSquare[i_sqaure_max];//static ARMarkerInfo    marker_infoL[AR_SQUARE_MAX];\r
55         //解析オブジェクトを作る\r
56         int width=i_param.getX();\r
57         int height=i_param.getY();\r
58 \r
59         labeling=new NyARLabeling(width,height);\r
60         detect=new NyARDetectMarker(width,height,i_sqaure_max);\r
61     }\r
62     public NyARSquare[] getSquareArray()\r
63     {\r
64         return marker_info;\r
65     }\r
66     public int getSquareCount()\r
67     {\r
68         return number_of_square;\r
69     }\r
70     /**\r
71      * 矩形を検出する。\r
72      * @param i_marker\r
73      * @param i_number_of_marker\r
74      * @throws NyARException\r
75      */\r
76     public void detectSquare(NyARRaster i_image,int i_thresh) throws NyARException\r
77     {\r
78         number_of_square=0;\r
79         labeling.labeling(i_image, i_thresh);\r
80         if(labeling.getLabelNum()<1){\r
81             return;\r
82         }\r
83         detect.detectMarker(labeling,1.0);\r
84         int number_of_marker=detect.getMarkerNum();\r
85 \r
86 \r
87         \r
88         int j=0;\r
89         for (int i = 0; i <number_of_marker; i++){\r
90             double[][]  line    =new double[4][3];\r
91             double[][]  vertex  =new double[4][2];\r
92             NyARMarker marker=detect.getMarker(i);\r
93             \r
94             //・・・線の検出??\r
95             if (!getLine(marker.x_coord, marker.y_coord,marker.coord_num, marker.vertex,line,vertex))\r
96             {\r
97                 continue;\r
98             }\r
99             //markerは参照渡し。実体はdetect内のバッファを共有してるので注意\r
100             marker_info[j]=new NyARSquare(marker,line,vertex);\r
101 \r
102             \r
103 //ここで計算するのは良くないと思うんだ        \r
104 //              marker_infoL[j].id  = id.get();\r
105 //              marker_infoL[j].dir = dir.get();\r
106 //              marker_infoL[j].cf  = cf.get(); \r
107             j++;\r
108             //配列数こえたらドゴォォォンしないようにループを抜ける\r
109             if(j>=marker_info.length){\r
110                 break;\r
111             }\r
112         }\r
113         number_of_square=j;\r
114     }\r
115     /**\r
116      * arGetLine(int x_coord[], int y_coord[], int coord_num,int vertex[], double line[4][3], double v[4][2])\r
117      * arGetLine2(int x_coord[], int y_coord[], int coord_num,int vertex[], double line[4][3], double v[4][2], double *dist_factor)\r
118      * の2関数の合成品です。\r
119      * @param x_coord\r
120      * @param y_coord\r
121      * @param coord_num\r
122      * @param vertex\r
123      * @param line\r
124      * @param v\r
125      * @return\r
126      * @throws NyARException\r
127      */\r
128     private boolean getLine(int x_coord[], int y_coord[], int coord_num,int vertex[], double line[][], double v[][]) throws NyARException\r
129     {\r
130         NyARMat    input,evec;\r
131         NyARVec    ev,mean;\r
132         double   w1;\r
133         int      st, ed, n;\r
134         int      i, j;\r
135         DoubleValue dv1=new DoubleValue();\r
136         DoubleValue dv2=new DoubleValue();\r
137                 \r
138         ev     = new NyARVec(2);\r
139         mean   = new NyARVec(2);\r
140         evec   = new NyARMat(2,2);\r
141         double[] mean_array=mean.getArray();\r
142         double[][] evec_array=evec.getArray();\r
143         for( i = 0; i < 4; i++ ) {\r
144             w1 = (double)(vertex[i+1]-vertex[i]+1) * 0.05 + 0.5;\r
145             st = (int)(vertex[i]   + w1);\r
146             ed = (int)(vertex[i+1] - w1);\r
147             n = ed - st + 1;\r
148             if(n<2){//nが2以下でmatrix.PCAを計算することはできないので、エラーにしておく。\r
149                 //System.err.println("NyARDetectSquare::getLine 稀に出るエラーです。このエラーが出ても例外が起こらなければ平気だと思いますが、出たらnyatlaまで連絡してください。");\r
150                 return false;//throw new NyARException();\r
151             }\r
152             input  = new NyARMat( n, 2 );\r
153             double [][] in_array=input.getArray();\r
154             for( j = 0; j < n; j++ ) {\r
155                 param.observ2Ideal(x_coord[st+j], y_coord[st+j],dv1,dv2);//arParamObserv2Ideal( dist_factor, x_coord[st+j], y_coord[st+j],&(input->m[j*2+0]), &(input->m[j*2+1]) );\r
156                 in_array[j][0]=dv1.value;\r
157                 in_array[j][1]=dv2.value;\r
158             }\r
159             NyARMat.matrixPCA(input, evec, ev, mean);\r
160             \r
161             line[i][0] =  evec_array[0][1];//line[i][0] =  evec->m[1];\r
162             line[i][1] = -evec_array[0][0];//line[i][1] = -evec->m[0];\r
163             line[i][2] = -(line[i][0]*mean_array[0] + line[i][1]*mean_array[1]);//line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);\r
164         }\r
165         \r
166         for( i = 0; i < 4; i++ ) {\r
167             w1 = line[(i+3)%4][0] * line[i][1] - line[i][0] * line[(i+3)%4][1];\r
168             if( w1 == 0.0 ){\r
169                 return false;\r
170             }\r
171             v[i][0] = (  line[(i+3)%4][1] * line[i][2]- line[i][1] * line[(i+3)%4][2] ) / w1;\r
172             v[i][1] = (  line[i][0] * line[(i+3)%4][2]- line[(i+3)%4][0] * line[i][2] ) / w1;\r
173         }\r
174         return true;\r
175     }\r
176 }\r