\r
private final String PARAM_FILE = "../../Data/camera_para.dat";\r
\r
- private final static int SCREEN_X = 320;\r
+ private final static int SCREEN_X = 640;\r
\r
- private final static int SCREEN_Y = 240;\r
+ private final static int SCREEN_Y = 480;\r
\r
private Animator _animator;\r
\r
//キャプチャの準備\r
JmfCaptureDeviceList devlist=new JmfCaptureDeviceList();\r
this._capture=devlist.getDevice(0);\r
- if(!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y,15f)){\r
+ if(!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y,30.0f)){\r
throw new Exception();\r
}\r
this._capture.setOnCapture(this);\r
import jp.nyatla.nyartoolkit.core.pca2d.INyARPca2d;\r
import jp.nyatla.nyartoolkit.core.pca2d.*;\r
import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
-import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
-import jp.nyatla.nyartoolkit.core.types.NyARIntPoint;\r
-import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
-import jp.nyatla.nyartoolkit.core.types.NyARLinear;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;\r
\r
public class NyARQrCodeDetector implements INyARSquareDetector\r
* @return\r
* @throws NyARException\r
*/\r
- private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARLinear[] o_line,NyARIntPoint[] o_imvertex) throws NyARException\r
+ private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARLinear[] o_line,NyARIntPoint2d[] o_imvertex) throws NyARException\r
{\r
final NyARDoubleMatrix22 evec=this.__getSquareLine_evec;\r
final NyARDoublePoint2d mean=this.__getSquareLine_mean;\r
int d;\r
int x,y;\r
int dmax=0x7fffffff;\r
- final NyARIntPoint[] vertex0=i_sqare[0].imvertex;\r
- final NyARIntPoint[] vertex1=i_sqare[1].imvertex;\r
- final NyARIntPoint[] vertex2=i_sqare[2].imvertex;\r
+ final NyARIntPoint2d[] vertex0=i_sqare[0].imvertex;\r
+ final NyARIntPoint2d[] vertex1=i_sqare[1].imvertex;\r
+ final NyARIntPoint2d[] vertex2=i_sqare[2].imvertex;\r
for(int i=0;i<4;i++)\r
{\r
for(int i2=0;i2<4;i2++)\r
* @param i_sqare\r
* @param o_vertex_id\r
*/\r
- private static void getMinimumLineVertex(NyARIntPoint[] i_sqare0,NyARIntPoint[] i_sqare1,int[] o_vertex_id)\r
+ private static void getMinimumLineVertex(NyARIntPoint2d[] i_sqare0,NyARIntPoint2d[] i_sqare1,int[] o_vertex_id)\r
{\r
//辺の長さが最小になる頂点の組合せを探す\r
int d;\r
* @param i_sqare\r
* @param i_center\r
*/\r
- private void getSymbolGroupCenter(NyARSquare[] i_sqare,NyARIntPoint i_center)\r
+ private void getSymbolGroupCenter(NyARSquare[] i_sqare,NyARIntPoint2d i_center)\r
{\r
//シンボルグループの重心を計算\r
int cx,cy;\r
cx=cy=0;\r
for(int i=0;i<3;i++)\r
{\r
- final NyARIntPoint[] sq_ptr=i_sqare[i].imvertex;\r
+ final NyARIntPoint2d[] sq_ptr=i_sqare[i].imvertex;\r
cx+=sq_ptr[0].x; \r
cx+=sq_ptr[1].x; \r
cx+=sq_ptr[2].x; \r
* 最小三角形の頂点IDセット\r
* @return\r
*/\r
- private static int getKeySymble(NyARSquare[] i_sqare,NyARIntPoint i_center,int[] i_vertex_id)\r
+ private static int getKeySymble(NyARSquare[] i_sqare,NyARIntPoint2d i_center,int[] i_vertex_id)\r
{\r
//シンボルグループの重心を計算\r
final int cx=i_center.x;\r
o_qr_square.line[3].copyFrom(i_sq2.line[(i_lv2+0)%4]);\r
//歪み無しの座標系を計算\r
final NyARDoublePoint2d[] l_sqvertex = o_qr_square.sqvertex;\r
- final NyARIntPoint[] imvertex_ptr = o_qr_square.imvertex;\r
+ final NyARIntPoint2d[] imvertex_ptr = o_qr_square.imvertex;\r
\r
final NyARLinear[] l_line = o_qr_square.line;\r
final NyARDoublePoint2d ideal_vertex=this.__bindSquare_ideal_vertex;\r
int[] minimum_triangle_vertex=new int[3];\r
int[] minimum_line_vertex=new int[2];\r
\r
- NyARIntPoint center=new NyARIntPoint();\r
+ NyARIntPoint2d center=new NyARIntPoint2d();\r
\r
//辺の長さが最小になる頂点の組合せを探す\r
getMinimumTriangleVertex(i_sq,minimum_triangle_vertex);\r
* @param i_center\r
* @return\r
*/\r
- private int getDirection(NyARSquare i_square,NyARIntPoint i_vertex,NyARIntPoint i_center)\r
+ private int getDirection(NyARSquare i_square,NyARIntPoint2d i_vertex,NyARIntPoint2d i_center)\r
{\r
//開始点(中央シンボル)までの頂点のシフト数を決める\r
int x,y;\r
}\r
\r
NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;\r
- NyARIntPoint[] l_imvertex = o_square.imvertex;\r
+ NyARIntPoint2d[] l_imvertex = o_square.imvertex;\r
for (int i = 0; i < 4; i++)\r
{\r
NyARI64Linear l_line_i = i64liner[i];\r
--- /dev/null
+package jp.nyatla.nyartoolkit.sandbox.utils;\r
+\r
+/**\r
+ * 1区間にある1個のエッジ位置を推定するクラスです。\r
+ *\r
+ */\r
+public class NyARSingleEdgeFinder\r
+{\r
+ public static class TEdgeInfo\r
+ {\r
+ double point; //検出したエッジの位置\r
+ int sub; //エッジの差分\r
+ } \r
+ private int[] _work;\r
+ private int _width;\r
+ private int _height;\r
+ public NyARSingleEdgeFinder(int i_width,int i_height)\r
+ {\r
+ this._work=new int[(i_width>i_height?i_width:i_height)+1];\r
+ this._work[this._work.length-1]=0;\r
+ this._width=i_width;\r
+ this._height=i_height;\r
+ return;\r
+ }\r
+ /**\r
+ * この関数は、一区間に1個のエッジが含まれていると仮定して、その位置を推定します。\r
+ * [n]個の配列を与えた場合、[n+2]~[n-1]の間にあるエッジを検出します。\r
+ * 検出方向は左→右の順です\r
+ * @param i_pixcel\r
+ * @param i_start\r
+ * @param i_length\r
+ * @param o_out\r
+ * @return\r
+ */\r
+ public boolean scanSingleEdgeLeftToRight(int[] i_pixcel,int i_y,TEdgeInfo o_out)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int length=this._width-1;\r
+ int p=i_y*this._width;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixcel[p+1]-i_pixcel[p];\r
+ p++;\r
+ }\r
+ return scanSingleEdge(temp,length,o_out);\r
+ }\r
+ /**\r
+ * 線分内のエッジを検出します。\r
+ * この関数は、1区間に1個のエッジが含まれていると仮定して、その位置を推定します。\r
+ * [n]個の配列を与えた場合、[n+2]~[n-1]の間にあるエッジを検出します。\r
+ * 検出方向は右→左の順です\r
+ * @param i_pixcel\r
+ * @param i_start\r
+ * @param i_length\r
+ * @param o_out\r
+ * @return\r
+ */\r
+ public boolean scanSingleEdgeRightToLeft(int[] i_pixcel,int i_y,TEdgeInfo o_out)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int length=this._width-1;\r
+ int p=(i_y+1)*this._width-1;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixcel[p-1]-i_pixcel[p];\r
+ p--;\r
+ }\r
+ return scanSingleEdge(temp,length,o_out);\r
+ } \r
+ public boolean scanSingleEdgeTopToBottom(int[] i_pixcel,int i_x,TEdgeInfo o_out)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int step=this._width;\r
+ final int length=this._height-1;\r
+ int p=i_x;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixcel[p+step]-i_pixcel[p];\r
+ p+=step;\r
+ }\r
+ return scanSingleEdge(temp,length,o_out);\r
+ }\r
+ public boolean scanSingleEdgeBottomToTop(int[] i_pixcel,int i_x,TEdgeInfo o_out)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int step=this._width;\r
+ final int length=this._height-1;\r
+ int p=i_x+step*length;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixcel[p-step]-i_pixcel[p];\r
+ p-=step;\r
+ }\r
+ return scanSingleEdge(temp,length,o_out);\r
+ } \r
+ private boolean scanSingleEdge(int[] i_pixels,int i_length,TEdgeInfo o_out)\r
+ {\r
+ //微分(2回目)して、極値2か所を得る\r
+ int max_index,min_index;\r
+ int length=i_length-1;\r
+ max_index=min_index=0;\r
+ int max_value,min_value;\r
+ max_value=min_value=0;\r
+ for(int i2=0;i2<length;i2++){\r
+ int t=i_pixels[i2+1]-i_pixels[i2];\r
+ if(t>max_value){\r
+ max_index=i2;\r
+ max_value=t;\r
+ }\r
+ if(t<min_value){\r
+ min_index=i2;\r
+ min_value=t;\r
+ }\r
+ }\r
+ //同符号である場合、範囲内にエッジはない\r
+ if(max_value*min_value>=0){\r
+ return false;\r
+ } \r
+ o_out.point=(max_index+min_index)/2.0;\r
+ o_out.sub=max_value-min_value;\r
+ return true;\r
+ }\r
+ public int scanEdgeLeftToRight(int[] i_pixel,int i_y,int i_noise_th,double[] o_edge_index)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int length=this._width-1;\r
+ int p=i_y*this._width;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixel[p+1]-i_pixel[p];\r
+ p++;\r
+ }\r
+ //0終端させるために1要素を後続に追加\r
+ return scanEdge(temp,length+1,i_noise_th,o_edge_index);\r
+ }\r
+ private int scanEdge(int[] i_pixels,int i_length,int i_noise_th,double[] o_out)\r
+ {\r
+ int points=0;\r
+ final int length=i_length;\r
+ //エッジ1区間を抜き出す\r
+ for(int i2=0;i2<length;i2++){\r
+ int t=i_pixels[i2];\r
+ if(t>i_noise_th){\r
+ int st=i2;\r
+ i2++;\r
+ for(;i2<length;i2++){\r
+ t=i_pixels[i2];\r
+ if(t<=0){\r
+ //(st - i2で1区間)\r
+ //エッジ位置は区間の中央にする。\r
+ o_out[points]=(st+i2)/2.0;\r
+ points++;\r
+ if(t<0){\r
+ //マイナスであれば、0を補完する\r
+ i2--;\r
+ i_pixels[i2]=0;\r
+ }\r
+ break;\r
+ }\r
+\r
+ }\r
+ }else if(t<-i_noise_th){\r
+ int st=i2;\r
+ i2++;\r
+ for(;i2<length;i2++){\r
+ t=i_pixels[i2];\r
+ if(t>=0){\r
+ //(st - i2で1区間)\r
+ //エッジ位置は区間の中央にする。\r
+ o_out[points]=(st+i2)/2.0;\r
+ points++;\r
+ if(t>0){\r
+ //プラスであれば、0を補完する\r
+ i2--;\r
+ i_pixels[i2]=0;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return points;\r
+ } \r
+ /**\r
+ * 指定した配列をノイズパターンとして、ノイズ値を計算します。\r
+ * このノイズ値は、scanEdgeのノイズ値として使用できます。\r
+ * @param i_pixels\r
+ * @param i_length\r
+ * @return\r
+ */\r
+ public int getNoiseValue(int[] i_pixels,int i_length)\r
+ {\r
+ //1回微分して、その最大値と最小値を計算\r
+ int length=i_length-1;\r
+ int max_value,min_value;\r
+ max_value=min_value=0;\r
+ for(int i2=0;i2<length;i2++){\r
+ int t=i_pixels[i2+1]-i_pixels[i2];\r
+ if(t>max_value){\r
+ max_value=t;\r
+ }\r
+ if(t<min_value){\r
+ min_value=t;\r
+ }\r
+ }\r
+ return (-min_value>max_value)?-min_value:max_value;\r
+ }\r
+}\r
for (r = 0; r < this.row; r++){\r
ptr=i_mat.getArray();\r
for (c = 0; c < this.clm; c++){\r
- this.m[c][r]=(double)ptr[c][r]/0x10000;\r
+ this._m[c][r]=(double)ptr[c][r]/0x10000;\r
}\r
}\r
return;\r
}\r
\r
final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;\r
- final NyARIntPoint[] l_imvertex = o_square.imvertex;\r
+ final NyARIntPoint2d[] l_imvertex = o_square.imvertex;\r
for (int i = 0; i < 4; i++) {\r
final NyARI64Linear l_line_i = i64liner[i];\r
final NyARI64Linear l_line_2 = i64liner[(i + 3) % 4];\r
import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
import jp.nyatla.nyartoolkit.core.transmat.*;\r
-import jp.nyatla.nyartoolkit.sandbox.quadx2.*;\r
\r
\r
/**\r
*/\r
package jp.nyatla.nyartoolkit;\r
\r
+/**\r
+ * NyARToolkitライブラリが生成するExceptionオブジェクトです。\r
+ *\r
+ */\r
public class NyARException extends Exception\r
{\r
private static final long serialVersionUID = 1L;\r
* 配列サイズと行列サイズは必ずしも一致しないことに注意 返された配列のサイズを行列の大きさとして使わないこと!\r
* \r
*/\r
- protected double[][] m;\r
+ protected double[][] _m;\r
+ private int[] __matrixSelfInv_nos;\r
\r
- protected int clm, row;\r
+ protected int clm;\r
+ protected int row;\r
\r
/**\r
* デフォルトコンストラクタは機能しません。\r
\r
public NyARMat(int i_row, int i_clm)\r
{\r
- m = new double[i_row][i_clm];\r
- clm = i_clm;\r
- row = i_row;\r
- }\r
-\r
- /**\r
- * i_row x i_clmサイズの行列を格納できるように行列サイズを変更します。 実行後、行列の各値は不定になります。\r
- * \r
- * @param i_row\r
- * @param i_clm\r
- */\r
- public void realloc(int i_row, int i_clm)\r
- {\r
- if (i_row <= this.m.length && i_clm <= this.m[0].length) {\r
- // 十分な配列があれば何もしない。\r
- } else {\r
- // 不十分なら取り直す。\r
- m = new double[i_row][i_clm];\r
- }\r
+ this._m = new double[i_row][i_clm];\r
this.clm = i_clm;\r
this.row = i_row;\r
+ this.__matrixSelfInv_nos=new int[i_row];\r
+ return;\r
}\r
-\r
+ \r
+ /**\r
+ * 行列の列数を返します。\r
+ * @return\r
+ */\r
public int getClm()\r
{\r
return clm;\r
}\r
-\r
- public int getRow()\r
- {\r
- return row;\r
- }\r
-\r
/**\r
- * 行列をゼロクリアする。\r
+ * 行列の行数を返します。\r
+ * @return\r
*/\r
- public void zeroClear()\r
+ public int getRow()\r
{\r
- int i, i2;\r
- // For順変更OK\r
- for (i = row - 1; i >= 0; i--) {\r
- for (i2 = clm - 1; i2 >= 0; i2--) {\r
- m[i][i2] = 0.0;\r
- }\r
- }\r
- }\r
-\r
+ return row;\r
+ } \r
+ \r
/**\r
- * i_copy_fromの内容を自分自身にコピーします。 高さ・幅は同一で無いと失敗します。\r
- * \r
- * @param i_copy_from\r
+ * 行列のサイズを変更します。\r
+ * 実行後、行列の各値は不定になります。\r
+ * @param i_row\r
+ * @param i_clm\r
*/\r
- public void copyFrom(NyARMat i_copy_from) throws NyARException\r
+ public void realloc(int i_row, int i_clm)\r
{\r
- // サイズ確認\r
- if (this.row != i_copy_from.row || this.clm != i_copy_from.clm) {\r
- throw new NyARException();\r
- }\r
- // 値コピー\r
- for (int r = this.row - 1; r >= 0; r--) {\r
- for (int c = this.clm - 1; c >= 0; c--) {\r
- this.m[r][c] = i_copy_from.m[r][c];\r
- }\r
+ if (i_row <= this._m.length && i_clm <= this._m[0].length) {\r
+ // 十分な配列があれば何もしない。\r
+ } else {\r
+ // 不十分なら取り直す。\r
+ this._m = new double[i_row][i_clm];\r
+ this.__matrixSelfInv_nos=new int[i_row];\r
}\r
+ this.clm = i_clm;\r
+ this.row = i_row;\r
+ return;\r
}\r
-\r
- public double[][] getArray()\r
- {\r
- return m;\r
- }\r
-\r
- // public void getRowVec(int i_row,NyARVec o_vec)\r
- // {\r
- // o_vec.set(this.m[i_row],this.clm);\r
- // }\r
+ \r
+ \r
+ \r
/**\r
- * aとbの積を自分自身に格納する。arMatrixMul()の代替品\r
- * \r
- * @param a\r
- * @param b\r
+ * i_mat_aとi_mat_bの積を計算して、thisへ格納します。\r
+ * @param i_mat_a\r
+ * @param i_mat_b\r
* @throws NyARException\r
*/\r
- public void matrixMul(NyARMat a, NyARMat b) throws NyARException\r
+ public void matrixMul(NyARMat i_mat_a, NyARMat i_mat_b) throws NyARException\r
{\r
- if (a.clm != b.row || this.row != a.row || this.clm != b.clm) {\r
- throw new NyARException();\r
- }\r
+ assert i_mat_a.clm == i_mat_b.row && this.row==i_mat_a.row && this.clm==i_mat_b.clm;\r
+\r
double w;\r
int r, c, i;\r
- double[][] am = a.m, bm = b.m, dm = this.m;\r
+ double[][] am = i_mat_a._m, bm = i_mat_b._m, dm = this._m;\r
// For順変更禁止\r
for (r = 0; r < this.row; r++) {\r
for (c = 0; c < this.clm; c++) {\r
- w = 0.0;// dest.setARELEM0(r, c,0.0);\r
- for (i = 0; i < a.clm; i++) {\r
- w += am[r][i] * bm[i][c];// ARELEM0(dest, r, c) +=ARELEM0(a, r, i) * ARELEM0(b,i, c);\r
+ w = 0.0;\r
+ for (i = 0; i < i_mat_a.clm; i++) {\r
+ w += am[r][i] * bm[i][c];\r
}\r
dm[r][c] = w;\r
}\r
}\r
- }\r
-\r
- private int[] wk_nos_matrixSelfInv = new int[50];\r
-\r
- // private final static double matrixSelfInv_epsl=1.0e-10;\r
+ return;\r
+ } \r
+ \r
/**\r
- * i_targetを逆行列に変換する。arMatrixSelfInv()と、arMatrixSelfInv_minv()関数を合成してあります。\r
- * OPTIMIZE STEP[485->422]\r
- * \r
- * @param i_target\r
- * 逆行列にする行列\r
- * @return 逆行列があればTRUE/無ければFALSE\r
- * \r
+ * 逆行列を計算して、thisへ格納します。\r
* @throws NyARException\r
*/\r
public boolean matrixSelfInv() throws NyARException\r
{\r
- double[][] ap = this.m;\r
+ double[][] ap = this._m;\r
int dimen = this.row;\r
int dimen_1 = dimen - 1;\r
double[] ap_n, ap_ip, ap_i;// wap;\r
int j, ip, nwork;\r
- int[] nos = wk_nos_matrixSelfInv;// この関数で初期化される。\r
+ int[] nos = __matrixSelfInv_nos;//ワーク変数\r
// double epsl;\r
double p, pbuf, work;\r
\r
for (int n = 0; n < dimen; n++) {\r
ap_n = ap[n];// wcp = ap + n * rowa;\r
p = 0.0;\r
- for (int i = n; i < dimen; i++) {// for(i = n, wap = wcp, p =\r
- // 0.0; i < dimen ; i++, wap +=\r
- // rowa)\r
+ for (int i = n; i < dimen; i++) {\r
if (p < (pbuf = Math.abs(ap[i][0]))) {\r
p = pbuf;\r
ip = i;\r
}\r
\r
work = ap_n[0];\r
- for (j = 0; j < dimen_1; j++) {// for(j = 1, wap = wcp, work =\r
- // *wcp; j < dimen ; j++, wap++)\r
+ for (j = 0; j < dimen_1; j++) {\r
ap_n[j] = ap_n[j + 1] / work;// *wap = *(wap + 1) / work;\r
}\r
ap_n[j] = 1.0 / work;// *wap = 1.0 / work;\r
for (int i = 0; i < dimen; i++) {\r
if (i != n) {\r
ap_i = ap[i];// wap = ap + i * rowa;\r
-\r
work = ap_i[0];\r
for (j = 0; j < dimen_1; j++) {// for(j = 1, wbp = wcp,work = *wap;j < dimen ;j++, wap++, wbp++)\r
ap_i[j] = ap_i[j + 1] - work * ap_n[j];// wap = *(wap +1) - work *(*wbp);\r
}\r
}\r
nos[j] = nos[n];\r
- for (int i = 0; i < dimen; i++) {// for(i = 0, wap = ap + j, wbp\r
- // = ap + n; i < dimen ;i++, wap\r
- // += rowa, wbp += rowa) {\r
+ for (int i = 0; i < dimen; i++) {\r
ap_i = ap[i];\r
work = ap_i[j];// work = *wap;\r
ap_i[j] = ap_i[n];// *wap = *wbp;\r
}\r
\r
/**\r
+ * 行列をゼロクリアする。\r
+ */\r
+ public void zeroClear()\r
+ {\r
+ int i, i2;\r
+ // For順変更OK\r
+ for (i = row - 1; i >= 0; i--) {\r
+ for (i2 = clm - 1; i2 >= 0; i2--) {\r
+ _m[i][i2] = 0.0;\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * i_copy_fromの内容を自分自身にコピーします。 高さ・幅は同一で無いと失敗します。\r
+ * \r
+ * @param i_copy_from\r
+ */\r
+ public void copyFrom(NyARMat i_copy_from) throws NyARException\r
+ {\r
+ // サイズ確認\r
+ if (this.row != i_copy_from.row || this.clm != i_copy_from.clm) {\r
+ throw new NyARException();\r
+ }\r
+ // 値コピー\r
+ for (int r = this.row - 1; r >= 0; r--) {\r
+ for (int c = this.clm - 1; c >= 0; c--) {\r
+ this._m[r][c] = i_copy_from._m[r][c];\r
+ }\r
+ }\r
+ }\r
+\r
+ public double[][] getArray()\r
+ {\r
+ return _m;\r
+ }\r
+\r
+\r
+ /**\r
* sourceの転置行列をdestに得る。arMatrixTrans()の代替品\r
* \r
* @param dest\r
// For順変更禁止\r
for (int r = 0; r < dest.row; r++) {\r
for (int c = 0; c < dest.clm; c++) {\r
- dest.m[r][c] = source.m[c][r];\r
+ dest._m[r][c] = source._m[c][r];\r
}\r
}\r
}\r
for (int r = 0; r < unit.getRow(); r++) {\r
for (int c = 0; c < unit.getClm(); c++) {\r
if (r == c) {\r
- unit.m[r][c] = 1.0;\r
+ unit._m[r][c] = 1.0;\r
} else {\r
- unit.m[r][c] = 0.0;\r
+ unit._m[r][c] = 0.0;\r
}\r
}\r
}\r
// 内容を転写\r
int r, c;\r
double[][] src_m, dest_m;\r
- src_m = i_source.m;\r
- dest_m = this.m;\r
+ src_m = i_source._m;\r
+ dest_m = this._m;\r
// コピーはFor順を変えてもOK\r
for (r = this.row - 1; r >= 0; r--) {\r
for (c = this.clm - 1; c >= 0; c--) {\r
// コピー\r
int r, c;\r
double[][] dest_m, src_m;\r
- dest_m = result.m;\r
- src_m = this.m;\r
+ dest_m = result._m;\r
+ src_m = this._m;\r
// コピーはFor順を変えてもOK\r
for (r = this.row - 1; r >= 0; r--) {\r
for (c = this.clm - 1; c >= 0; c--) {\r
return result;\r
}\r
\r
- /**\r
- * arMatrixInv関数の代替品です。 destにsourceの逆行列を返します。\r
- * \r
- * @param dest\r
- * @param source\r
- * @throws NyARException\r
- */\r
- public static void matrixInv(NyARMat dest, NyARMat source)\r
- throws NyARException\r
- {\r
- NyARException.trap("未チェックのパス");\r
- dest.matrixDup(source);\r
-\r
- NyARException.trap("未チェックのパス");\r
- dest.matrixSelfInv();\r
- }\r
-\r
- public NyARMat matrixAllocInv() throws NyARException\r
- {\r
- NyARException.trap("未チェックのパス");\r
- NyARMat result = matrixAllocDup();\r
-\r
- NyARException.trap("未チェックのパス");\r
- result.matrixSelfInv();\r
- return result;\r
- }\r
-\r
- /**\r
- * dim x dim の単位行列を作る。\r
- * \r
- * @param dim\r
- * @return\r
- * @throws NyARException\r
- */\r
- public static NyARMat matrixAllocUnit(int dim) throws NyARException\r
- {\r
- NyARException.trap("未チェックのパス");\r
- NyARMat result = new NyARMat(dim, dim);\r
- NyARException.trap("未チェックのパス");\r
- NyARMat.matrixUnit(result);\r
- return result;\r
- }\r
-\r
- /**\r
- * arMatrixDispの代替品\r
- * \r
- * @param m\r
- * @return\r
- */\r
- public int matrixDisp() throws NyARException\r
- {\r
- NyARException.trap("未チェックのパス");\r
- System.out.println(" === matrix (" + row + "," + clm + ") ===");// printf(" ===matrix (%d,%d) ===\n", m->row, m->clm);\r
- for (int r = 0; r < row; r++) {// for(int r = 0; r < m->row; r++) {\r
- System.out.print(" |");// printf(" |");\r
- for (int c = 0; c < clm; c++) {// for(int c = 0; c < m->clm; c++) {\r
- System.out.print(" " + m[r][c]);// printf(" %10g", ARELEM0(m, r, c));\r
- }\r
- System.out.println(" |");// printf(" |\n");\r
- }\r
- System.out.println(" ======================");// printf(" ======================\n");\r
- return 0;\r
- }\r
\r
private static final double PCA_EPS = 1e-6; // #define EPS 1e-6\r
\r
int i, i2;\r
lrow = this.row;\r
lclm = this.clm;\r
- double[][] lm = this.m;\r
+ double[][] lm = this._m;\r
\r
if (lrow <= 0 || lclm <= 0) {\r
throw new NyARException();\r
double[] v;\r
int row, clm;\r
\r
- row = inout.getRow();\r
- clm = inout.getClm();\r
+ row = inout.row;\r
+ clm = inout.clm;\r
if (mean.getClm() != clm) {\r
throw new NyARException();\r
}\r
- double[][] im = inout.m;\r
+ double[][] im = inout._m;\r
double[] im_i;\r
double w0, w1;\r
v = mean.getArray();\r
for (int j = 0; j < row; j++) {\r
if (j < i) {\r
NyARException.trap("未チェックのパス");\r
- output.m[i][j] = output.m[j][i];// *out =\r
+ output._m[i][j] = output._m[j][i];// *out =\r
// output->m[j*row+i];\r
} else {\r
NyARException.trap("未チェックのパス");\r
- in1 = input.m[i];// input.getRowArray(i);//in1 = &(input->m[clm*i]);\r
- in2 = input.m[j];// input.getRowArray(j);//in2 = &(input->m[clm*j]);\r
- output.m[i][j] = 0;// *out = 0.0;\r
+ in1 = input._m[i];// input.getRowArray(i);//in1 = &(input->m[clm*i]);\r
+ in2 = input._m[j];// input.getRowArray(j);//in2 = &(input->m[clm*j]);\r
+ output._m[i][j] = 0;// *out = 0.0;\r
for (int k = 0; k < clm; k++) {\r
- output.m[i][j] += (in1[k] * in2[k]);// *out += *(in1++)\r
+ output._m[i][j] += (in1[k] * in2[k]);// *out += *(in1++)\r
// * *(in2++);\r
}\r
}\r
}\r
\r
int k, j;\r
- double[][] out_m = i_output.m;\r
+ double[][] out_m = i_output._m;\r
double w;\r
for (int i = 0; i < clm; i++) {\r
for (j = 0; j < clm; j++) {\r
} else {\r
w = 0.0;// *out = 0.0;\r
for (k = 0; k < row; k++) {\r
- in_ = input.m[k];// in=input.getRowArray(k);\r
+ in_ = input._m[k];// in=input.getRowArray(k);\r
w += (in_[i] * in_[j]);// *out += *in1 * *in2;\r
}\r
out_m[i][j] = w;\r
if (ev == null) {\r
throw new NyARException();\r
}\r
- final double[][] L_m = this.m;\r
+ final double[][] L_m = this._m;\r
this.vecTridiagonalize(dv, ev, 1);\r
\r
ev_array[0] = 0.0;// ev->v[0] = 0.0;\r
{\r
int i;\r
double w;\r
- double[] r1 = this.m[i_row_1], r2 = this.m[i_row_2];\r
+ double[] r1 = this._m[i_row_1], r2 = this._m[i_row_2];\r
// For順変更OK\r
for (i = clm - 1; i >= 0; i--) {\r
w = r1[i];\r
double sum, work;\r
\r
NyARException.trap("未チェックのパス");\r
- m = output.m;// m = output->m;\r
- in_ = input.m;\r
+ m = output._m;// m = output->m;\r
+ in_ = input._m;\r
int i;\r
ev_array = ev.getArray();\r
for (i = 0; i < row; i++) {\r
// sqrt(fabs(ev->v[i]));\r
for (int j = 0; j < clm; j++) {\r
sum = 0.0;\r
- m1 = u.m[i];// m1 = &(u->m[i*row]);\r
+ m1 = u._m[i];// m1 = &(u->m[i*row]);\r
// m2=input.getPointer(j);//m2 = &(input->m[j]);\r
for (int k = 0; k < row; k++) {\r
sum += m1[k] + in_[k][j];// sum += *m1 * *m2;\r
NyARException.trap("未チェックのパス");\r
PCA_EV_create(this, u, o_output, o_ev);\r
} else {\r
- m1 = u.m;// m1 = u->m;\r
- m2 = o_output.m;// m2 = output->m;\r
+ m1 = u._m;// m1 = u->m;\r
+ m2 = o_output._m;// m2 = output->m;\r
int i;\r
for (i = 0; i < min; i++) {\r
if (ev_array[i] < PCA_VZERO) {// if( ev->v[i] < VZERO ){\r
}\r
}\r
}\r
-\r
- private NyARMat wk_work_matrixPCA = null;\r
-\r
/**\r
- * int arMatrixPCA( ARMat *input, ARMat *evec, ARVec *ev, ARVec *mean );\r
- * 関数の置き換え。input引数がthisになる。 Optimize:2008.04.19\r
- * \r
+ * 主成分分析を実行して、結果をthisと引数へ格納します。\r
* @param o_evec\r
* @param o_ev\r
- * \r
- * @param mean\r
+ * @param o_mean\r
* @throws NyARException\r
*/\r
- public void matrixPCA(NyARMat o_evec, NyARVec o_ev, NyARVec mean)throws NyARException\r
- {\r
- double srow, sum;\r
- int l_row, l_clm;\r
- int check;\r
-\r
- l_row = this.row;// row = input->row;\r
- l_clm = this.clm;// clm = input->clm;\r
- check = (l_row < l_clm) ? l_row : l_clm;\r
- if (l_row < 2 || l_clm < 2) {\r
- throw new NyARException();\r
- }\r
- if (o_evec.clm != l_clm || o_evec.row != check) {// if( evec->clm !=\r
- // input->clm ||\r
- // evec->row !=\r
- // check ){\r
- throw new NyARException();\r
- }\r
- if (o_ev.getClm() != check) {// if( ev->clm != check ){\r
- throw new NyARException();\r
- }\r
- if (mean.getClm() != l_clm) {// if( mean->clm != input->clm ){\r
- throw new NyARException();\r
- }\r
-\r
- // 自分の内容をワークにコピー(高速化の為に、1度作ったインスタンスは使いまわす)\r
- NyARMat work;\r
- if (this.wk_work_matrixPCA == null) {\r
- work = this.matrixAllocDup();\r
- this.wk_work_matrixPCA = work;\r
- } else {\r
- work = this.wk_work_matrixPCA;\r
- work.matrixDup(this);// arMatrixAllocDup( input );work =\r
- // arMatrixAllocDup( input );\r
- }\r
-\r
- srow = Math.sqrt((double) l_row);\r
- work.PCA_EX(mean);\r
-\r
- PCA_CENTER(work, mean);\r
+ public void pca(NyARMat o_evec, NyARVec o_ev, NyARVec o_mean)throws NyARException\r
+ {\r
+ final double l_row = this.row;// row = input->row;\r
+ final double l_clm = this.clm;// clm = input->clm;\r
+ final double check=(l_row < l_clm) ? l_row : l_clm;\r
+ \r
+ assert l_row >= 2 || l_clm >= 2;\r
+ assert o_evec.clm == l_clm && o_evec.row == check;\r
+ assert o_ev.getClm() == check;\r
+ assert o_mean.getClm() == l_clm;\r
+ \r
+ final double srow = Math.sqrt((double) l_row);\r
+ PCA_EX(o_mean);\r
+\r
+ PCA_CENTER(this, o_mean);\r
\r
int i, j;\r
// For順変更OK\r
for (i = 0; i < l_row; i++) {\r
for (j = 0; j < l_clm; j++) {\r
- work.m[i][j] /= srow;// work->m[i] /= srow;\r
+ this._m[i][j] /= srow;// work->m[i] /= srow;\r
}\r
}\r
\r
- work.PCA_PCA(o_evec, o_ev);\r
+ PCA_PCA(o_evec, o_ev);\r
\r
- sum = 0.0;\r
+ double sum = 0.0;\r
double[] ev_array = o_ev.getArray();\r
int ev_clm = o_ev.getClm();\r
// For順変更禁止\r
for (i = 0; i < ev_clm; i++) {// for(int i = 0; i < ev->clm; i++ ){\r
ev_array[i] /= sum;// ev->v[i] /= sum;\r
}\r
- }\r
-\r
- /* int arMatrixPCA2( ARMat *input, ARMat *evec, ARVec *ev ); */\r
- public static void arMatrixPCA2(NyARMat input, NyARMat evec, NyARVec ev) throws NyARException\r
- {\r
- NyARException.trap("未チェックのパス");\r
- NyARMat work;\r
- // double srow; // unreferenced\r
- double sum;\r
- int row, clm;\r
- int check;\r
-\r
- row = input.row;// row = input->row;\r
- clm = input.clm;// clm = input->clm;\r
- check = (row < clm) ? row : clm;\r
- if (row < 2 || clm < 2) {\r
- throw new NyARException();\r
- }\r
- if (evec.getClm() != input.clm || evec.row != check) {// if( evec->clm!= input->clm|| evec->row!= check ){\r
- throw new NyARException();\r
- }\r
- if (ev.getClm() != check) {// if( ev->clm != check ){\r
- throw new NyARException();\r
- }\r
-\r
- NyARException.trap("未チェックのパス");\r
- work = input.matrixAllocDup();\r
-\r
- NyARException.trap("未チェックパス");\r
- work.PCA_PCA(evec, ev);// rval = PCA( work, evec, ev );\r
- sum = 0.0;\r
- double[] ev_array = ev.getArray();\r
- for (int i = 0; i < ev.getClm(); i++) {// for( i = 0; i < ev->clm; i++\r
- // ){\r
- NyARException.trap("未チェックパス");\r
- sum += ev_array[i];// sum += ev->v[i];\r
- }\r
- for (int i = 0; i < ev.getClm(); i++) {// for(int i = 0; i < ev->clm;i++ ){\r
- NyARException.trap("未チェックパス");\r
- ev_array[i] /= sum;// ev->v[i] /= sum;\r
- }\r
return;\r
}\r
+ \r
\r
- public static NyARMat matrixAllocMul(NyARMat a, NyARMat b) throws NyARException\r
- {\r
- NyARException.trap("未チェックのパス");\r
- NyARMat dest = new NyARMat(a.row, b.clm);\r
- NyARException.trap("未チェックのパス");\r
- dest.matrixMul(a, b);\r
- return dest;\r
- }\r
-\r
- /* static double mdet(double *ap, int dimen, int rowa) */\r
- private static double Det_mdet(double[][] ap, int dimen, int rowa) throws NyARException\r
- {\r
- NyARException.trap("動作未チェック/配列化未チェック");\r
- double det = 1.0;\r
- double work;\r
- int is_ = 0;\r
- int mmax;\r
-\r
- for (int k = 0; k < dimen - 1; k++) {\r
- mmax = k;\r
- for (int i = k + 1; i < dimen; i++) {\r
- // if (Math.abs(arMatrixDet_MATRIX_get(ap, i, k, rowa)) >\r
- // Math.abs(arMatrixDet_MATRIX_get(ap, mmax, k, rowa))){\r
- if (Math.abs(ap[i][k]) > Math.abs(ap[mmax][k])) {\r
- mmax = i;\r
- }\r
- }\r
- if (mmax != k) {\r
- for (int j = k; j < dimen; j++) {\r
- work = ap[k][j];// work = MATRIX(ap, k, j, rowa);\r
- ap[k][j] = ap[mmax][j];// MATRIX(ap, k, j, rowa) =MATRIX(ap, mmax, j, rowa);\r
- ap[mmax][j] = work;// MATRIX(ap, mmax, j, rowa) = work;\r
- }\r
- is_++;\r
- }\r
- for (int i = k + 1; i < dimen; i++) {\r
- work = ap[i][k] / ap[k][k];// work = arMatrixDet_MATRIX_get(ap,i, k, rowa) /arMatrixDet_MATRIX_get(ap, k, k,rowa);\r
- for (int j = k + 1; j < dimen; j++) {\r
- // MATRIX(ap, i, j, rowa) -= work * MATRIX(ap, k, j, rowa);\r
- ap[i][j] -= work * ap[k][j];\r
- }\r
- }\r
- }\r
- for (int i = 0; i < dimen; i++) {\r
- det = ap[i][i];// det *= MATRIX(ap, i, i, rowa);\r
- }\r
- for (int i = 0; i < is_; i++) {\r
- det *= -1.0;\r
- }\r
- return det;\r
- }\r
-\r
- /* double arMatrixDet(ARMat *m); */\r
- public static double arMatrixDet(NyARMat m) throws NyARException\r
- {\r
- NyARException.trap("動作未チェック/配列化未チェック");\r
- if (m.row != m.clm) {\r
- return 0.0;\r
- }\r
- return Det_mdet(m.getArray(), m.row, m.clm);// return mdet(m->m, m->row,m->row);\r
- }\r
\r
private final NyARVec wk_vecTridiagonalize_vec = new NyARVec(0);\r
\r
\r
for (int k = 0; k < dim - 2; k++) {\r
\r
- a_vec_k = this.m[k];\r
+ a_vec_k = this._m[k];\r
vec.setNewArray(a_vec_k, clm);// vec=this.getRowVec(k);//double[]\r
// vec_array=vec.getArray();\r
NyARException.trap("未チェックパス");\r
s = 0.0;\r
for (int j = k + 1; j < i; j++) {\r
NyARException.trap("未チェックのパス");\r
- s += this.m[j][i] * a_vec_k[j];// s += a_array[j][i] *vec.v[j];//s +=a.get(j*dim+i) *v.get(j);//s +=a->m[j*dim+i] * v[j];\r
+ s += this._m[j][i] * a_vec_k[j];// s += a_array[j][i] *vec.v[j];//s +=a.get(j*dim+i) *v.get(j);//s +=a->m[j*dim+i] * v[j];\r
}\r
for (int j = i; j < dim; j++) {\r
NyARException.trap("未チェックのパス");\r
- s += this.m[i][j] * a_vec_k[j];// s += a_array[i][j] *vec.v[j];//s +=a.get(i*dim+j) *v.get(j);//s +=a->m[i*dim+j] * v[j];\r
+ s += this._m[i][j] * a_vec_k[j];// s += a_array[i][j] *vec.v[j];//s +=a.get(i*dim+j) *v.get(j);//s +=a->m[i*dim+j] * v[j];\r
}\r
NyARException.trap("未チェックのパス");\r
d_vec[i] = s;// d.v[i]=s;//d->v[i] = s;\r
// wv1.clm = wv2.clm = dim-k-1;\r
// wv1.v = &(v[k+1]);\r
// wv2.v = &(d->v[k+1]);\r
- a_vec_k = this.m[k];\r
+ a_vec_k = this._m[k];\r
vec.setNewArray(a_vec_k, clm);// vec=this.getRowVec(k);\r
// vec_array=vec.getArray();\r
NyARException.trap("未チェックパス");\r
q = d_vec[i];// d.v[i]-=t*p;q=d.v[i];//q = d->v[i] -= t*p;\r
for (int j = i; j < dim; j++) {\r
NyARException.trap("未チェックパス");\r
- this.m[i][j] -= p * (d_vec[j] + q * a_vec_k[j]);// a.m[i][j]-=p*(d.v[j] +q*vec.v[j]);//a->m[i*dim+j] -=p*(d->v[j]) + q*v[j];\r
+ this._m[i][j] -= p * (d_vec[j] + q * a_vec_k[j]);// a.m[i][j]-=p*(d.v[j] +q*vec.v[j]);//a->m[i*dim+j] -=p*(d->v[j]) + q*v[j];\r
}\r
}\r
}\r
\r
if (dim >= 2) {\r
- d_vec[dim - 2] = 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)];\r
- e_vec[dim - 2 + i_e_start] = 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)];\r
+ d_vec[dim - 2] = 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)];\r
+ e_vec[dim - 2 + i_e_start] = 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)];\r
}\r
\r
if (dim >= 1) {\r
- d_vec[dim - 1] = 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)];\r
+ d_vec[dim - 1] = 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)];\r
}\r
NyARVec vec2 = this.wk_vecTridiagonalize_vec2;\r
for (int k = dim - 1; k >= 0; k--) {\r
- a_vec_k = this.m[k];\r
+ a_vec_k = this._m[k];\r
vec.setNewArray(a_vec_k, clm);// vec=this.getRowVec(k);//v =a.getPointer(k*dim);//v = &(a->m[k*dim]);\r
if (k < dim - 2) {\r
for (int i = k + 1; i < dim; i++) {\r
// wv1.clm = wv2.clm = dim-k-1;\r
// wv1.v = &(v[k+1]);\r
// wv2.v = &(a->m[i*dim+k+1]);\r
- vec2.setNewArray(this.m[i], clm);// vec2=this.getRowVec(i);\r
+ vec2.setNewArray(this._m[i], clm);// vec2=this.getRowVec(i);\r
\r
t = vec.vecInnerproduct(vec2, k + 1);\r
for (int j = k + 1; j < dim; j++) {\r
NyARException.trap("未チェックパス");\r
- this.m[i][j] -= t * a_vec_k[j];// a_array[i][j]-=t*vec.v[j];//a.subValue(i*dim+j,t*v.get(j));//a->m[i*dim+j]-= t * v[j];\r
+ this._m[i][j] -= t * a_vec_k[j];// a_array[i][j]-=t*vec.v[j];//a.subValue(i*dim+j,t*v.get(j));//a->m[i*dim+j]-= t * v[j];\r
}\r
}\r
}\r
public int direction;\r
public NyARLinear[] line = new NyARLinear[4];\r
public NyARDoublePoint2d[] sqvertex = new NyARDoublePoint2d[4];\r
- public NyARIntPoint[] imvertex = new NyARIntPoint[4];\r
+ public NyARIntPoint2d[] imvertex = new NyARIntPoint2d[4];\r
public NyARSquare()\r
{\r
this.direction=DIRECTION_UNKNOWN;\r
for(int i=0;i<4;i++){\r
this.sqvertex[i]=new NyARDoublePoint2d();\r
- this.imvertex[i]=new NyARIntPoint();\r
+ this.imvertex[i]=new NyARIntPoint2d();\r
this.line[i]=new NyARLinear();\r
}\r
}\r
}\r
\r
final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;\r
- final NyARIntPoint[] l_imvertex = o_square.imvertex;\r
+ final NyARIntPoint2d[] l_imvertex = o_square.imvertex;\r
for (int i = 0; i < 4; i++) {\r
final NyARLinear l_line_i = l_line[i];\r
final NyARLinear l_line_2 = l_line[(i + 3) % 4];\r
return -s;\r
}\r
\r
- // /**\r
- // * arVecTridiagonalize関数の代替品\r
- // * a,d,e間で演算をしてる。何をどうしているかはさっぱりさっぱり\r
- // * @param a\r
- // * @param d\r
- // * @param e\r
- // * @param i_e_start\r
- // * 演算開始列(よくわからないけどarVecTridiagonalizeの呼び出し元でなんかしてる)\r
- // * @return\r
- // * @throws NyARException\r
- // */\r
- // public static void vecTridiagonalize(NyARMat a, NyARVec d, NyARVec e,int\r
- // i_e_start) throws NyARException\r
- // {\r
- // NyARVec vec,vec2;\r
- // double[][] a_array=a.getArray();\r
- // double s, t, p, q;\r
- // int dim;\r
- //\r
- // if(a.getClm()!=a.getRow()){\r
- // throw new NyARException();\r
- // }\r
- // if(a.getClm() != d.clm){\r
- // throw new NyARException();\r
- // }\r
- // if(a.getClm() != e.clm){\r
- // throw new NyARException();\r
- // }\r
- // dim = a.getClm();\r
- //\r
- // for(int k = 0; k < dim-2; k++ ){\r
- // vec=a.getRowVec(k);\r
- // // double[] vec_array=vec.getArray();\r
- // NyARException.trap("未チェックパス");\r
- // d.v[k]=vec.v[k];//d.set(k,v.get(k)); //d->v[k] = v[k];\r
- //\r
- // //wv1.clm = dim-k-1;\r
- // //wv1.v = &(v[k+1]);\r
- // NyARException.trap("未チェックパス");\r
- // e.v[k+i_e_start]=vec.vecHousehold(k+1);//e->v[k] = arVecHousehold(&wv1);\r
- // if(e.v[k+i_e_start]== 0.0 ){\r
- // continue;\r
- // }\r
- //\r
- // for(int i = k+1; i < dim; i++ ){\r
- // s = 0.0;\r
- // for(int j = k+1; j < i; j++ ) {\r
- // NyARException.trap("未チェックのパス");\r
- // s += a_array[j][i] * vec.v[j];//s += a.get(j*dim+i) * v.get(j);//s +=\r
- // a->m[j*dim+i] * v[j];\r
- // }\r
- // for(int j = i; j < dim; j++ ) {\r
- // NyARException.trap("未チェックのパス");\r
- // s += a_array[i][j] * vec.v[j];//s += a.get(i*dim+j) * v.get(j);//s +=\r
- // a->m[i*dim+j] * v[j];\r
- // }\r
- // NyARException.trap("未チェックのパス");\r
- // d.v[i]=s;//d->v[i] = s;\r
- // }\r
- //\r
- //\r
- // //wv1.clm = wv2.clm = dim-k-1;\r
- // //wv1.v = &(v[k+1]);\r
- // //wv2.v = &(d->v[k+1]);\r
- // vec=a.getRowVec(k);\r
- // // vec_array=vec.getArray();\r
- // NyARException.trap("未チェックパス");\r
- // t = vec.vecInnerproduct(d,k+1)/ 2;\r
- // for(int i = dim-1; i > k; i-- ) {\r
- // NyARException.trap("未チェックパス");\r
- // p = vec.v[i];//p = v.get(i);//p = v[i];\r
- // d.v[i]-=t*p;q=d.v[i];//q = d->v[i] -= t*p;\r
- // for(int j = i; j < dim; j++ ){\r
- // NyARException.trap("未チェックパス");\r
- // a_array[i][j]-=p*(d.v[j] + q*vec.v[j]);//a->m[i*dim+j] -= p*(d->v[j]) +\r
- // q*v[j];\r
- // }\r
- // }\r
- // }\r
- //\r
- // if( dim >= 2) {\r
- // d.v[dim-2]=a_array[dim-2][dim-2];//d->v[dim-2] =\r
- // a->m[(dim-2)*dim+(dim-2)];\r
- // e.v[dim-2+i_e_start]=a_array[dim-2][dim-1];//e->v[dim-2] =\r
- // a->m[(dim-2)*dim+(dim-1)];\r
- // }\r
- //\r
- // if( dim >= 1 ){\r
- // d.v[dim-1]=a_array[dim-1][dim-1];//d->v[dim-1] =\r
- // a->m[(dim-1)*dim+(dim-1)];\r
- // }\r
- //\r
- // for(int k = dim-1; k >= 0; k--) {\r
- // vec=a.getRowVec(k);//v = a.getPointer(k*dim);//v = &(a->m[k*dim]);\r
- // if( k < dim-2 ) {\r
- // for(int i = k+1; i < dim; i++ ){\r
- // //wv1.clm = wv2.clm = dim-k-1;\r
- // //wv1.v = &(v[k+1]);\r
- // //wv2.v = &(a->m[i*dim+k+1]);\r
- // vec2=a.getRowVec(i);\r
- //\r
- // t = vec.vecInnerproduct(vec2,k+1);\r
- // for(int j = k+1; j < dim; j++ ){\r
- // NyARException.trap("未チェックパス");\r
- // a_array[i][j]-=t*vec.v[j];//a.subValue(i*dim+j,t*v.get(j));//a->m[i*dim+j]\r
- // -= t * v[j];\r
- // }\r
- // }\r
- // }\r
- // for(int i = 0; i < dim; i++ ){\r
- // vec.v[i]=0.0;//v.set(i,0.0);//v[i] = 0.0;\r
- // }\r
- // vec.v[k]=1;//v.set(k,1);//v[k] = 1;\r
- // }\r
- // }\r
/**\r
* 現在ラップしている配列を取り外して、新しい配列をラップします。\r
* \r
input_array[i][1]=i_y[i];\r
}\r
// 主成分分析\r
- input.matrixPCA(this.__pca_evec, this.__pca_ev, this.__pca_mean);\r
+ input.pca(this.__pca_evec, this.__pca_ev, this.__pca_mean);\r
final double[] mean_array = this.__pca_mean.getArray();\r
final double[][] evec_array = this.__pca_evec.getArray();\r
final double[] ev_array=this.__pca_ev.getArray();\r
import jp.nyatla.nyartoolkit.NyARException;\r
import jp.nyatla.nyartoolkit.core.NyARSquare;\r
import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
-import jp.nyatla.nyartoolkit.core.raster.*;\r
\r
-public interface INyARColorPatt extends INyARRaster\r
+public interface INyARColorPatt extends INyARRgbRaster\r
{\r
/**\r
* ラスタイメージからi_square部分のカラーパターンを抽出して、thisメンバに格納します。\r
import jp.nyatla.nyartoolkit.core.NyARSquare;\r
import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
/**\r
* 24ビットカラーのマーカーを保持するために使うクラスです。 このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。\r
\r
private int[] _patdata;\r
private NyARBufferReader _buf_reader;\r
+ private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
\r
private NyARIntSize _size;\r
\r
public NyARColorPatt_O1(int i_width, int i_height)\r
{\r
//入力制限\r
- assert i_width<=64;\r
- assert i_height<=64;\r
+ assert i_width<=64 && i_height<=64;\r
\r
this._size=new NyARIntSize(i_width,i_height);\r
this._patdata = new int[i_height*i_width];\r
this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
return;\r
}\r
\r
- public int getWidth()\r
+ public final int getWidth()\r
{\r
return this._size.w;\r
}\r
- public int getHeight()\r
+ public final int getHeight()\r
{\r
return this._size.h;\r
}\r
- public NyARIntSize getSize()\r
+ public final NyARIntSize getSize()\r
{\r
return this._size;\r
}\r
- public INyARBufferReader getBufferReader()\r
+ public final INyARBufferReader getBufferReader()\r
{\r
return this._buf_reader;\r
}\r
+ public final INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._pixelreader;\r
+ }\r
\r
- private final NyARMat wk_get_cpara_a = new NyARMat(8, 8);\r
-\r
- private final NyARMat wk_get_cpara_b = new NyARMat(8, 1);\r
-\r
- private final NyARMat wk_get_cpara_c = new NyARMat(8, 1);\r
-\r
- /**\r
- * \r
- * @param world\r
- * @param vertex\r
- * @param para\r
- * [3x3]\r
- * @throws NyARException\r
- */\r
- private boolean get_cpara(double world[][], double vertex[][], double[] para)throws NyARException\r
+ private final NyARMat __get_cpara_a = new NyARMat(8, 8);\r
+ private final NyARMat __get_cpara_b = new NyARMat(8, 1);\r
+ private final double[][] __get__cpara_world = {{ 100.0, 100.0 }, { 100.0 + 10.0, 100.0 }, { 100.0 + 10.0, 100.0 + 10.0 },{ 100.0, 100.0 + 10.0 } };\r
+ \r
+ final protected boolean get_cpara(final NyARIntPoint2d[] i_vertex, NyARMat o_para)throws NyARException\r
{\r
- NyARMat a = wk_get_cpara_a;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );\r
+ double[][] world = this.__get__cpara_world;\r
+ NyARMat a = __get_cpara_a;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );\r
double[][] a_array = a.getArray();\r
- NyARMat b = wk_get_cpara_b;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );\r
+ NyARMat b = __get_cpara_b;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );\r
double[][] b_array = b.getArray();\r
- double[] a_pt0, a_pt1, world_pti;\r
+ double[] a_pt0, a_pt1;\r
+ double[] world_pti;\r
\r
for (int i = 0; i < 4; i++) {\r
a_pt0 = a_array[i * 2];\r
a_pt1 = a_array[i * 2 + 1];\r
world_pti = world[i];\r
\r
- a_pt0[0] = world_pti[0];// a->m[i*16+0] = world[i][0];\r
- a_pt0[1] = world_pti[1];// a->m[i*16+1] = world[i][1];\r
+ a_pt0[0] = (double) world_pti[0];// a->m[i*16+0] = world[i][0];\r
+ a_pt0[1] = (double) world_pti[1];// a->m[i*16+1] = world[i][1];\r
a_pt0[2] = 1.0;// a->m[i*16+2] = 1.0;\r
a_pt0[3] = 0.0;// a->m[i*16+3] = 0.0;\r
a_pt0[4] = 0.0;// a->m[i*16+4] = 0.0;\r
a_pt0[5] = 0.0;// a->m[i*16+5] = 0.0;\r
- a_pt0[6] = -world_pti[0] * vertex[i][0];// a->m[i*16+6] =-world[i][0] *vertex[i][0];\r
- a_pt0[7] = -world_pti[1] * vertex[i][0];// a->m[i*16+7] =-world[i][1] *vertex[i][0];\r
+ a_pt0[6] = (double) (-world_pti[0] * i_vertex[i].x);// a->m[i*16+6]= -world[i][0]*vertex[i][0];\r
+ a_pt0[7] = (double) (-world_pti[1] * i_vertex[i].x);// a->m[i*16+7]=-world[i][1]*vertex[i][0];\r
a_pt1[0] = 0.0;// a->m[i*16+8] = 0.0;\r
a_pt1[1] = 0.0;// a->m[i*16+9] = 0.0;\r
a_pt1[2] = 0.0;// a->m[i*16+10] = 0.0;\r
- a_pt1[3] = world_pti[0];// a->m[i*16+11] = world[i][0];\r
- a_pt1[4] = world_pti[1];// a->m[i*16+12] = world[i][1];\r
+ a_pt1[3] = (double) world_pti[0];// a->m[i*16+11] = world[i][0];\r
+ a_pt1[4] = (double) world_pti[1];// a->m[i*16+12] = world[i][1];\r
a_pt1[5] = 1.0;// a->m[i*16+13] = 1.0;\r
- a_pt1[6] = -world_pti[0] * vertex[i][1];// a->m[i*16+14] =-world[i][0] *vertex[i][1];\r
- a_pt1[7] = -world_pti[1] * vertex[i][1];// a->m[i*16+15] =-world[i][1] *vertex[i][1];\r
- b_array[i * 2 + 0][0] = vertex[i][0];// b->m[i*2+0] =vertex[i][0];\r
- b_array[i * 2 + 1][0] = vertex[i][1];// b->m[i*2+1] =vertex[i][1];\r
+ a_pt1[6] = (double) (-world_pti[0] * i_vertex[i].y);// a->m[i*16+14]=-world[i][0]*vertex[i][1];\r
+ a_pt1[7] = (double) (-world_pti[1] * i_vertex[i].y);// a->m[i*16+15]=-world[i][1]*vertex[i][1];\r
+ b_array[i * 2 + 0][0] = (double) i_vertex[i].x;// b->m[i*2+0] =vertex[i][0];\r
+ b_array[i * 2 + 1][0] = (double) i_vertex[i].y;// b->m[i*2+1] =vertex[i][1];\r
}\r
if (!a.matrixSelfInv()) {\r
- return false;// 逆行列を求められないので失敗\r
+ return false;\r
}\r
- NyARMat c = wk_get_cpara_c;// 次処理で結果を受け取るので、初期化不要//new NyARMat( 8, 1 );\r
- double[][] c_array = c.getArray();\r
\r
- c.matrixMul(a, b);\r
- for (int i = 0; i < 2; i++) {\r
- para[i * 3 + 0] = c_array[i * 3 + 0][0];// para[i][0] = c->m[i*3+0];\r
- para[i * 3 + 1] = c_array[i * 3 + 1][0];// para[i][1] = c->m[i*3+1];\r
- para[i * 3 + 2] = c_array[i * 3 + 2][0];// para[i][2] = c->m[i*3+2];\r
- }\r
- para[2 * 3 + 0] = c_array[2 * 3 + 0][0];// para[2][0] = c->m[2*3+0];\r
- para[2 * 3 + 1] = c_array[2 * 3 + 1][0];// para[2][1] = c->m[2*3+1];\r
- para[2 * 3 + 2] = 1.0;// para[2][2] = 1.0;\r
+ o_para.matrixMul(a, b);\r
return true;\r
- }\r
-\r
- private final double[][] wk_pickFromRaster_local = new double[4][2];\r
-\r
- private final double[] wk_pickFromRaster_para = new double[9];// [3][3];\r
-\r
- private final double[][] wk_pickFromRaster_world = {// double world[4][2];\r
- { 100.0, 100.0 }, { 100.0 + 10.0, 100.0 }, { 100.0 + 10.0, 100.0 + 10.0 },{ 100.0, 100.0 + 10.0 } };\r
-\r
-\r
- private final int[] wk_pickFromRaster_rgb_tmp = new int[3];\r
-\r
+ } \r
+ private final int[] __pickFromRaster_rgb_tmp = new int[3];\r
+ private final NyARMat __pickFromRaster_cpara_c = new NyARMat(8, 1);\r
+ \r
/**\r
* imageから、i_markerの位置にあるパターンを切り出して、保持します。 Optimize:STEP[769->]\r
* \r
*/\r
public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
{\r
- int lx1, lx2, ly1, ly2;\r
-\r
- int img_x = image.getWidth();\r
- int img_y = image.getHeight();\r
-\r
- double xdiv2_reciprocal; // [tp]\r
- double ydiv2_reciprocal; // [tp]\r
-\r
- // int[] x_coord=i_marker.x_coord;\r
- // int[] y_coord=i_marker.y_coord;\r
- // int[] vertex=i_marker.mkvertex;\r
- double[][] local = wk_pickFromRaster_local;// double local[4][2];\r
- //\r
- for (int i = 0; i < 4; i++) {\r
- local[i][0] = i_square.imvertex[i].x;\r
- local[i][1] = i_square.imvertex[i].y;\r
- }\r
+ final NyARIntPoint2d[] local = i_square.imvertex;\r
\r
- double[][] world = wk_pickFromRaster_world;\r
- /*\r
- * world[0][0] = 100.0; world[0][1] = 100.0; world[1][0] = 100.0 + 10.0;\r
- * world[1][1] = 100.0; world[2][0] = 100.0 + 10.0; world[2][1] = 100.0 +\r
- * 10.0; world[3][0] = 100.0; world[3][1] = 100.0 + 10.0;\r
- */\r
- double[] para = wk_pickFromRaster_para; // double para[3][3];\r
// パターンの切り出しに失敗することもある。\r
- if (!get_cpara(world, local, para)) {\r
+ NyARMat cpara = this.__pickFromRaster_cpara_c;\r
+ if (!get_cpara(i_square.imvertex, cpara)) {\r
return false;\r
}\r
- lx1 = (int) ((local[0][0] - local[1][0]) * (local[0][0] - local[1][0]) + (local[0][1] - local[1][1])* (local[0][1] - local[1][1]));\r
- lx2 = (int) ((local[2][0] - local[3][0]) * (local[2][0] - local[3][0]) + (local[2][1] - local[3][1])* (local[2][1] - local[3][1]));\r
- ly1 = (int) ((local[1][0] - local[2][0]) * (local[1][0] - local[2][0]) + (local[1][1] - local[2][1])* (local[1][1] - local[2][1]));\r
- ly2 = (int) ((local[3][0] - local[0][0]) * (local[3][0] - local[0][0]) + (local[3][1] - local[0][1])* (local[3][1] - local[0][1]));\r
+ final double[][] para=cpara.getArray();\r
+ final double para00=para[0*3+0][0];\r
+ final double para01=para[0*3+1][0];\r
+ final double para02=para[0*3+2][0];\r
+ final double para10=para[1*3+0][0];\r
+ final double para11=para[1*3+1][0];\r
+ final double para12=para[1*3+2][0];\r
+ final double para20=para[2*3+0][0];\r
+ final double para21=para[2*3+1][0];\r
+ final double para22=1.0;\r
+ \r
+ int lx1 = (int) ((local[0].x - local[1].x) * (local[0].x - local[1].x) + (local[0].y - local[1].y)* (local[0].y - local[1].y));\r
+ int lx2 = (int) ((local[2].x - local[3].x) * (local[2].x - local[3].x) + (local[2].y - local[3].y)* (local[2].y - local[3].y));\r
+ int ly1 = (int) ((local[1].x - local[2].x) * (local[1].x - local[2].x) + (local[1].y - local[2].y)* (local[1].y - local[2].y));\r
+ int ly2 = (int) ((local[3].x - local[0].x) * (local[3].x - local[0].x) + (local[3].y - local[0].y)* (local[3].y - local[0].y));\r
if (lx2 > lx1) {\r
lx1 = lx2;\r
}\r
if (ly2 > ly1) {\r
ly1 = ly2;\r
}\r
+ \r
int sample_pixel_x = this._size.w;\r
int sample_pixel_y = this._size.h;\r
-\r
while (sample_pixel_x * sample_pixel_x < lx1 / 4) {\r
sample_pixel_x *= 2;\r
}\r
final int ydiv = sample_pixel_y / this._size.h;// ydiv = ydiv2/Config.AR_PATT_SIZE_Y;\r
\r
\r
- xdiv2_reciprocal = 1.0 / sample_pixel_x;\r
- ydiv2_reciprocal = 1.0 / sample_pixel_y;\r
+ int img_x = image.getWidth();\r
+ int img_y = image.getHeight();\r
+\r
+ final double xdiv2_reciprocal = 1.0 / sample_pixel_x;\r
+ final double ydiv2_reciprocal = 1.0 / sample_pixel_y;\r
int r,g,b;\r
- int[] rgb_tmp = wk_pickFromRaster_rgb_tmp;\r
+ int[] rgb_tmp = __pickFromRaster_rgb_tmp;\r
\r
//ピクセルリーダーを取得\r
INyARRgbPixelReader reader=image.getRgbPixelReader();\r
final double yw = 102.5 + 5.0 * (iy*ydiv+j + 0.5) * ydiv2_reciprocal; \r
for(int i=0;i<xdiv;i++){\r
final double xw = 102.5 + 5.0 * (ix*xdiv+i + 0.5) * xdiv2_reciprocal;\r
- final double d = para[2 * 3 + 0] * xw + para[2 * 3 + 1] * yw+ para[2 * 3 + 2];\r
+ final double d = para20 * xw + para21 * yw+ para22;\r
if (d == 0) {\r
throw new NyARException();\r
}\r
- final int xc = (int) ((para[0 * 3 + 0] * xw + para[0 * 3 + 1] * yw + para[0 * 3 + 2]) / d);\r
- final int yc = (int) ((para[1 * 3 + 0] * xw + para[1 * 3 + 1] * yw + para[1 * 3 + 2]) / d);\r
+ final int xc = (int) ((para00 * xw + para01 * yw + para02) / d);\r
+ final int yc = (int) ((para10 * xw + para11 * yw + para12) / d);\r
\r
if (xc >= 0 && xc < img_x && yc >= 0 && yc < img_y) {\r
reader.getPixel(xc, yc, rgb_tmp);\r
private int[] _patdata;\r
private NyARBufferReader _buf_reader;\r
private NyARIntSize _size;\r
+ private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+ private double _edge_percent;\r
\r
public NyARColorPatt_O3(int i_width, int i_height)\r
{\r
this._size=new NyARIntSize(i_width,i_height);\r
this._patdata = new int[i_height*i_width];\r
this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+ this._edge_percent=50.0/100;\r
}\r
public int getWidth()\r
{\r
{\r
return this._buf_reader;\r
}\r
-\r
+ public INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._pixelreader;\r
+ }\r
private final NyARMat wk_get_cpara_a = new NyARMat(8, 8);\r
-\r
private final NyARMat wk_get_cpara_b = new NyARMat(8, 1);\r
+ private final NyARMat wk_pickFromRaster_cpara = new NyARMat(8, 1);\r
\r
/**\r
* @param world\r
* @param o_para\r
* @throws NyARException\r
*/\r
- private boolean get_cpara(final NyARIntPoint[] i_vertex, NyARMat o_para)throws NyARException\r
+ private boolean get_cpara(final NyARIntPoint2d[] i_vertex, NyARMat o_para)throws NyARException\r
{\r
int[][] world = this.wk_pickFromRaster_world;\r
NyARMat a = wk_get_cpara_a;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );\r
{ 100, 100 }, { 100 + 10, 100 }, { 100 + 10, 100 + 10 }, { 100, 100 + 10 } };\r
\r
\r
- private final NyARMat wk_pickFromRaster_cpara = new NyARMat(8, 1);\r
\r
/**\r
* imageから、i_markerの位置にあるパターンを切り出して、保持します。 Optimize:STEP[769->750]\r
public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
{\r
NyARMat cpara = this.wk_pickFromRaster_cpara;\r
- NyARIntPoint[] local = i_square.imvertex;\r
+ NyARIntPoint2d[] local = i_square.imvertex;\r
// xdiv2,ydiv2の計算\r
int xdiv2, ydiv2;\r
int l1, l2;\r
int[] rgb_set = this.__updateExtpat_rgbset;\r
\r
\r
- \r
for(int iy=this._size.h-1;iy>=0;iy--){\r
for(int ix=pat_size_w-1;ix>=0;ix--){\r
//xw,ywマップを作成\r
reciprocal= 1.0 / i_xdiv2;\r
for(i=xdiv-1;i>=0;i--){\r
- xw[i]=102.5 + 5.0 * (ix*xdiv+i + 0.5) * reciprocal;\r
+ xw[i]=100 + 10.0 * (ix*xdiv+i + 0.5) * reciprocal;\r
}\r
reciprocal= 1.0 / i_ydiv2;\r
for(i=ydiv-1;i>=0;i--){\r
- yw[i]=102.5 + 5.0 * (iy*ydiv+i + 0.5) * reciprocal;\r
+ yw[i]=100 + 10.0 * (iy*ydiv+i + 0.5) * reciprocal;\r
}\r
- //xc,ycマップを作成\r
+ //1ピクセルを構成するピクセル座標の集合をxc,yc配列に取得\r
int number_of_pix=0;\r
for(i=ydiv-1;i>=0;i--)\r
{\r
number_of_pix++;\r
}\r
}\r
- //ã\83\94ã\82¯ã\82»ã\83«å\8f\96å¾\97ã\81¨ã\83\94ã\82¯ã\82»ã\83«å\80¤ã\81®è¨\88ç®\97\r
+ //1ã\83\94ã\82¯ã\82»ã\83«å\88\86ã\81®é\85\8då\88\97ã\82\92å\8f\96å¾\97\r
reader.getPixelSet(xc,yc,number_of_pix, rgb_set);\r
r=g=b=0;\r
for(i=number_of_pix*3-1;i>=0;i-=3){\r
--- /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.pickup;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.utils.NyARPerspectiveParamGenerator_O1;\r
+\r
+\r
+/**\r
+ * 遠近法を使ったパースペクティブ補正をかけて、ラスタ上の四角形から\r
+ * 任意解像度の矩形パターンを作成します。\r
+ *\r
+ */\r
+public class NyARColorPatt_Perspective implements INyARColorPatt\r
+{\r
+ private int[] _patdata;\r
+ private NyARBufferReader _buf_reader;\r
+ private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+ private NyARIntSize _size;\r
+ NyARPerspectiveParamGenerator_O1 _perspective_gen;\r
+ private static final int LOCAL_LT=1;\r
+ private NyARIntPoint2d _pickup_lt=new NyARIntPoint2d(); \r
+ /**\r
+ * 例えば、64\r
+ * @param i_width\r
+ * 取得画像の解像度幅\r
+ * @param i_height\r
+ * 取得画像の解像度高さ\r
+ */\r
+ public NyARColorPatt_Perspective(int i_width, int i_height)\r
+ {\r
+ //入力制限\r
+ assert i_width>2 && i_height>2;\r
+ \r
+ this._size=new NyARIntSize(i_width,i_height);\r
+ this._patdata = new int[i_height*i_width];\r
+ this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+ setEdgeSize(0,0);\r
+ return;\r
+ }\r
+ /**\r
+ * 例えば、64\r
+ * @param i_width\r
+ * 取得画像の解像度幅\r
+ * @param i_height\r
+ * 取得画像の解像度高さ\r
+ * @param i_edge_percentage\r
+ * エッジ幅の割合(ARToolKit標準と同じなら、25)\r
+ */\r
+ public NyARColorPatt_Perspective(int i_width, int i_height,int i_edge_percentage)\r
+ {\r
+ //入力制限\r
+ assert i_width>2 && i_height>2;\r
+ \r
+ this._size=new NyARIntSize(i_width,i_height);\r
+ this._patdata = new int[i_height*i_width];\r
+ this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+ setEdgeSizeByPercent(i_edge_percentage,i_edge_percentage);\r
+ return;\r
+ } \r
+ /**\r
+ * 矩形領域のエッジサイズを指定します。\r
+ * エッジの計算方法は以下の通りです。\r
+ * 1.マーカ全体を(i_x_edge*2+width)x(i_y_edge*2+height)の解像度でパラメタを計算します。\r
+ * 2.ピクセルの取得開始位置を(i_x_edge/2,i_y_edge/2)へ移動します。\r
+ * 3.開始位置から、width x height個のピクセルを取得します。\r
+ * \r
+ * ARToolKit標準マーカの場合は、width/2,height/2を指定してください。\r
+ * @param i_x_edge\r
+ * @param i_y_edge\r
+ */\r
+ public void setEdgeSize(int i_x_edge,int i_y_edge)\r
+ {\r
+ assert(i_x_edge>=0);\r
+ assert(i_y_edge>=0);\r
+ //Perspectiveパラメタ計算器を作成\r
+ this._perspective_gen=new NyARPerspectiveParamGenerator_O1(LOCAL_LT,LOCAL_LT,i_x_edge*2+this._size.w,i_y_edge*2+this._size.h);\r
+ //ピックアップ開始位置を計算\r
+ this._pickup_lt.x=i_x_edge+LOCAL_LT;\r
+ this._pickup_lt.y=i_y_edge+LOCAL_LT;\r
+ return;\r
+ }\r
+ public void setEdgeSizeByPercent(int i_x_percent,int i_y_percent)\r
+ {\r
+ assert(i_x_percent>=0);\r
+ assert(i_y_percent>=0);\r
+ setEdgeSize(this._size.w*i_x_percent/50,this._size.h*i_y_percent/50);\r
+ return;\r
+ }\r
+\r
+ \r
+ public final int getWidth()\r
+ {\r
+ return this._size.w;\r
+ }\r
+ public final int getHeight()\r
+ {\r
+ return this._size.h;\r
+ }\r
+ public final NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ }\r
+ public final INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buf_reader;\r
+ }\r
+ public final INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._pixelreader;\r
+ }\r
+ private final int[] __pickFromRaster_rgb_tmp = new int[3];\r
+ /**\r
+ * \r
+ * @param image\r
+ * @param i_marker\r
+ * @return 切り出しに失敗した\r
+ * @throws Exception\r
+ */\r
+ public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
+ {\r
+ //遠近法のパラメータを計算\r
+ double[] cpara = new double[8];\r
+ if (!this._perspective_gen.getParam(i_square.imvertex, cpara)) {\r
+ return false;\r
+ }\r
+ \r
+ int img_x = image.getWidth();\r
+ int img_y = image.getHeight();\r
+\r
+ int[] rgb_tmp = __pickFromRaster_rgb_tmp;\r
+\r
+ //ピクセルリーダーを取得\r
+ INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+\r
+ for(int iy=0;iy<this._size.h;iy++){\r
+ for(int ix=0;ix<this._size.w;ix++){\r
+ //1ピクセルを作成\r
+ int cx=this._pickup_lt.x+ix;\r
+ int cy=this._pickup_lt.y+iy;\r
+ final double d=cpara[6]*cx+cpara[7]*cy+1.0;\r
+ final int x=(int)((cpara[0]*cx+cpara[1]*cy+cpara[2])/d);\r
+ final int y=(int)((cpara[3]*cx+cpara[4]*cy+cpara[5])/d);\r
+ if (x >= 0 && x < img_x && y >= 0 && y < img_y) {\r
+ reader.getPixel(x, y, rgb_tmp);\r
+ this._patdata[iy*this._size.w+ix]=(((rgb_tmp[0])&0xff)<<16)|(((rgb_tmp[1])&0xff)<<8)|(((rgb_tmp[2])&0xff));\r
+ }\r
+ }\r
+ //ピクセル問い合わせ\r
+ //ピクセルセット\r
+ }\r
+ return true;\r
+ } \r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\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.pickup;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.utils.NyARDoubleMatrixProcessor;\r
+\r
+\r
+/**\r
+ * 疑似アフィン変換を使用して、ラスタ上の四角形から任意解像度\r
+ * の矩形パターンを作成します。\r
+ *\r
+ */\r
+public class NyARColorPatt_PseudoAffine implements INyARColorPatt\r
+{\r
+ private int[] _patdata;\r
+ private NyARBufferReader _buf_reader;\r
+ private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+ private NyARIntSize _size;\r
+ \r
+ public final int getWidth()\r
+ {\r
+ return this._size.w;\r
+ }\r
+ \r
+ public final int getHeight()\r
+ {\r
+ return this._size.h;\r
+ }\r
+ \r
+ public final NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ }\r
+ \r
+ public final INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buf_reader;\r
+ }\r
+ \r
+ public final INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._pixelreader;\r
+ }\r
+ NyARDoubleMatrix44 _invmat=new NyARDoubleMatrix44();\r
+ /**\r
+ * @param i_width\r
+ * @param i_height\r
+ */\r
+ public NyARColorPatt_PseudoAffine(int i_width, int i_height)\r
+ { \r
+ this._size=new NyARIntSize(i_width,i_height);\r
+ this._patdata = new int[i_height*i_width];\r
+ this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+ //疑似アフィン変換のパラメタマトリクスを計算します。\r
+ //長方形から計算すると、有効要素がm00,m01,m02,m03,m10,m11,m20,m23,m30になります。\r
+ final NyARDoubleMatrix44 mat=this._invmat;\r
+ mat.m00=0;\r
+ mat.m01=0;\r
+ mat.m02=0;\r
+ mat.m03=1.0;\r
+ mat.m10=0;\r
+ mat.m11=i_width-1;\r
+ mat.m12=0;\r
+ mat.m13=1.0;\r
+ mat.m20=(i_width-1)*(i_height-1);\r
+ mat.m21=i_width-1;\r
+ mat.m22=i_height-1;\r
+ mat.m23=1.0;\r
+ mat.m30=0;\r
+ mat.m31=0;\r
+ mat.m32=i_height-1;\r
+ mat.m33=1.0;\r
+ NyARDoubleMatrixProcessor.inverse(mat,mat);\r
+ return;\r
+ } \r
+\r
+ /**\r
+ * 変換行列と頂点座標から、パラメータを計算\r
+ * o_paramの[0..3]にはXのパラメタ、[4..7]にはYのパラメタを格納する。\r
+ * @param i_vertex\r
+ * @param pa\r
+ * @param pb\r
+ */\r
+ private void calcPara(NyARIntPoint2d[] i_vertex,double[] o_cparam)\r
+ {\r
+ final NyARDoubleMatrix44 invmat=this._invmat;\r
+ double v1,v2,v4;\r
+ //変換行列とベクトルの積から、変換パラメタを計算する。\r
+ v1=i_vertex[0].x;\r
+ v2=i_vertex[1].x;\r
+ v4=i_vertex[3].x;\r
+ \r
+ o_cparam[0]=invmat.m00*v1+invmat.m01*v2+invmat.m02*i_vertex[2].x+invmat.m03*v4;\r
+ o_cparam[1]=invmat.m10*v1+invmat.m11*v2;//m12,m13は0;\r
+ o_cparam[2]=invmat.m20*v1+invmat.m23*v4;//m21,m22は0;\r
+ o_cparam[3]=v1;//m30は1.0で、m31,m32,m33は0\r
+ \r
+ v1=i_vertex[0].y;\r
+ v2=i_vertex[1].y;\r
+ v4=i_vertex[3].y;\r
+\r
+ o_cparam[4]=invmat.m00*v1+invmat.m01*v2+invmat.m02*i_vertex[2].y+invmat.m03*v4;\r
+ o_cparam[5]=invmat.m10*v1+invmat.m11*v2;//m12,m13は0;\r
+ o_cparam[6]=invmat.m20*v1+invmat.m23*v4;//m21,m22は0;\r
+ o_cparam[7]=v1;//m30は1.0で、m31,m32,m33は0\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * 疑似アフィン変換の変換パラメタ\r
+ */\r
+ private double[] _convparam=new double[8];\r
+ \r
+ public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
+ {\r
+ final double[] conv_param=this._convparam;\r
+ int rx2,ry2;\r
+ rx2=this._size.w;\r
+ ry2=this._size.h;\r
+ int[] rgb_tmp=new int[3];\r
+\r
+ INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+ // 変形先領域の頂点を取得\r
+\r
+ //変換行列から現在の座標系への変換パラメタを作成\r
+ calcPara(i_square.imvertex,conv_param);// 変換パラメータを求める\r
+ for(int y=0;y<ry2;y++){\r
+ for(int x=0;x<rx2;x++){\r
+ final int ttx=(int)((conv_param[0]*x*y+conv_param[1]*x+conv_param[2]*y+conv_param[3])+0.5);\r
+ final int tty=(int)((conv_param[4]*x*y+conv_param[5]*x+conv_param[6]*y+conv_param[7])+0.5);\r
+ reader.getPixel((int)ttx,(int)tty,rgb_tmp);\r
+ this._patdata[x+y*rx2]=(rgb_tmp[0]<<16)|(rgb_tmp[1]<<8)|rgb_tmp[2]; \r
+ }\r
+ }\r
+ return true;\r
+ }\r
+}
\ No newline at end of file
--- /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.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+public class NyARRgbPixelReader_INT1D_GLAY_8 implements INyARRgbPixelReader\r
+{\r
+ protected int[] _ref_buf;\r
+\r
+ private NyARIntSize _size;\r
+\r
+ public NyARRgbPixelReader_INT1D_GLAY_8(int[] i_buf, NyARIntSize i_size)\r
+ {\r
+ this._ref_buf = i_buf;\r
+ this._size = i_size;\r
+ }\r
+\r
+ public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+ {\r
+ o_rgb[0] = o_rgb[1]=o_rgb[2]=this._ref_buf[i_x + i_y * this._size.w];\r
+ return;\r
+ }\r
+\r
+ public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+ {\r
+ final int width = this._size.w;\r
+ final int[] ref_buf = this._ref_buf;\r
+ for (int i = i_num - 1; i >= 0; i--){\r
+ o_rgb[i * 3 + 0] = o_rgb[i * 3 + 1]=o_rgb[i * 3 + 2]=ref_buf[i_x[i] + i_y[i] * width];\r
+ }\r
+ return;\r
+ }\r
+}\r
--- /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.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+public class NyARRgbPixelReader_INT1D_X8R8G8B8_32 implements INyARRgbPixelReader\r
+{\r
+ protected int[] _ref_buf;\r
+\r
+ private NyARIntSize _size;\r
+\r
+ public NyARRgbPixelReader_INT1D_X8R8G8B8_32(int[] i_buf, NyARIntSize i_size)\r
+ {\r
+ this._ref_buf = i_buf;\r
+ this._size = i_size;\r
+ }\r
+\r
+ public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+ {\r
+ final int rgb= this._ref_buf[i_x + i_y * this._size.w];\r
+ o_rgb[0] = (rgb>>16)&0xff;// R\r
+ o_rgb[1] = (rgb>>8)&0xff;// G\r
+ o_rgb[2] = rgb&0xff;// B\r
+ return;\r
+ }\r
+\r
+ public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+ {\r
+ final int width = this._size.w;\r
+ final int[] ref_buf = this._ref_buf;\r
+ for (int i = i_num - 1; i >= 0; i--){\r
+ int rgb=ref_buf[i_x[i] + i_y[i] * width];\r
+ o_rgb[i * 3 + 0] = (rgb>>16)&0xff;// R\r
+ o_rgb[i * 3 + 1] = (rgb>>8)&0xff;// G\r
+ o_rgb[i * 3 + 2] = rgb&0xff;// B\r
+ }\r
+ return;\r
+ }\r
+}\r
o_result.m22 = i_rot.m22;\r
o_result.m23 = i_rot.m20 * i_off.x + i_rot.m21 * i_off.y + i_rot.m22 * i_off.z + i_trans.z;\r
\r
- o_result.angle.copyFrom(i_rot.refAngle());\r
+ o_result.angle.setValue(i_rot.refAngle());\r
o_result.has_value = true;\r
return;\r
} \r
double err, minerr = 0;\r
int i,i2;\r
int best_idx=0;\r
- angle.copyFrom(io_rot.refAngle());// arGetAngle( rot, &a, &b, &c );\r
+ angle.setValue(io_rot.refAngle());// arGetAngle( rot, &a, &b, &c );\r
factor = 10.0 * Math.PI / 180.0;\r
for (int j = 0; j < 10; j++){\r
minerr = 1000000000.0;\r
*/\r
package jp.nyatla.nyartoolkit.core.types;\r
\r
+\r
public class NyARDoublePoint2d\r
{\r
public double x;\r
}\r
return ret;\r
}\r
+ public static NyARDoublePoint2d[][] create2dArray(int i_length_x,int i_length_y)\r
+ {\r
+ NyARDoublePoint2d[][] ret=new NyARDoublePoint2d[i_length_y][i_length_x];\r
+ for(int i=0;i<i_length_y;i++)\r
+ {\r
+ for(int i2=0;i2<i_length_x;i2++)\r
+ {\r
+ ret[i][i2]=new NyARDoublePoint2d();\r
+ }\r
+ }\r
+ return ret;\r
+ }\r
public NyARDoublePoint2d()\r
{\r
this.x=0;\r
this.y=0;\r
+ return;\r
} \r
public NyARDoublePoint2d(double i_x,double i_y)\r
{\r
this.x=i_x;\r
this.y=i_y;\r
+ return;\r
+ }\r
+ public NyARDoublePoint2d(NyARDoublePoint2d i_src)\r
+ {\r
+ this.x=i_src.x;\r
+ this.y=i_src.y;\r
+ return;\r
+ }\r
+ public NyARDoublePoint2d(NyARIntPoint2d i_src)\r
+ {\r
+ this.x=(double)i_src.x;\r
+ this.y=(double)i_src.y;\r
+ return;\r
+ }\r
+ public void setValue(NyARDoublePoint2d i_src)\r
+ {\r
+ this.x=i_src.x;\r
+ this.y=i_src.y;\r
+ return;\r
+ }\r
+ public void setValue(NyARIntPoint2d i_src)\r
+ {\r
+ this.x=(double)i_src.x;\r
+ this.y=(double)i_src.y;\r
+ return;\r
+ }\r
+ /**\r
+ * 格納値をベクトルとして、距離を返します。\r
+ * @return\r
+ */\r
+ public double dist()\r
+ {\r
+ return Math.sqrt(this.x*this.x+this.y+this.y);\r
}\r
}\r
}\r
return ret;\r
}\r
- public void copyFrom(final NyARDoublePoint3d i_in)\r
+ public void setValue(final NyARDoublePoint3d i_in)\r
{\r
this.x=i_in.x;\r
this.y=i_in.y;\r
* \r
*/\r
package jp.nyatla.nyartoolkit.core.types;\r
-\r
-public class NyARIntPoint\r
+/**\r
+ * @deprecated このクラスは名称変更のため、削除されます。\r
+ * @see NyARIntPoint2d\r
+ */\r
+public class NyARIntPoint extends NyARIntPoint2d\r
{\r
- public int x;\r
-\r
- public int y;\r
/**\r
* 配列ファクトリ\r
* @param i_number\r
}\r
return ret;\r
}\r
- public static void copyArray(final NyARIntPoint[] i_from,NyARIntPoint[] i_to)\r
- {\r
- for(int i=i_from.length-1;i>=0;i--)\r
- {\r
- i_to[i].x=i_from[i].x;\r
- i_to[i].y=i_from[i].y;\r
- }\r
- return;\r
- }\r
}\r
--- /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.types;\r
+\r
+public class NyARIntPoint2d\r
+{\r
+ public int x;\r
+\r
+ public int y;\r
+ /**\r
+ * 配列ファクトリ\r
+ * @param i_number\r
+ * @return\r
+ */\r
+ public static NyARIntPoint2d[] createArray(int i_number)\r
+ {\r
+ NyARIntPoint2d[] ret=new NyARIntPoint2d[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARIntPoint2d();\r
+ }\r
+ return ret;\r
+ }\r
+ public static void copyArray(final NyARIntPoint2d[] i_from,NyARIntPoint2d[] i_to)\r
+ {\r
+ for(int i=i_from.length-1;i>=0;i--)\r
+ {\r
+ i_to[i].x=i_from[i].x;\r
+ i_to[i].y=i_from[i].y;\r
+ }\r
+ return;\r
+ }\r
+}\r
*/\r
package jp.nyatla.nyartoolkit.core.types.matrix;\r
\r
+import jp.nyatla.nyartoolkit.*;\r
\r
public class NyARDoubleMatrix33 implements INyARDoubleMatrix\r
{\r
o_value[10]=this.m22;\r
o_value[11]=this.m23;\r
return;\r
- } \r
+ }\r
}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+\r
+public class NyARDoubleMatrix44 implements INyARDoubleMatrix\r
+{\r
+ public double m00;\r
+ public double m01;\r
+ public double m02;\r
+ public double m03;\r
+ public double m10;\r
+ public double m11;\r
+ public double m12;\r
+ public double m13;\r
+ public double m20;\r
+ public double m21;\r
+ public double m22;\r
+ public double m23;\r
+ public double m30;\r
+ public double m31;\r
+ public double m32;\r
+ public double m33;\r
+ public static NyARDoubleMatrix44[] createArray(int i_number)\r
+ {\r
+ NyARDoubleMatrix44[] ret=new NyARDoubleMatrix44[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARDoubleMatrix44();\r
+ }\r
+ return ret;\r
+ }\r
+ /**\r
+ * 遅いからあんまり使わないでね。\r
+ */\r
+ public void setValue(double[] i_value)\r
+ {\r
+ this.m00=i_value[ 0];\r
+ this.m01=i_value[ 1];\r
+ this.m02=i_value[ 2];\r
+ this.m03=i_value[ 3];\r
+ this.m10=i_value[ 4];\r
+ this.m11=i_value[ 5];\r
+ this.m12=i_value[ 6];\r
+ this.m13=i_value[ 7];\r
+ this.m20=i_value[ 8];\r
+ this.m21=i_value[ 9];\r
+ this.m22=i_value[10];\r
+ this.m23=i_value[11];\r
+ this.m30=i_value[12];\r
+ this.m31=i_value[13];\r
+ this.m32=i_value[14];\r
+ this.m33=i_value[15];\r
+ return;\r
+ }\r
+ /**\r
+ * 遅いからあんまり使わないでね。\r
+ */\r
+ public void getValue(double[] o_value)\r
+ {\r
+ o_value[ 0]=this.m00;\r
+ o_value[ 1]=this.m01;\r
+ o_value[ 2]=this.m02;\r
+ o_value[ 3]=this.m03;\r
+ o_value[ 4]=this.m10;\r
+ o_value[ 5]=this.m11;\r
+ o_value[ 6]=this.m12;\r
+ o_value[ 7]=this.m13;\r
+ o_value[ 8]=this.m20;\r
+ o_value[ 9]=this.m21;\r
+ o_value[10]=this.m22;\r
+ o_value[11]=this.m23;\r
+ o_value[12]=this.m30;\r
+ o_value[13]=this.m31;\r
+ o_value[14]=this.m32;\r
+ o_value[15]=this.m33;\r
+ return;\r
+ }\r
+}\r
{\r
public NyARIntPointStack(int i_length)\r
{\r
- super(new NyARIntPoint[i_length]);\r
+ super(new NyARIntPoint2d[i_length]);\r
\r
}\r
\r
protected void onReservRequest(int i_start, int i_end, Object[] i_buffer)\r
{\r
for (int i = i_start; i < i_end; i++) {\r
- i_buffer[i] = new NyARIntPoint();\r
+ i_buffer[i] = new NyARIntPoint2d();\r
}\r
}\r
\r
--- /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-2009 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.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix33;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix44;\r
+\r
+public class NyARDoubleMatrixProcessor\r
+{\r
+ /**\r
+ * i_srcの逆行列を計算して、thisへ格納します。\r
+ * @param i_src\r
+ * @return\r
+ */\r
+ public static boolean inverse(NyARDoubleMatrix22 i_src,NyARDoubleMatrix22 o_dest)\r
+ {\r
+ final double a11,a12,a21,a22;\r
+ a11=i_src.m00;\r
+ a12=i_src.m01;\r
+ a21=i_src.m10;\r
+ a22=i_src.m11;\r
+ double det=a11*a22-a12*a21;\r
+ if(det==0){\r
+ return false;\r
+ }\r
+ det=1/det;\r
+ o_dest.m00=a22*det;\r
+ o_dest.m01=-a12*det;\r
+ o_dest.m10=a21*det;\r
+ o_dest.m11=-a11*det;\r
+ return true;\r
+ } \r
+ public static boolean inverse(NyARDoubleMatrix33 i_src,NyARDoubleMatrix33 o_dest) throws NyARException\r
+ {\r
+ /*i_srcの逆行列をthisへ格納するコードを書くこと。*/\r
+ NyARException.notImplement();\r
+ return false;\r
+ }\r
+ /**\r
+ * i_srcの逆行列を計算して、結果をo_destへセットします。\r
+ * @param i_src\r
+ * @return\r
+ */\r
+ public static boolean inverse(NyARDoubleMatrix44 i_src,NyARDoubleMatrix44 o_dest)\r
+ {\r
+ final double a11,a12,a13,a14,a21,a22,a23,a24,a31,a32,a33,a34,a41,a42,a43,a44;\r
+ final double b11,b12,b13,b14,b21,b22,b23,b24,b31,b32,b33,b34,b41,b42,b43,b44; \r
+ double t1,t2,t3,t4,t5,t6;\r
+ a11=i_src.m00;a12=i_src.m01;a13=i_src.m02;a14=i_src.m03;\r
+ a21=i_src.m10;a22=i_src.m11;a23=i_src.m12;a24=i_src.m13;\r
+ a31=i_src.m20;a32=i_src.m21;a33=i_src.m22;a34=i_src.m23;\r
+ a41=i_src.m30;a42=i_src.m31;a43=i_src.m32;a44=i_src.m33;\r
+ \r
+ t1=a33*a44-a34*a43;\r
+ t2=a34*a42-a32*a44;\r
+ t3=a32*a43-a33*a42;\r
+ t4=a34*a41-a31*a44;\r
+ t5=a31*a43-a33*a41;\r
+ t6=a31*a42-a32*a41;\r
+ \r
+ b11=a22*t1+a23*t2+a24*t3;\r
+ b21=-(a23*t4+a24*t5+a21*t1);\r
+ b31=a24*t6-a21*t2+a22*t4;\r
+ b41=-(a21*t3-a22*t5+a23*t6);\r
+ \r
+ t1=a43*a14-a44*a13;\r
+ t2=a44*a12-a42*a14;\r
+ t3=a42*a13-a43*a12;\r
+ t4=a44*a11-a41*a14;\r
+ t5=a41*a13-a43*a11;\r
+ t6=a41*a12-a42*a11;\r
+\r
+ b12=-(a32*t1+a33*t2+a34*t3);\r
+ b22=a33*t4+a34*t5+a31*t1;\r
+ b32=-(a34*t6-a31*t2+a32*t4);\r
+ b42=a31*t3-a32*t5+a33*t6;\r
+ \r
+ t1=a13*a24-a14*a23;\r
+ t2=a14*a22-a12*a24;\r
+ t3=a12*a23-a13*a22;\r
+ t4=a14*a21-a11*a24;\r
+ t5=a11*a23-a13*a21;\r
+ t6=a11*a22-a12*a21;\r
+\r
+ b13=a42*t1+a43*t2+a44*t3;\r
+ b23=-(a43*t4+a44*t5+a41*t1);\r
+ b33=a44*t6-a41*t2+a42*t4;\r
+ b43=-(a41*t3-a42*t5+a43*t6);\r
+\r
+ t1=a23*a34-a24*a33;\r
+ t2=a24*a32-a22*a34;\r
+ t3=a22*a33-a23*a32;\r
+ t4=a24*a31-a21*a34; \r
+ t5=a21*a33-a23*a31;\r
+ t6=a21*a32-a22*a31;\r
+\r
+ b14=-(a12*t1+a13*t2+a14*t3);\r
+ b24=a13*t4+a14*t5+a11*t1;\r
+ b34=-(a14*t6-a11*t2+a12*t4);\r
+ b44=a11*t3-a12*t5+a13*t6;\r
+ \r
+ double det_1=(a11*b11+a21*b12+a31*b13+a41*b14);\r
+ if(det_1==0){\r
+ return false;\r
+ }\r
+ det_1=1/det_1;\r
+\r
+ o_dest.m00=b11*det_1;\r
+ o_dest.m01=b12*det_1;\r
+ o_dest.m02=b13*det_1;\r
+ o_dest.m03=b14*det_1;\r
+ \r
+ o_dest.m10=b21*det_1;\r
+ o_dest.m11=b22*det_1;\r
+ o_dest.m12=b23*det_1;\r
+ o_dest.m13=b24*det_1;\r
+ \r
+ o_dest.m20=b31*det_1;\r
+ o_dest.m21=b32*det_1;\r
+ o_dest.m22=b33*det_1;\r
+ o_dest.m23=b34*det_1;\r
+ \r
+ o_dest.m30=b41*det_1;\r
+ o_dest.m31=b42*det_1;\r
+ o_dest.m32=b43*det_1;\r
+ o_dest.m33=b44*det_1;\r
+ \r
+ return true;\r
+ }\r
+}\r
--- /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-2009 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.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+\r
+/**\r
+ * 遠近法を用いたPerspectiveパラメータを計算するクラスです。\r
+ *\r
+ */\r
+public class NyARPerspectiveParamGenerator\r
+{\r
+ protected int _local_x;\r
+ protected int _local_y;\r
+ protected int _width;\r
+ protected int _height;\r
+ public NyARPerspectiveParamGenerator(int i_local_x,int i_local_y,int i_width, int i_height)\r
+ {\r
+ this._height=i_height;\r
+ this._width=i_width;\r
+ this._local_x=i_local_x;\r
+ this._local_y=i_local_y;\r
+ return;\r
+ }\r
+ public boolean getParam(final NyARIntPoint2d[] i_vertex,double[] o_param)throws NyARException\r
+ {\r
+ double[][] la1,la2;\r
+ double[] ra1,ra2;\r
+ double ltx=this._local_x;\r
+ double lty=this._local_y;\r
+ double rbx=ltx+this._width;\r
+ double rby=lty+this._height;\r
+ la1=new double[4][5];\r
+ la2=new double[4][5];\r
+ ra1=new double[4];\r
+ ra2=new double[4];\r
+ //A,B,C,(GH)の方程式\r
+ la1[0][0]=ltx; la1[0][1]=lty; la1[0][2]=1; la1[0][3]=-ltx*i_vertex[0].x; la1[0][4]=-lty*i_vertex[0].x;\r
+ la1[1][0]=rbx; la1[1][1]=lty; la1[1][2]=1; la1[1][3]=-rbx*i_vertex[1].x; la1[1][4]=-lty*i_vertex[1].x;\r
+ la1[2][0]=rbx; la1[2][1]=rby; la1[2][2]=1; la1[2][3]=-rbx*i_vertex[2].x; la1[2][4]=-rby*i_vertex[2].x;\r
+ la1[3][0]=ltx; la1[3][1]=rby; la1[3][2]=1; la1[3][3]=-ltx*i_vertex[3].x; la1[3][4]=-rby*i_vertex[3].x;\r
+ ra1[0]=i_vertex[0].x;ra1[1]=i_vertex[1].x;ra1[2]=i_vertex[2].x;ra1[3]=i_vertex[3].x;\r
+ NyARSystemOfLinearEquationsProcessor.doGaussianElimination(la1,ra1,5,4);\r
+\r
+ //D,E,F,(GH)の方程式\r
+ la2[0][0]=ltx; la2[0][1]=lty; la2[0][2]=1; la2[0][3]=-ltx*i_vertex[0].y; la2[0][4]=-lty*i_vertex[0].y;\r
+ la2[1][0]=rbx; la2[1][1]=lty; la2[1][2]=1; la2[1][3]=-rbx*i_vertex[1].y; la2[1][4]=-lty*i_vertex[1].y;\r
+ la2[2][0]=rbx; la2[2][1]=rby; la2[2][2]=1; la2[2][3]=-rbx*i_vertex[2].y; la2[2][4]=-rby*i_vertex[2].y;\r
+ la2[3][0]=ltx; la2[3][1]=rby; la2[3][2]=1; la2[3][3]=-ltx*i_vertex[3].y; la2[3][4]=-rby*i_vertex[3].y;\r
+ ra2[0]=i_vertex[0].y;ra2[1]=i_vertex[1].y;ra2[2]=i_vertex[2].y;ra2[3]=i_vertex[3].y;\r
+ NyARSystemOfLinearEquationsProcessor.doGaussianElimination(la2,ra2,5,4);\r
+ //GHを計算\r
+ double A,B,C,D,E,F,G,H;\r
+ H=(ra2[3]-ra1[3])/(la2[3][4]-la1[3][4]);\r
+ G=ra2[3]-la2[3][4]*H;\r
+ //残りを計算\r
+ F=ra2[2]-H*la2[2][4]-G*la2[2][3];\r
+ E=ra2[1]-H*la2[1][4]-G*la2[1][3]-F*la2[1][2];\r
+ D=ra2[0]-H*la2[0][4]-G*la2[0][3]-F*la2[0][2]-E*la2[0][1];\r
+ C=ra1[2]-H*la1[2][4]-G*la1[2][3];\r
+ B=ra1[1]-H*la1[1][4]-G*la1[1][3]-C*la1[1][2];\r
+ A=ra1[0]-H*la1[0][4]-G*la1[0][3]-C*la1[0][2]-B*la1[0][1];\r
+ o_param[0]=A;\r
+ o_param[1]=B;\r
+ o_param[2]=C;\r
+ o_param[3]=D;\r
+ o_param[4]=E;\r
+ o_param[5]=F;\r
+ o_param[6]=G;\r
+ o_param[7]=H;\r
+ return true;\r
+ }\r
+}\r
--- /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-2009 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.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+\r
+/**\r
+ * NyARPerspectiveParamGeneratorを最適化したクラスです。\r
+ */\r
+public class NyARPerspectiveParamGenerator_O1 extends NyARPerspectiveParamGenerator\r
+{\r
+ public NyARPerspectiveParamGenerator_O1(int i_local_x,int i_local_y,int i_width, int i_height)\r
+ {\r
+ super(i_local_x,i_local_y,i_width,i_height);\r
+ this._height=i_height;\r
+ this._width=i_width;\r
+ this._local_x=i_local_x;\r
+ this._local_y=i_local_y;\r
+ return;\r
+ }\r
+ final public boolean getParam(final NyARIntPoint2d[] i_vertex,double[] o_param)throws NyARException\r
+ {\r
+ double G,H;\r
+ double w1,w2,w3,w4;\r
+ final double x0=i_vertex[0].x;\r
+ final double x1=i_vertex[1].x;\r
+ final double x2=i_vertex[2].x;\r
+ final double x3=i_vertex[3].x;\r
+ final double y0=i_vertex[0].y;\r
+ final double y1=i_vertex[1].y;\r
+ final double y2=i_vertex[2].y;\r
+ final double y3=i_vertex[3].y;\r
+ final double ltx=this._local_x;\r
+ final double lty=this._local_y;\r
+ final double rbx=ltx+this._width;\r
+ final double rby=lty+this._height;\r
+\r
+ \r
+ w1=-y3+y0;\r
+ w2= y2-y1;\r
+ final double la2_33=ltx*w1+rbx*w2;//これが0になるのはまずい。\r
+ final double la2_34=(rby*(-y3+y2)+lty*(y0-y1))/la2_33;\r
+ final double ra2_3 =(-w1-w2)/la2_33;\r
+ \r
+ w1=-x3+x0;\r
+ w2=x2-x1;\r
+ final double la1_33=ltx*w1+rbx*w2;//これが0になるのはまずい。\r
+ \r
+ //GHを計算\r
+ H=(ra2_3-((-w1-w2)/la1_33))/(la2_34-((rby*(-x3+x2)+lty*(x0-x1))/la1_33));\r
+ G=ra2_3-la2_34*H;\r
+ o_param[7]=H;\r
+ o_param[6]=G;\r
+\r
+ //残りを計算\r
+ w3=rby-lty;\r
+ w4=rbx-ltx;\r
+ w1=(y2-y1-H*(-rby*y2+lty*y1)-G*(-rbx*y2+rbx*y1))/w3;\r
+ w2=(y1-y0-H*(-lty*y1+lty*y0)-G*(-rbx*y1+ltx*y0))/w4;\r
+ o_param[5]=y0*(1+H*lty+G*ltx)-w1*lty-w2*ltx;\r
+ o_param[4]=w1;\r
+ o_param[3]=w2;\r
+ \r
+ \r
+ w1=(x2-x1-H*(-rby*x2+lty*x1)-G*(-rbx*x2+rbx*x1))/w3;\r
+ w2=(x1-x0-H*(-lty*x1+lty*x0)-G*(-rbx*x1+ltx*x0))/w4;\r
+ o_param[2]=x0*(1+H*lty+G*ltx)-w1*lty-w2*ltx;\r
+ o_param[1]=w1;\r
+ o_param[0]=w2;\r
+ return true;\r
+ }\r
+}\r
--- /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-2009 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.utils;\r
+\r
+/**\r
+ * 連立方程式を解くためのプロセッサクラスです。\r
+ *\r
+ */\r
+public class NyARSystemOfLinearEquationsProcessor\r
+{\r
+ /**\r
+ * i_reftとi_rightの整合性を確認します。\r
+ * @param i_left\r
+ * @param i_right\r
+ * @return\r
+ */\r
+ private static boolean isValid2dArray(double[][] i_left,double[] i_right)\r
+ { \r
+ final int sm=i_left.length;\r
+ final int sn=i_left[0].length;\r
+ if(i_left.length!=sm){\r
+ return false;\r
+ }\r
+ if(i_right.length!=sm){\r
+ return false;\r
+ }\r
+ for(int i=1;i<sm;i++){\r
+ if(i_left[i].length!=sn){\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+ /**\r
+ * [i_left_src]=[i_right_src]の式にガウスの消去法を実行して、[x][x]の要素が1になるように基本変形します。\r
+ * i_mとi_nが等しくない時は、最終行までの[x][x]要素までを1になるように変形します。\r
+ * @param i_left\r
+ * 連立方程式の左辺値を指定します。[i_m][i_n]の配列を指定してください。\r
+ * @param i_right\r
+ * 連立方程式の右辺値を指定します。[i_m][i_n]の配列を指定してください。\r
+ * @param i_n\r
+ * 連立方程式の係数の数を指定します。\r
+ * @param i_m\r
+ * 連立方程式の数を指定します。\r
+ * @return\r
+ * 最終行まで基本変形ができてばtrueを返します。\r
+ */\r
+ public static boolean doGaussianElimination(double[][] i_left,double[] i_right,int i_n,int i_m)\r
+ {\r
+ //整合性を確認する.\r
+ assert isValid2dArray(i_left,i_right);\r
+ \r
+\r
+ //1行目以降\r
+ for(int solve_row=0;solve_row<i_m;solve_row++)\r
+ {\r
+ {//ピボット操作\r
+ int pivod=solve_row;\r
+ double pivod_value=Math.abs(i_left[pivod][pivod]);\r
+ for(int i=solve_row+1;i<i_m;i++){\r
+ final double pivod_2=Math.abs(i_left[i][pivod]);\r
+ if(pivod_value<Math.abs(pivod_2)){\r
+ pivod=i;\r
+ pivod_value=pivod_2;\r
+ }\r
+ }\r
+ if(solve_row!=pivod){\r
+ //行の入れ替え(Cの時はポインタテーブル使って!)\r
+ final double[] t=i_left[solve_row];\r
+ i_left[solve_row]=i_left[pivod];\r
+ i_left[pivod]=t;\r
+ final double t2=i_right[solve_row];\r
+ i_right[solve_row]=i_right[pivod];\r
+ i_right[pivod]=t2;\r
+ }\r
+ }\r
+ final double[] dest_l_n=i_left[solve_row];\r
+ final double dest_l_nn=i_left[solve_row][solve_row];\r
+ if(dest_l_nn==0.0){\r
+ //選択後の対角要素が0になってしまったら失敗する。\r
+ return false;\r
+ } \r
+\r
+ //消去計算(0 - solve_row-1項までの消去)\r
+ for(int i=0;i<solve_row;i++){\r
+ double s=dest_l_n[i];\r
+ for(int i2=0;i2<i_n;i2++)\r
+ {\r
+ final double p=i_left[i][i2]*s;\r
+ dest_l_n[i2]=dest_l_n[i2]-p;\r
+ }\r
+ final double p=i_right[i]*s;\r
+ i_right[solve_row]=i_right[solve_row]-p;\r
+ \r
+ }\r
+ //消去法の実行(割り算)\r
+ final double d=dest_l_n[solve_row];\r
+ for(int i2=0;i2<solve_row;i2++){\r
+ dest_l_n[i2]=0;\r
+ }\r
+ if(d!=1.0){\r
+ dest_l_n[solve_row]=1.0;\r
+ for(int i=solve_row+1;i<i_n;i++){\r
+ dest_l_n[i]/=d;\r
+ }\r
+ i_right[solve_row]/=d;\r
+ }\r
+ }\r
+ return true; \r
+ }\r
+ /**\r
+ * i_leftとi_rightの連立方程式を解いて、i_left,i_right内容を更新します。\r
+ * i_right[n]の内容が、i_left[x][n]番目の係数の解になります。\r
+ * @return\r
+ * 方程式が解ければtrueを返します。\r
+ */\r
+ public static boolean solve(double[][] i_left,double[] i_right,int i_number_of_system)\r
+ {\r
+ return doGaussianElimination(i_left,i_right,i_number_of_system,i_number_of_system);\r
+ }\r
+}\r
+/* \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.core2.types.matrix;\r
\r
public class NyARI64Matrix22\r
import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
import jp.nyatla.nyartoolkit.core.types.*;\r
-import java.util.*;\r
\r
/**\r
* 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。\r
this._marker_width = i_marker_width;\r
//パターンピックアップを作成\r
// this._patt = new NyARColorPatt_O1(i_code.getWidth(), i_code.getHeight());\r
- this._patt = new NyARColorPatt_O3(i_code.getWidth(), i_code.getHeight());\r
+// this._patt = new NyARColorPatt_O3(i_code.getWidth(), i_code.getHeight());\r
+ this._patt = new NyARColorPatt_Perspective(i_code.getWidth(), i_code.getHeight(),25);\r
//取得パターンの差分データ器を作成\r
this._deviation_data=new NyARMatchPattDeviationColorData(i_code.getWidth(),i_code.getHeight());\r
//i_code用の評価器を作成\r
* @param o_point\r
* 4要素以上の配列を指定して下さい。先頭の4要素に値がコピーされます。\r
*/\r
- public void getSquarePosition(NyARIntPoint[] o_point)\r
+ public void getSquarePosition(NyARIntPoint2d[] o_point)\r
{\r
- NyARIntPoint.copyArray(this._detected_square.imvertex,o_point);\r
+ NyARIntPoint2d.copyArray(this._detected_square.imvertex,o_point);\r
return;\r
}\r
/**\r
* 外部でデータをストックする場合は、getSquarePositionで複製して下さい。\r
* @return\r
*/\r
- public NyARIntPoint[] refSquarePosition()\r
+ public NyARIntPoint2d[] refSquarePosition()\r
{\r
return this._detected_square.imvertex;\r
}\r
--- /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-2009 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.nyidmarker;\r
+/**\r
+ * IDマーカの値を格納するクラスです。\r
+ * クラスは、未整形のマーカデータを格納しています。\r
+ *\r
+ */\r
+public class NyARIdMarkerData\r
+{\r
+ public int model;\r
+ public int ctrl_domain;\r
+ public int ctrl_mask;\r
+ public int check;\r
+ public int[] data=new int[16];\r
+}
\ No newline at end of file
--- /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-2009 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.nyidmarker;\r
+\r
+/**\r
+ * マーカを抽出した時のパラメータを格納するクラスです。\r
+ *\r
+ */\r
+public class NyARIdMarkerParam\r
+{\r
+ public int direction;\r
+ public int threshold; \r
+ \r
+}\r
--- /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-2009 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.nyidmarker;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.utils.*;\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * NyARColorPatt_NyIdMarkerがラスタからPerspective変換して読みだすためのクラス\r
+ *\r
+ */\r
+class PerspectivePixelReader\r
+{\r
+ private NyARPerspectiveParamGenerator _param_gen=new NyARPerspectiveParamGenerator_O1(1,1,100,100);\r
+ private double[] _cparam=new double[8];\r
+\r
+ public PerspectivePixelReader()\r
+ {\r
+ return;\r
+ }\r
+ private INyARRgbRaster _raster;\r
+ public void setSourceRaster(INyARRgbRaster i_raster)\r
+ {\r
+ this._raster=i_raster;\r
+ return;\r
+ }\r
+ public boolean setSourceSquare(NyARIntPoint2d[] i_vertex)throws NyARException\r
+ {\r
+ return this._param_gen.getParam(i_vertex, this._cparam);\r
+ }\r
+\r
+ /**\r
+ * 矩形からピクセルを切り出します\r
+ * @param i_lt_x\r
+ * @param i_lt_y\r
+ * @param i_step_x\r
+ * @param i_step_y\r
+ * @param i_width\r
+ * @param i_height\r
+ * @param i_out_st\r
+ * o_pixelへの格納場所の先頭インデクス\r
+ * @param o_pixel\r
+ * @throws NyARException\r
+ */\r
+ private void rectPixels(int i_lt_x,int i_lt_y,int i_step_x,int i_step_y,int i_width,int i_height,int i_out_st,int[] o_pixel)throws NyARException\r
+ {\r
+ final double[] cpara=this._cparam;\r
+ final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+ final int[] ref_x=this._ref_x;\r
+ final int[] ref_y=this._ref_y;\r
+ final int[] pixcel_temp=this._pixcel_temp;\r
+ int out_index=i_out_st;\r
+\r
+ for(int i=0;i<i_height;i++){\r
+ //1列分のピクセルのインデックス値を計算する。\r
+ int cy0=1+i*i_step_y+i_lt_y;\r
+ double cpy0_12=cpara[1]*cy0+cpara[2];\r
+ double cpy0_45=cpara[4]*cy0+cpara[5];\r
+ double cpy0_7=cpara[7]*cy0+1.0; \r
+ int pt=0;\r
+ for(int i2=0;i2<i_width;i2++)\r
+ {\r
+ int cx0=1+i2*i_step_x+i_lt_x;\r
+\r
+ double cp6_0=cpara[6]*cx0;\r
+ double cpx0_0=cpara[0]*cx0;\r
+ double cpx3_0=cpara[3]*cx0;\r
+ \r
+ final double d=cp6_0+cpy0_7;\r
+ ref_x[pt]=(int)((cpx0_0+cpy0_12)/d);\r
+ ref_y[pt]=(int)((cpx3_0+cpy0_45)/d);\r
+ pt++;\r
+ }\r
+ //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)\r
+ reader.getPixelSet(ref_x,ref_y,i_width,pixcel_temp);\r
+ //グレースケールにしながら、line→mapへの転写\r
+ for(int i2=0;i2<i_width;i2++){\r
+ int index=i2*3;\r
+ o_pixel[out_index]=(pixcel_temp[index+0]+pixcel_temp[index+1]+pixcel_temp[index+2])/3;\r
+ out_index++;\r
+ } \r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * i_freqにあるゼロクロス点の周期が、等間隔か調べます。\r
+ * 次段半周期が、前段の80%より大きく、120%未満であるものを、等間隔周期であるとみなします。\r
+ * @param i_freq\r
+ * @param i_width\r
+ */\r
+ private static boolean checkFreqWidth(int[] i_freq,int i_width)\r
+ {\r
+ int c=i_freq[1]-i_freq[0];\r
+ final int count=i_width*2-1;\r
+ for(int i=1;i<count;i++){\r
+ final int n=i_freq[i+1]-i_freq[i];\r
+ final int v=n*100/c;\r
+ if(v>150 || v<50){\r
+ return false;\r
+ }\r
+ c=n;\r
+ }\r
+ return true;\r
+ }\r
+ /**\r
+ * i_freq_count_tableとi_freq_tableの内容を調査し、最も大きな周波数成分を返します。\r
+ * @param i_freq_count_table\r
+ * @param i_freq_table\r
+ * @param o_freq_table\r
+ * @return\r
+ * 見つかれば0以上、密辛ければ0未満\r
+ */\r
+ private static int getMaxFreq(int[] i_freq_count_table,int[] i_freq_table,int[] o_freq_table)\r
+ {\r
+ //一番成分の大きいものを得る\r
+ int index=-1;\r
+ int max=0;\r
+ for(int i=0;i<MAX_FREQ;i++){\r
+ if(max<i_freq_count_table[i]){\r
+ index=i;\r
+ max=i_freq_count_table[i];\r
+ }\r
+ } \r
+ if(index==-1){\r
+ return -1;\r
+ }\r
+ /*周波数インデクスを計算*/\r
+ final int st=(index-1)*index;\r
+ for(int i=0;i<index*2;i++)\r
+ {\r
+ o_freq_table[i]=i_freq_table[st+i]*FRQ_STEP/max;\r
+ }\r
+ return index;\r
+ }\r
+ \r
+ \r
+ //タイミングパターン用のパラメタ(FRQ_POINTS*FRQ_STEPが100を超えないようにすること)\r
+ private static int FRQ_EDGE=5;\r
+ private static int FRQ_STEP=2;\r
+ private static int FRQ_POINTS=(100-(FRQ_EDGE*2))/FRQ_STEP;\r
+ \r
+\r
+ private static int MIN_FREQ=3;\r
+ private static int MAX_FREQ=10;\r
+ private static int FREQ_SAMPLE_NUM=4;\r
+ private static int MAX_DATA_BITS=MAX_FREQ+MAX_FREQ-1;\r
+\r
+ private final int[] _ref_x=new int[108];\r
+ private final int[] _ref_y=new int[108];\r
+ //(model+1)*4*3とTHRESHOLD_PIXEL*3のどちらか大きい方\r
+ private int[] _pixcel_temp=new int[108*3];\r
+ \r
+ private final int[] _freq_count_table=new int[MAX_FREQ];\r
+ private final int[] _freq_table=new int[(MAX_FREQ*2-1)*MAX_FREQ*2/2];\r
+\r
+ /**\r
+ * i_y1行目とi_y2行目を平均して、タイミングパターンの周波数を得ます。\r
+ * LHLを1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを\r
+ * 検出した場合、関数は失敗します。\r
+ * \r
+ * @param i_y1\r
+ * @param i_y2\r
+ * @param i_th_h\r
+ * @param i_th_l\r
+ * @param o_edge_index\r
+ * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列です。\r
+ * [FRQ_POINTS]以上の配列を指定してください。\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public int getRowFrequency(int i_y1,int i_th_h,int i_th_l,int[] o_edge_index)throws NyARException\r
+ {\r
+ //3,4,5,6,7,8,9,10\r
+ final int[] freq_count_table=this._freq_count_table;\r
+ //0,2,4,6,8,10,12,14,16,18,20の要素を持つ配列\r
+ final int freq_table[]=this._freq_table;\r
+ //初期化\r
+ final double[] cpara=this._cparam;\r
+ final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+ final int[] ref_x=this._ref_x;\r
+ final int[] ref_y=this._ref_y;\r
+ final int[] pixcel_temp=this._pixcel_temp;\r
+ for(int i=0;i<10;i++){\r
+ freq_count_table[i]=0;\r
+ }\r
+ for(int i=0;i<110;i++){\r
+ freq_table[i]=0;\r
+ }\r
+ final double cpara_0=cpara[0];\r
+ final double cpara_3=cpara[3];\r
+ final double cpara_6=cpara[6];\r
+ \r
+ //10-20ピクセル目からタイミングパターンを検出\r
+ for(int i=0;i<FREQ_SAMPLE_NUM;i++){\r
+ //2行分のピクセルインデックスを計算\r
+ final double cy0=1+i_y1+i;\r
+ final double cpy0_12=cpara[1]*cy0+cpara[2];\r
+ final double cpy0_45=cpara[4]*cy0+cpara[5];\r
+ final double cpy0_7=cpara[7]*cy0+1.0; \r
+\r
+\r
+ int pt=0;\r
+ for(int i2=0;i2<FRQ_POINTS;i2++)\r
+ {\r
+ double d;\r
+ final double cx0=1+i2*FRQ_STEP+FRQ_EDGE; \r
+ d=(cpara_6*cx0)+cpy0_7;\r
+ ref_x[pt]=(int)((cpara_0*cx0+cpy0_12)/d);\r
+ ref_y[pt]=(int)((cpara_3*cx0+cpy0_45)/d);\r
+ pt++;\r
+ }\r
+ \r
+ //ピクセルを取得(入力画像を多様化するならここから先を調整すること)\r
+ reader.getPixelSet(ref_x,ref_y,FRQ_POINTS,pixcel_temp);\r
+\r
+ //o_edge_indexを一時的に破壊して調査する\r
+ final int freq_t=getFreqInfo(pixcel_temp,i_th_h,i_th_l,o_edge_index); \r
+ \r
+ //周期は3-10であること\r
+ if(freq_t<MIN_FREQ || freq_t>MAX_FREQ){\r
+ continue;\r
+ }\r
+ //周期は等間隔であること\r
+ if(!checkFreqWidth(o_edge_index,freq_t)){\r
+ continue;\r
+ }\r
+ //検出カウンタを追加\r
+ freq_count_table[freq_t]++;\r
+ final int table_st=(freq_t-1)*freq_t;\r
+ for(int i2=0;i2<freq_t*2;i2++){\r
+ freq_table[table_st+i2]+=o_edge_index[i2];\r
+ }\r
+ }\r
+ return getMaxFreq(freq_count_table,freq_table,o_edge_index);\r
+ }\r
+ \r
+ public int getColFrequency(int i_x1,int i_th_h,int i_th_l,int[] o_edge_index)throws NyARException\r
+ {\r
+ final double[] cpara=this._cparam;\r
+ final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+ final int[] ref_x=this._ref_x;\r
+ final int[] ref_y=this._ref_y;\r
+ final int[] pixcel_temp=this._pixcel_temp;\r
+ //0,2,4,6,8,10,12,14,16,18,20=(11*20)/2=110\r
+ final int[] freq_count_table=this._freq_count_table;\r
+ final int freq_table[]=this._freq_table;\r
+ //初期化\r
+ for(int i=0;i<10;i++){\r
+ freq_count_table[i]=0;\r
+ }\r
+ for(int i=0;i<110;i++){\r
+ freq_table[i]=0;\r
+ }\r
+ final double cpara7=cpara[7];\r
+ final double cpara4=cpara[4];\r
+ final double cpara1=cpara[1];\r
+ //基準点から4ピクセルを参照パターンとして抽出\r
+ for(int i=0;i<FREQ_SAMPLE_NUM;i++){\r
+\r
+ int cx0;\r
+ cx0=1+i+i_x1;\r
+ final double cp6_0=cpara[6]*cx0;\r
+ final double cpx0_0=cpara[0]*cx0+cpara[2];\r
+ final double cpx3_0=cpara[3]*cx0+cpara[5];\r
+ \r
+ int pt=0;\r
+ for(int i2=0;i2<FRQ_POINTS;i2++)\r
+ {\r
+ double d;\r
+ int cy=1+i2*FRQ_STEP+FRQ_EDGE;\r
+ \r
+ d=cp6_0+cpara7*cy+1.0;\r
+ ref_x[pt]=(int)((cpx0_0+cpara1*cy)/d);\r
+ ref_y[pt]=(int)((cpx3_0+cpara4*cy)/d);\r
+ pt++;\r
+ } \r
+ \r
+ //ピクセルを取得(入力画像を多様化するならここを調整すること)\r
+ reader.getPixelSet(ref_x,ref_y,FRQ_POINTS,pixcel_temp);\r
+ \r
+ final int freq_t=getFreqInfo(pixcel_temp,i_th_h,i_th_l,o_edge_index);\r
+ //周期は3-10であること\r
+ if(freq_t<MIN_FREQ || freq_t>MAX_FREQ){\r
+ continue;\r
+ }\r
+ //周期は等間隔であること\r
+ if(!checkFreqWidth(o_edge_index,freq_t)){\r
+ continue;\r
+ }\r
+ //検出カウンタを追加\r
+ freq_count_table[freq_t]++;\r
+ final int table_st=(freq_t-1)*freq_t;\r
+ for(int i2=0;i2<freq_t*2;i2++){\r
+ freq_table[table_st+i2]+=o_edge_index[i2];\r
+ }\r
+ }\r
+ return getMaxFreq(freq_count_table,freq_table,o_edge_index); \r
+ }\r
+\r
+ /**\r
+ * デバックすんだらstaticにしておk\r
+ * @param i_pixcels\r
+ * @param i_th_h\r
+ * @param i_th_l\r
+ * @param o_edge_index\r
+ * @return\r
+ */\r
+ private static int getFreqInfo(int[] i_pixcels,int i_th_h,int i_th_l,int[] o_edge_index)\r
+ {\r
+ //トークンを解析して、周波数を計算\r
+ int i=0;\r
+ int frq_l2h=0;\r
+ int frq_h2l=0;\r
+ while(i<FRQ_POINTS){\r
+ //L->Hトークンを検出する\r
+ while(i<FRQ_POINTS){\r
+ final int index=i*3;\r
+ final int pix=(i_pixcels[index+0]+i_pixcels[index+1]+i_pixcels[index+2])/3;\r
+ if(pix>i_th_h){\r
+ //トークン発見\r
+ o_edge_index[frq_l2h+frq_h2l]=i;\r
+ frq_l2h++;\r
+ break;\r
+ }\r
+ i++;\r
+ }\r
+ i++;\r
+ //L->Hトークンを検出する\r
+ while(i<FRQ_POINTS){\r
+ final int index=i*3;\r
+ final int pix=(i_pixcels[index+0]+i_pixcels[index+1]+i_pixcels[index+2])/3;\r
+ if(pix<=i_th_l){\r
+ //トークン発見\r
+ o_edge_index[frq_l2h+frq_h2l]=i;\r
+ frq_h2l++;\r
+ break;\r
+ }\r
+ i++;\r
+ }\r
+ i++;\r
+ }\r
+ return frq_l2h==frq_h2l?frq_l2h:-1; \r
+ }\r
+\r
+ private final static int THRESHOLD_EDGE=10;\r
+ private final static int THRESHOLD_STEP=2;\r
+ private final static int THRESHOLD_WIDTH=10;\r
+ private final static int THRESHOLD_PIXEL=THRESHOLD_WIDTH/THRESHOLD_STEP;\r
+ private final static int THRESHOLD_SAMPLE=THRESHOLD_PIXEL*THRESHOLD_PIXEL;\r
+ private final static int THRESHOLD_SAMPLE_LT=THRESHOLD_EDGE;\r
+ private final static int THRESHOLD_SAMPLE_RB=100-THRESHOLD_WIDTH-THRESHOLD_EDGE;\r
+ \r
+ public static class TThreshold{\r
+ public int th_h;\r
+ public int th_l;\r
+ public int th;\r
+ public int lt_x;\r
+ public int lt_y;\r
+ public int rb_x;\r
+ public int rb_y;\r
+ } \r
+\r
+ class THighAndLow{\r
+ int h;\r
+ int l;\r
+ }\r
+ /**\r
+ * ピクセル配列の上位、下位の4ピクセルのピクセル値平均を求めます。\r
+ * この関数は、(4/i_pixcel.length)の領域を占有するPtail法で双方向の閾値を求めることになります。\r
+ * @param i_pixcel\r
+ * @param i_initial\r
+ * @param i_out\r
+ */\r
+ private void getPtailHighAndLow(int[] i_pixcel,THighAndLow i_out)\r
+ {\r
+ int h3,h2,h1,h0,l3,l2,l1,l0;\r
+ h3=h2=h1=h0=l3=l2=l1=l0=i_pixcel[0];\r
+ \r
+ for(int i=i_pixcel.length-1;i>=1;i--){\r
+ final int pix=i_pixcel[i];\r
+ if(h0<pix){\r
+ if(h1<pix){\r
+ if(h2<pix){\r
+ if(h3<pix){\r
+ h0=h1;\r
+ h1=h2;\r
+ h2=h3;\r
+ h3=pix;\r
+ }else{\r
+ h0=h1;\r
+ h1=h2;\r
+ h2=pix;\r
+ }\r
+ }else{\r
+ h0=h1;\r
+ h1=pix;\r
+ }\r
+ }else{\r
+ h0=pix;\r
+ }\r
+ }\r
+ if(l0>pix){\r
+ if(l1>pix){\r
+ if(l2>pix){\r
+ if(l3>pix){\r
+ l0=l1;\r
+ l1=l2;\r
+ l2=l3;\r
+ l3=pix;\r
+ }else{\r
+ l0=l1;\r
+ l1=l2;\r
+ l2=pix;\r
+ }\r
+ }else{\r
+ l0=l1;\r
+ l1=pix;\r
+ }\r
+ }else{\r
+ l0=pix;\r
+ }\r
+ }\r
+ }\r
+ i_out.l=(l0+l1+l2+l3)/4;\r
+ i_out.h=(h0+h1+h2+h3)/4;\r
+ return;\r
+ }\r
+ private THighAndLow __detectThresholdValue_hl=new THighAndLow();\r
+ private NyARIntPoint2d __detectThresholdValue_tpt=new NyARIntPoint2d();\r
+ private int[] _th_pixels=new int[THRESHOLD_SAMPLE*4];\r
+ /**\r
+ * 指定した場所のピクセル値を調査して、閾値を計算して返します。\r
+ * @param i_reader\r
+ * @param i_x\r
+ * @param i_y\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public void detectThresholdValue(INyARRgbPixelReader i_reader,int i_x,int i_y,TThreshold o_threshold)throws NyARException\r
+ {\r
+ final int[] th_pixels=this._th_pixels;\r
+\r
+ //左上のピックアップ領域からピクセルを得る(00-24)\r
+ rectPixels(THRESHOLD_SAMPLE_LT,THRESHOLD_SAMPLE_LT,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,0,th_pixels);\r
+ \r
+ //左下のピックアップ領域からピクセルを得る(25-49)\r
+ rectPixels(THRESHOLD_SAMPLE_LT,THRESHOLD_SAMPLE_RB,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,THRESHOLD_SAMPLE,th_pixels);\r
+ \r
+ //右上のピックアップ領域からピクセルを得る(50-74)\r
+ rectPixels(THRESHOLD_SAMPLE_RB,THRESHOLD_SAMPLE_LT,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,THRESHOLD_SAMPLE*2,th_pixels);\r
+\r
+ //右下のピックアップ領域からピクセルを得る(75-99)\r
+ rectPixels(THRESHOLD_SAMPLE_RB,THRESHOLD_SAMPLE_RB,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,THRESHOLD_SAMPLE*3,th_pixels);\r
+\r
+ final THighAndLow hl=this.__detectThresholdValue_hl;\r
+ //Ptailで求めたピクセル平均\r
+ getPtailHighAndLow(th_pixels,hl);\r
+\r
+\r
+ \r
+ //閾値中心\r
+ int th=(hl.h+hl.l)/2;\r
+ //ヒステリシス(差分の20%)\r
+ int th_sub=(hl.h-hl.l)/5;\r
+ \r
+ o_threshold.th=th;\r
+ o_threshold.th_h=th+th_sub;//ヒステリシス付き閾値\r
+ o_threshold.th_l=th-th_sub;//ヒステリシス付き閾値\r
+\r
+ //エッジを計算(明点重心)\r
+ int lt_x,lt_y,lb_x,lb_y,rt_x,rt_y,rb_x,rb_y;\r
+ final NyARIntPoint2d tpt=this.__detectThresholdValue_tpt;\r
+ //LT\r
+ if(getHighPixelCenter(0,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+ lt_x=tpt.x*THRESHOLD_STEP;\r
+ lt_y=tpt.y*THRESHOLD_STEP;\r
+ }else{\r
+ lt_x=11;\r
+ lt_y=11;\r
+ }\r
+ //LB\r
+ if(getHighPixelCenter(THRESHOLD_SAMPLE*1,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+ lb_x=tpt.x*THRESHOLD_STEP;\r
+ lb_y=tpt.y*THRESHOLD_STEP;\r
+ }else{\r
+ lb_x=11;\r
+ lb_y=-1;\r
+ }\r
+ //RT\r
+ if(getHighPixelCenter(THRESHOLD_SAMPLE*2,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+ rt_x=tpt.x*THRESHOLD_STEP;\r
+ rt_y=tpt.y*THRESHOLD_STEP;\r
+ }else{\r
+ rt_x=-1;\r
+ rt_y=11;\r
+ }\r
+ //RB\r
+ if(getHighPixelCenter(THRESHOLD_SAMPLE*3,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+ rb_x=tpt.x*THRESHOLD_STEP;\r
+ rb_y=tpt.y*THRESHOLD_STEP;\r
+ }else{\r
+ rb_x=-1;\r
+ rb_y=-1;\r
+ }\r
+ //トラッキング開始位置の決定\r
+ o_threshold.lt_x=(lt_x+lb_x)/2+THRESHOLD_SAMPLE_LT-1;\r
+ o_threshold.rb_x=(rt_x+rb_x)/2+THRESHOLD_SAMPLE_RB+1;\r
+ o_threshold.lt_y=(lt_y+rt_y)/2+THRESHOLD_SAMPLE_LT-1;\r
+ o_threshold.rb_y=(lb_y+rb_y)/2+THRESHOLD_SAMPLE_RB+1;\r
+ return;\r
+ }\r
+\r
+ private boolean getHighPixelCenter(int i_st,final int[] i_pixels,int i_width,int i_height,int i_th,NyARIntPoint2d o_point)\r
+ {\r
+ int rp=i_st;\r
+ int pos_x=0;\r
+ int pos_y=0;\r
+ int number_of_pos=0;\r
+ for(int i=0;i<i_height;i++){\r
+ for(int i2=0;i2<i_width;i2++){\r
+ if(i_pixels[rp++]>i_th){\r
+ pos_x+=i2;\r
+ pos_y+=i;\r
+ number_of_pos++;\r
+ }\r
+ }\r
+ }\r
+ if(number_of_pos>0){\r
+ pos_x/=number_of_pos;\r
+ pos_y/=number_of_pos;\r
+ }else{\r
+ return false;\r
+ }\r
+ o_point.x=pos_x;\r
+ o_point.y=pos_y;\r
+ return true;\r
+ }\r
+ private int[] __detectDataBitsIndex_freq_index1=new int[FRQ_POINTS];\r
+ private int[] __detectDataBitsIndex_freq_index2=new int[FRQ_POINTS];\r
+ private int detectDataBitsIndex(PerspectivePixelReader.TThreshold i_th,double[] o_index_row,double[] o_index_col) throws NyARException\r
+ {\r
+ //周波数を測定\r
+ final int freq_index1[]=this.__detectDataBitsIndex_freq_index1;\r
+ final int freq_index2[]=this.__detectDataBitsIndex_freq_index2;\r
+ \r
+ \r
+ int frq_t=getRowFrequency(i_th.lt_y,i_th.th_h,i_th.th_l,freq_index1);\r
+ int frq_b=getRowFrequency(i_th.rb_y,i_th.th_h,i_th.th_l,freq_index2);\r
+ //周波数はまとも?\r
+ if((frq_t<0 && frq_b<0) || frq_t==frq_b){\r
+ return -1;\r
+ }\r
+ //タイミングパターンからインデクスを作成\r
+ int freq_h,freq_v;\r
+ int[] index;\r
+ if(frq_t>frq_b){\r
+ freq_h=frq_t;\r
+ index=freq_index1;\r
+ }else{\r
+ freq_h=frq_b;\r
+ index=freq_index2;\r
+ }\r
+ for(int i=0;i<freq_h+freq_h-1;i++){\r
+ o_index_row[i*2]=((index[i+1]-index[i])*2/5+index[i])+FRQ_EDGE;\r
+ o_index_row[i*2+1]=((index[i+1]-index[i])*3/5+index[i])+FRQ_EDGE;\r
+ } \r
+ \r
+ \r
+ int frq_l=getColFrequency(i_th.lt_x,i_th.th_h,i_th.th_l,freq_index1);\r
+ int frq_r=getColFrequency(i_th.rb_x,i_th.th_h,i_th.th_l,freq_index2);\r
+ //周波数はまとも?\r
+ if((frq_l<0 && frq_r<0) || frq_l==frq_r){\r
+ return -1;\r
+ }\r
+ //タイミングパターンからインデクスを作成\r
+ if(frq_l>frq_r){\r
+ freq_v=frq_l;\r
+ index=freq_index1;\r
+ }else{\r
+ freq_v=frq_r;\r
+ index=freq_index2;\r
+ }\r
+ //同じ周期?\r
+ if(freq_v!=freq_h){\r
+ return -1;\r
+ }\r
+ \r
+ for(int i=0;i<freq_v+freq_v-1;i++){\r
+ final int w=index[i];\r
+ final int w2=index[i+1]-w;\r
+ o_index_col[i*2]=((w2)*2/5+w)+FRQ_EDGE;\r
+ o_index_col[i*2+1]=((w2)*3/5+w)+FRQ_EDGE;\r
+ } \r
+ //Lv4以上は無理\r
+ if(freq_v>MAX_FREQ){\r
+ return -1;\r
+ }\r
+ return freq_v;\r
+ \r
+ }\r
+ private double[] __readDataBits_index_bit_x=new double[MAX_DATA_BITS*2];\r
+ private double[] __readDataBits_index_bit_y=new double[MAX_DATA_BITS*2];\r
+ \r
+ public boolean readDataBits(PerspectivePixelReader.TThreshold i_th,MarkerPattEncoder o_bitbuffer)throws NyARException\r
+ {\r
+ final double[] index_x=this.__readDataBits_index_bit_x;\r
+ final double[] index_y=this.__readDataBits_index_bit_y;\r
+ //読み出し位置を取得\r
+ final int size=detectDataBitsIndex(i_th,index_x,index_y);\r
+ final int resolution=size+size-1;\r
+ if(size<0){\r
+ return false;\r
+ }\r
+ if(!o_bitbuffer.initEncoder(size-1)){\r
+ return false;\r
+ } \r
+ \r
+ final double[] cpara=this._cparam;\r
+ final int[] ref_x=this._ref_x;\r
+ final int[] ref_y=this._ref_y;\r
+ final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+ final int[] pixcel_temp=this._pixcel_temp;\r
+ \r
+ final double cpara_0=cpara[0];\r
+ final double cpara_1=cpara[1];\r
+ final double cpara_3=cpara[3];\r
+ final double cpara_6=cpara[6];\r
+ \r
+ \r
+ final int th=i_th.th;\r
+ int p=0;\r
+ int pt2=0;\r
+ for(int i=0;i<resolution;i++){\r
+ //1列分のピクセルのインデックス値を計算する。\r
+ double cy0=1+index_y[i*2+0];\r
+ double cy1=1+index_y[i*2+1]; \r
+ double cpy0_12=cpara_1*cy0+cpara[2];\r
+ double cpy0_45=cpara[4]*cy0+cpara[5];\r
+ double cpy0_7=cpara[7]*cy0+1.0;\r
+ double cpy1_12=cpara_1*cy1+cpara[2];\r
+ double cpy1_45=cpara[4]*cy1+cpara[5];\r
+ double cpy1_7=cpara[7]*cy1+1.0;\r
+ \r
+ int pt=0;\r
+ for(int i2=0;i2<resolution;i2++)\r
+ { \r
+\r
+ double d;\r
+ double cx0=1+index_x[i2*2+0];\r
+ double cx1=1+index_x[i2*2+1];\r
+\r
+ double cp6_0=cpara_6*cx0;\r
+ double cpx0_0=cpara_0*cx0;\r
+ double cpx3_0=cpara_3*cx0;\r
+\r
+ double cp6_1=cpara_6*cx1;\r
+ double cpx0_1=cpara_0*cx1;\r
+ double cpx3_1=cpara_3*cx1;\r
+ \r
+ d=cp6_0+cpy0_7;\r
+ ref_x[pt]=(int)((cpx0_0+cpy0_12)/d);\r
+ ref_y[pt]=(int)((cpx3_0+cpy0_45)/d);\r
+ this.vertex_x[pt2]=ref_x[pt];\r
+ this.vertex_y[pt2++]=ref_y[pt];\r
+ pt++;\r
+\r
+ d=cp6_0+cpy1_7;\r
+ ref_x[pt]=(int)((cpx0_0+cpy1_12)/d);\r
+ ref_y[pt]=(int)((cpx3_0+cpy1_45)/d);\r
+ this.vertex_x[pt2]=ref_x[pt];\r
+ this.vertex_y[pt2++]=ref_y[pt];\r
+ pt++;\r
+\r
+ d=cp6_1+cpy0_7;\r
+ ref_x[pt]=(int)((cpx0_1+cpy0_12)/d);\r
+ ref_y[pt]=(int)((cpx3_1+cpy0_45)/d);\r
+ this.vertex_x[pt2]=ref_x[pt];\r
+ this.vertex_y[pt2++]=ref_y[pt];\r
+ pt++;\r
+\r
+ d=cp6_1+cpy1_7;\r
+ ref_x[pt]=(int)((cpx0_1+cpy1_12)/d);\r
+ ref_y[pt]=(int)((cpx3_1+cpy1_45)/d);\r
+ this.vertex_x[pt2]=ref_x[pt];\r
+ this.vertex_y[pt2++]=ref_y[pt];\r
+ pt++;\r
+ }\r
+ //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)\r
+ reader.getPixelSet(ref_x,ref_y,resolution*4,pixcel_temp);\r
+ //グレースケールにしながら、line→mapへの転写\r
+ for(int i2=0;i2<resolution;i2++){\r
+ int index=i2*3*4;\r
+ int pixel=( pixcel_temp[index+0]+pixcel_temp[index+1]+pixcel_temp[index+2]+\r
+ pixcel_temp[index+3]+pixcel_temp[index+4]+pixcel_temp[index+5]+\r
+ pixcel_temp[index+6]+pixcel_temp[index+7]+pixcel_temp[index+8]+\r
+ pixcel_temp[index+9]+pixcel_temp[index+10]+pixcel_temp[index+11])/(4*3);\r
+ o_bitbuffer.setBitByBitIndex(p,pixel>th?1:0);\r
+ p++;\r
+ }\r
+ }\r
+/* \r
+ for(int i=0;i<225*4;i++){\r
+ this.vertex_x[i]=0;\r
+ this.vertex_y[i]=0;\r
+ }\r
+ for(int i=0;i<(resolution)*2;i++){\r
+ for(int i2=0;i2<(resolution)*2;i2++){\r
+ this.vertex_x[i*(resolution)*2+i2]=(int)index_x[i2];\r
+ this.vertex_y[i*(resolution)*2+i2]=(int)index_y[i];\r
+ \r
+ }\r
+ }\r
+*/ return true;\r
+ }\r
+ int[] vertex_x;\r
+ int[] vertex_y;\r
+ public boolean setSquare(NyARIntPoint2d[] i_vertex) throws NyARException\r
+ {\r
+ if (!this._param_gen.getParam(i_vertex,this._cparam)) {\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+\r
+}\r
+class MarkerPattDecoder\r
+{\r
+ public void decode(int model,int domain,int mask)\r
+ {\r
+ \r
+ }\r
+}\r
+/**\r
+ * マーカパターンのエンコーダです。\r
+ *\r
+ */\r
+class MarkerPattEncoder\r
+{\r
+ private final static int[] _bit_table_3={\r
+ 25, 26, 27, 28, 29, 30, 31,\r
+ 48, 9, 10, 11, 12, 13, 32,\r
+ 47, 24, 1, 2, 3, 14, 33,\r
+ 46, 23, 8, 0, 4, 15, 34,\r
+ 45, 22, 7, 6, 5, 16, 35,\r
+ 44, 21, 20, 19, 18, 17, 36,\r
+ 43, 42, 41, 40, 39, 38, 37\r
+ }; \r
+ private final static int[] _bit_table_2={\r
+ 9, 10, 11, 12, 13,\r
+ 24, 1, 2, 3, 14,\r
+ 23, 8, 0, 4, 15,\r
+ 22, 7, 6, 5, 16,\r
+ 21, 20, 19, 18, 17};\r
+ private final static int[][] _bit_tables={\r
+ _bit_table_2,_bit_table_3,null,null,null,null,null,\r
+ };\r
+ /**\r
+ * RECT(0):[0]=(0)\r
+ * RECT(1):[1]=(1-8)\r
+ * RECT(2):[2]=(9-16),[3]=(17-24)\r
+ * RECT(3):[4]=(25-32),[5]=(33-40),[6]=(41-48)\r
+ */\r
+ int[] _bit_table;\r
+ int[] _bits=new int[16];\r
+ int[] _work=new int[16];\r
+ int _model;\r
+ public void setBitByBitIndex(int i_index_no,int i_value)\r
+ {\r
+ assert i_value==0 || i_value==1;\r
+ final int bit_no=this._bit_table[i_index_no];\r
+ if(bit_no==0){\r
+ this._bits[0]=i_value;\r
+ }else{\r
+ int bidx=(bit_no-1)/8+1;\r
+ int sidx=(bit_no-1)%8;\r
+ this._bits[bidx]=(this._bits[bidx]&(~(0x01<<sidx)))|(i_value<<sidx);\r
+ }\r
+ return;\r
+ }\r
+ \r
+ public void setBit(int i_bit_no,int i_value)\r
+ {\r
+ assert i_value==0 || i_value==1;\r
+ if(i_bit_no==0){\r
+ this._bits[0]=i_value;\r
+ }else{\r
+ int bidx=(i_bit_no-1)/8+1;\r
+ int sidx=(i_bit_no-1)%8;\r
+ this._bits[bidx]=(this._bits[bidx]&(~(0x01<<sidx)))|(i_value<<sidx);\r
+ }\r
+ return;\r
+ }\r
+ public int getBit(int i_bit_no)\r
+ {\r
+ if(i_bit_no==0){\r
+ return this._bits[0];\r
+ }else{\r
+ int bidx=(i_bit_no-1)/8+1;\r
+ int sidx=(i_bit_no-1)%8;\r
+ return (this._bits[bidx]>>(sidx))&(0x01);\r
+ }\r
+ }\r
+ public int getModel()\r
+ {\r
+ return this._model;\r
+ }\r
+ private static int getControlValue(int i_model,int[] i_data)\r
+ {\r
+ int v;\r
+ switch(i_model){\r
+ case 2:\r
+ v=(i_data[2] & 0x0e)>>1;\r
+ return v>=5?v-1:v;\r
+ case 3:\r
+ v=(i_data[4] & 0x3e)>>1;\r
+ return v>=21?v-1:v;\r
+ case 4:\r
+ case 5:\r
+ case 6:\r
+ case 7:\r
+ }\r
+ return -1;\r
+ }\r
+ public static int getCheckValue(int i_model,int[] i_data)\r
+ {\r
+ int v;\r
+ switch(i_model){\r
+ case 2:\r
+ v=(i_data[2] & 0xe0)>>5;\r
+ return v>5?v-1:v;\r
+ case 3:\r
+ v=((i_data[4] & 0x80)>>7) |((i_data[5] & 0x0f)<<1);\r
+ return v>21?v-1:v;\r
+ case 4:\r
+ case 5:\r
+ case 6:\r
+ case 7:\r
+ }\r
+ return -1;\r
+ }\r
+ public boolean initEncoder(int i_model)\r
+ {\r
+ if(i_model>3 || i_model<2){\r
+ //Lv4以降に対応する時は、この制限を変える。\r
+ return false;\r
+ }\r
+ this._bit_table=_bit_tables[i_model-2];\r
+ this._model=i_model;\r
+ return true;\r
+ }\r
+ private int getDirection()\r
+ {\r
+ int l,t,r,b;\r
+ int timing_pat;\r
+ switch(this._model){\r
+ case 2:\r
+ //トラッキングセルを得る\r
+ t=this._bits[2] & 0x1f;\r
+ r=((this._bits[2] & 0xf0)>>4)|((this._bits[3]&0x01)<<4);\r
+ b=this._bits[3] & 0x1f;\r
+ l=((this._bits[3] & 0xf0)>>4)|((this._bits[2]&0x01)<<4);\r
+ timing_pat=0x15;\r
+ break;\r
+ case 3:\r
+ t=this._bits[4] & 0x7f;\r
+ r=((this._bits[4] & 0xc0)>>6)|((this._bits[5] & 0x1f)<<2);\r
+ b=((this._bits[5] & 0xf0)>>4)|(this._bits[6]&0x07<<4);\r
+ l=((this._bits[7] & 0xfc)>>2)|((this._bits[4] & 0x01)<<7);\r
+ timing_pat=0x55;\r
+ break;\r
+ default:\r
+ return -3;\r
+ }\r
+ //タイミングパターンの比較\r
+ if(t==timing_pat){\r
+ if(r==timing_pat){\r
+ return (b!=timing_pat && l!=timing_pat)?2:-2;\r
+ }else if(l==timing_pat){\r
+ return (b!=timing_pat && r!=timing_pat)?3:-2;\r
+ }\r
+ }else if(b==timing_pat){\r
+ if(r==timing_pat){\r
+ return (t!=timing_pat && l!=timing_pat)?1:-2;\r
+ }else if(l==timing_pat){\r
+ return (t!=timing_pat && r!=timing_pat)?0:-2;\r
+ }\r
+ }\r
+ return -1;\r
+ }\r
+ /**\r
+ * 格納しているマーカパターンをエンコードして、マーカデータを返します。\r
+ * @param o_out\r
+ * @return\r
+ * 成功すればマーカの方位を返却します。失敗すると-1を返します。\r
+ */\r
+\r
+ public int encode(NyARIdMarkerData o_out)\r
+ {\r
+ final int d=getDirection();\r
+ if(d<0){\r
+ return -1;\r
+ }\r
+ //回転ビットの取得\r
+ getRotatedBits(d,o_out.data);\r
+ final int model=this._model;\r
+ //周辺ビットの取得\r
+ o_out.model=model;\r
+ int control_bits=getControlValue(model,o_out.data);\r
+ o_out.check=getCheckValue(model,o_out.data);\r
+ o_out.ctrl_mask=control_bits%5;\r
+ o_out.ctrl_domain=control_bits/5;\r
+ if(o_out.ctrl_domain!=0 || o_out.ctrl_mask!=0){\r
+ return -1;\r
+ }\r
+ //マスク解除処理を実装すること\r
+ return d;\r
+ }\r
+ private void getRotatedBits(int i_direction,int[] o_out)\r
+ {\r
+ int sl=i_direction*2;\r
+ int sr=8-sl;\r
+\r
+ int w1;\r
+ //RECT1\r
+ w1=this._bits[1];\r
+ this._bits[1]=(w1<<sl)|(w1>>sr);\r
+ \r
+ //RECT2\r
+ sl=i_direction*4;\r
+ sr=16-sl;\r
+ w1=this._bits[2]|(this._bits[3]<<8);\r
+ w1=(w1<<sl)|(w1>>sr);\r
+ o_out[2]=w1 & 0xff;\r
+ o_out[3]=(w1>>8) & 0xff;\r
+\r
+ if(this._model<2){\r
+ return;\r
+ }\r
+\r
+ //RECT3\r
+ sl=i_direction*6;\r
+ sr=24-sl; \r
+ w1=this._bits[4]|(this._bits[5]<<8)|(this._bits[6]<<16);\r
+ w1=(w1<<sl)|(w1>>sr);\r
+ o_out[4]=w1 & 0xff;\r
+ o_out[5]=(w1>>8) & 0xff;\r
+ o_out[6]=(w1>>16) & 0xff;\r
+ \r
+ if(this._model<3){\r
+ return;\r
+ }\r
+ //RECT4(Lv4以降はここの制限を変える)\r
+// shiftLeft(this._bits,7,3,i_direction*8);\r
+// if(this._model<4){\r
+// return;\r
+// }\r
+ return;\r
+ }\r
+ public void shiftLeft(int[] i_pack,int i_start,int i_length,int i_ls)\r
+ {\r
+ int[] work=this._work;\r
+ //端数シフト\r
+ final int mod_shift=i_ls%8;\r
+ for(int i=i_length-1;i>=1;i--){\r
+ work[i]=(i_pack[i+i_start]<<mod_shift)|(0xff&(i_pack[i+i_start-1]>>(8-mod_shift)));\r
+ }\r
+ work[0]=(i_pack[i_start]<<mod_shift)|(0xff&(i_pack[i_start+i_length-1]>>(8-mod_shift)));\r
+ //バイトシフト\r
+ final int byte_shift=(i_ls/8)%i_length;\r
+ for(int i=i_length-1;i>=0;i--){\r
+ i_pack[(byte_shift+i)%i_length+i_start]=0xff & work[i];\r
+ }\r
+ return;\r
+ } \r
+}\r
+/**\r
+ * ラスタ画像の任意矩形から、NyARIdMarkerDataを抽出します。\r
+ *\r
+ */\r
+public class NyARIdMarkerPickup\r
+{\r
+ PerspectivePixelReader _perspective_reader;\r
+\r
+\r
+ public NyARIdMarkerPickup()\r
+ {\r
+ this._perspective_reader=new PerspectivePixelReader();\r
+ return;\r
+ } \r
+ \r
+ \r
+\r
+ public int[] vertex_x=new int[225*4];\r
+ public int[] vertex_y=new int[225*4];\r
+ public int[] vertex2_x=new int[400];\r
+ public int[] vertex2_y=new int[400];\r
+\r
+\r
+\r
+ /**\r
+ * i_imageから、idマーカを読みだします。\r
+ * o_dataにはマーカデータ、o_paramにはまーかのパラメータを返却します。\r
+ * @param image\r
+ * @param i_square\r
+ * @param o_data\r
+ * @param o_param\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square,NyARIdMarkerData o_data,NyARIdMarkerParam o_param)throws NyARException\r
+ {\r
+ this._perspective_reader.setSourceRaster(image);\r
+ \r
+ //遠近法のパラメータを計算\r
+ if(!this._perspective_reader.setSourceSquare(i_square.imvertex)){\r
+ return false;\r
+ };\r
+ \r
+ final INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+\r
+\r
+ PerspectivePixelReader.TThreshold th=new PerspectivePixelReader.TThreshold();\r
+ MarkerPattEncoder encoder=new MarkerPattEncoder();\r
+ //マーカパラメータを取得\r
+ this._perspective_reader.detectThresholdValue(reader,10,10,th);\r
+\r
+ \r
+ this._perspective_reader.vertex_x=this.vertex_x;\r
+ this._perspective_reader.vertex_y=this.vertex_y;\r
+\r
+ this._perspective_reader.readDataBits(th, encoder);\r
+ final int d=encoder.encode(o_data);\r
+ if(d<0){\r
+ return false;\r
+ }\r
+ o_param.direction=d;\r
+ o_param.threshold=th.th;\r
+ \r
+ return true;\r
+ }\r
+}\r
import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
import jp.nyatla.nyartoolkit.core.types.*;\r
\r
-/**このクラスは、同時に1個のマーカを処理することのできる、アプリケーションプロセッサです。\r
+/**\r
+ * このクラスは、同時に1個のマーカを処理することのできる、アプリケーションプロセッサです。\r
* マーカの出現・移動・消滅を、イベントで通知することができます。\r
* クラスには複数のマーカを登録できます。一つのマーカが見つかると、プロセッサは継続して同じマーカを\r
* 1つだけ認識し続け、見失うまでの間は他のマーカを認識しません。\r
* イベントは、 OnEnter→OnUpdate[n]→OnLeaveの順で発生します。\r
* マーカが見つかるとまずOnEnterが1度発生して、何番のマーカが発見されたかがわかります。\r
* 次にOnUpdateにより、現在の変換行列が連続して渡されます。最後にマーカを見失うと、OnLeave\r
- * イベントがコールされます。\r
+ * イベントが発生します。\r
* \r
*/\r
public abstract class SingleARMarkerProcesser\r
/* \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
/* \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
/* \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
--- /dev/null
+package jp.nyatla.utils.j2se;\r
+\r
+import java.awt.image.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+\r
+public class BufferedImageSink extends BufferedImage\r
+{\r
+ public BufferedImageSink(int i_width,int i_height)\r
+ {\r
+ super(i_width,i_height,TYPE_INT_RGB);\r
+ }\r
+ public void sinkFromRaster(INyARRgbRaster i_in) throws NyARException\r
+ {\r
+ assert i_in.getSize().isEqualSize(this.getWidth(), this.getHeight());\r
+ \r
+ //thisへ転写\r
+ INyARRgbPixelReader reader=i_in.getRgbPixelReader();\r
+ int[] rgb=new int[3];\r
+\r
+ for(int y=this.getHeight()-1;y>=0;y--){\r
+ for(int x=this.getWidth()-1;x>=0;x--){\r
+ reader.getPixel(x,y,rgb);\r
+ this.setRGB(x,y,(rgb[0]<<16)|(rgb[1]<<8)|rgb[2]);\r
+ }\r
+ }\r
+ return;\r
+ }\r
+}\r
public void overlayData(NyARIntPointStack i_stack)\r
{\r
int count = i_stack.getLength();\r
- NyARIntPoint[] items = (NyARIntPoint[])i_stack.getArray();\r
+ NyARIntPoint2d[] items = (NyARIntPoint2d[])i_stack.getArray();\r
Graphics g = this.getGraphics();\r
for (int i = 0; i < count; i++) {\r
int x = items[i].x;\r
--- /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.dev;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.utils.*;\r
+import jp.nyatla.nyartoolkit.core.labeling.NyARLabelingLabel;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.MarkerPattEncoder;\r
+import jp.nyatla.nyartoolkit.nyidmarker.PerspectivePixelReader;\r
+\r
+\r
+\r
+/**\r
+ * 1区間にある1個のエッジ位置を推定するクラスです。\r
+ *\r
+ */\r
+class NyARSingleEdgeFinder2\r
+{\r
+ public static class TEdgeInfo\r
+ {\r
+ double point; //検出したエッジの位置\r
+ int sub; //エッジの差分\r
+ } \r
+ private int[] _work;\r
+ private int _width;\r
+ private int _height;\r
+ public NyARSingleEdgeFinder2(int i_width,int i_height)\r
+ {\r
+ this._work=new int[(i_width>i_height?i_width:i_height)+1];\r
+ this._work[this._work.length-1]=0;\r
+ this._width=i_width;\r
+ this._height=i_height;\r
+ return;\r
+ }\r
+ /**\r
+ * この関数は、一区間に1個のエッジが含まれていると仮定して、その位置を推定します。\r
+ * [n]個の配列を与えた場合、[n+2]~[n-1]の間にあるエッジを検出します。\r
+ * 検出方向は左→右の順です\r
+ * @param i_pixcel\r
+ * @param i_start\r
+ * @param i_length\r
+ * @param o_out\r
+ * @return\r
+ */\r
+ public boolean scanSingleEdgeLeftToRight(int[] i_pixcel,int i_y,TEdgeInfo o_out)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int length=this._width-1;\r
+ int p=i_y*this._width;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixcel[p+1]-i_pixcel[p];\r
+ p++;\r
+ }\r
+ return scanSingleEdge(temp,length,o_out);\r
+ }\r
+ /**\r
+ * 線分内のエッジを検出します。\r
+ * この関数は、1区間に1個のエッジが含まれていると仮定して、その位置を推定します。\r
+ * [n]個の配列を与えた場合、[n+2]~[n-1]の間にあるエッジを検出します。\r
+ * 検出方向は右→左の順です\r
+ * @param i_pixcel\r
+ * @param i_start\r
+ * @param i_length\r
+ * @param o_out\r
+ * @return\r
+ */\r
+ public boolean scanSingleEdgeRightToLeft(int[] i_pixcel,int i_y,TEdgeInfo o_out)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int length=this._width-1;\r
+ int p=(i_y+1)*this._width-1;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixcel[p-1]-i_pixcel[p];\r
+ p--;\r
+ }\r
+ return scanSingleEdge(temp,length,o_out);\r
+ } \r
+ public boolean scanSingleEdgeTopToBottom(int[] i_pixcel,int i_x,TEdgeInfo o_out)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int step=this._width;\r
+ final int length=this._height-1;\r
+ int p=i_x;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixcel[p+step]-i_pixcel[p];\r
+ p+=step;\r
+ }\r
+ return scanSingleEdge(temp,length,o_out);\r
+ }\r
+ public boolean scanSingleEdgeBottomToTop(int[] i_pixcel,int i_x,TEdgeInfo o_out)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int step=this._width;\r
+ final int length=this._height-1;\r
+ int p=i_x+step*length;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixcel[p-step]-i_pixcel[p];\r
+ p-=step;\r
+ }\r
+ return scanSingleEdge(temp,length,o_out);\r
+ } \r
+ private boolean scanSingleEdge(int[] i_pixels,int i_length,TEdgeInfo o_out)\r
+ {\r
+ //微分(2回目)して、極値2か所を得る\r
+ int max_index,min_index;\r
+ int length=i_length-1;\r
+ max_index=min_index=0;\r
+ int max_value,min_value;\r
+ max_value=min_value=0;\r
+ for(int i2=0;i2<length;i2++){\r
+ int t=i_pixels[i2+1]-i_pixels[i2];\r
+ if(t>max_value){\r
+ max_index=i2;\r
+ max_value=t;\r
+ }\r
+ if(t<min_value){\r
+ min_index=i2;\r
+ min_value=t;\r
+ }\r
+ }\r
+ //同符号である場合、範囲内にエッジはない\r
+ if(max_value*min_value>=0){\r
+ return false;\r
+ } \r
+ o_out.point=(max_index+min_index)/2.0;\r
+ o_out.sub=max_value-min_value;\r
+ return true;\r
+ }\r
+ public int scanEdgeLeftToRight(int[] i_pixel,int i_y,int i_noise_th,double[] o_edge_index)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int length=this._width-1;\r
+ int p=i_y*this._width;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixel[p+1]-i_pixel[p];\r
+ p++;\r
+ }\r
+ //0終端させるために1要素を後続に追加\r
+ return scanEdge(temp,length+1,i_noise_th,o_edge_index);\r
+ }\r
+ private int scanEdge(int[] i_pixels,int i_length,int i_noise_th,double[] o_out)\r
+ {\r
+ int points=0;\r
+ final int length=i_length;\r
+ //エッジ1区間を抜き出す\r
+ for(int i2=0;i2<length;i2++){\r
+ int t=i_pixels[i2];\r
+ if(t>i_noise_th){\r
+ int st=i2;\r
+ i2++;\r
+ for(;i2<length;i2++){\r
+ t=i_pixels[i2];\r
+ if(t<=0){\r
+ //(st - i2で1区間)\r
+ //エッジ位置は区間の中央にする。\r
+ o_out[points]=(st+i2)/2.0;\r
+ points++;\r
+ if(t<0){\r
+ //マイナスであれば、0を補完する\r
+ i2--;\r
+ i_pixels[i2]=0;\r
+ }\r
+ break;\r
+ }\r
+\r
+ }\r
+ }else if(t<-i_noise_th){\r
+ int st=i2;\r
+ i2++;\r
+ for(;i2<length;i2++){\r
+ t=i_pixels[i2];\r
+ if(t>=0){\r
+ //(st - i2で1区間)\r
+ //エッジ位置は区間の中央にする。\r
+ o_out[points]=(st+i2)/2.0;\r
+ points++;\r
+ if(t>0){\r
+ //プラスであれば、0を補完する\r
+ i2--;\r
+ i_pixels[i2]=0;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return points;\r
+ } \r
+ /**\r
+ * 指定した配列をノイズパターンとして、ノイズ値を計算します。\r
+ * このノイズ値は、scanEdgeのノイズ値として使用できます。\r
+ * @param i_pixels\r
+ * @param i_length\r
+ * @return\r
+ */\r
+ public int getNoiseValue(int[] i_pixels,int i_length)\r
+ {\r
+ //1回微分して、その最大値と最小値を計算\r
+ int length=i_length-1;\r
+ int max_value,min_value;\r
+ max_value=min_value=0;\r
+ for(int i2=0;i2<length;i2++){\r
+ int t=i_pixels[i2+1]-i_pixels[i2];\r
+ if(t>max_value){\r
+ max_value=t;\r
+ }\r
+ if(t<min_value){\r
+ min_value=t;\r
+ }\r
+ }\r
+ return (-min_value>max_value)?-min_value:max_value;\r
+ } \r
+}\r
+\r
+class MarkerEncoder2\r
+{\r
+ private final static int[] _bit_table_3={\r
+ 25, 26, 27, 28, 29, 30, 31,\r
+ 48, 9, 10, 11, 12, 13, 32,\r
+ 47, 24, 1, 2, 3, 14, 33,\r
+ 46, 23, 8, 0, 4, 15, 34,\r
+ 45, 22, 7, 6, 5, 16, 35,\r
+ 44, 21, 20, 19, 18, 17, 36,\r
+ 43, 42, 41, 40, 39, 38, 37\r
+ }; \r
+ private final static int[] _bit_table_2={\r
+ 9, 10, 11, 12, 13,\r
+ 24, 1, 2, 3, 14,\r
+ 23, 8, 0, 4, 15,\r
+ 22, 7, 6, 5, 16,\r
+ 21, 20, 19, 18, 17};\r
+ private final static int[][] _bit_tables={\r
+ _bit_table_2,_bit_table_3\r
+ };\r
+ /**\r
+ * RECT(0):[0]=(0)\r
+ * RECT(1):[1]=(1-8)\r
+ * RECT(2):[2]=(9-16),[3]=(17-24)\r
+ * RECT(3):[4]=(25-32),[5]=(33-40),[6]=(41-48)\r
+ */\r
+ int[] _bit_table;\r
+ int[] _bits=new int[16];\r
+ int[] _work=new int[16];\r
+ int _model;\r
+ public void setBitByBitIndex(int i_index_no,int i_value)\r
+ {\r
+ assert i_value==0 || i_value==1;\r
+ final int bit_no=this._bit_table[i_index_no];\r
+ if(bit_no==0){\r
+ this._bits[0]=i_value;\r
+ }else{\r
+ int bidx=(bit_no-1)/8+1;\r
+ int sidx=(bit_no-1)%8;\r
+ this._bits[bidx]=(this._bits[bidx]&(~(0x01<<sidx)))|(i_value<<sidx);\r
+ }\r
+ return;\r
+ }\r
+ \r
+ public void setBit(int i_bit_no,int i_value)\r
+ {\r
+ assert i_value==0 || i_value==1;\r
+ if(i_bit_no==0){\r
+ this._bits[0]=i_value;\r
+ }else{\r
+ int bidx=(i_bit_no-1)/8+1;\r
+ int sidx=(i_bit_no-1)%8;\r
+ this._bits[bidx]=(this._bits[bidx]&(~(0x01<<sidx)))|(i_value<<sidx);\r
+ }\r
+ return;\r
+ }\r
+ public int getBit(int i_bit_no)\r
+ {\r
+ if(i_bit_no==0){\r
+ return this._bits[0];\r
+ }else{\r
+ int bidx=(i_bit_no-1)/8+1;\r
+ int sidx=(i_bit_no-1)%8;\r
+ return (this._bits[bidx]>>(sidx))&(0x01);\r
+ }\r
+ }\r
+ public boolean initEncoder(int i_model)\r
+ {\r
+ if(i_model>=4 || i_model<2){\r
+ //Lv4以降に対応する時は、この制限を変える。\r
+ return false;\r
+ }\r
+ this._bit_table=_bit_tables[i_model-2];\r
+ this._model=i_model;\r
+ return true;\r
+ }\r
+ private int getDirection()\r
+ {\r
+ int l,t,r,b;\r
+ switch(this._model){\r
+ case 2:\r
+ //トラッキングセルを得る\r
+ t=this._bits[2] & 0x07;\r
+ r=(this._bits[2] & 0x70)>>4;\r
+ b=this._bits[3] & 0x07;\r
+ l=(this._bits[3] & 0x70)>>4;\r
+ break;\r
+ case 3:\r
+ default:\r
+ return -3;\r
+ }\r
+ //101であるかを確認\r
+ if(t==0x05){\r
+ if(r==0x05){\r
+ return (b!=0x05 && l!=0x05)?2:-2;\r
+ }else if(l==0x05){\r
+ return (b!=0x05 && r!=0x05)?3:-2;\r
+ }\r
+ }else if(b==0x05){\r
+ if(r==0x05){\r
+ return (t!=0x05 && l!=0x05)?1:-2;\r
+ }else if(l==0x05){\r
+ return (t!=0x05 && r!=0x05)?0:-2;\r
+ }\r
+ }\r
+ return -1;\r
+ }\r
+\r
+ public boolean encode()\r
+ {\r
+ int d=getDirection();\r
+ if(d<0){\r
+ return false;\r
+ }\r
+ //回転操作\r
+ \r
+ rotateDirection(d);\r
+ //デコード\r
+ \r
+ return true;\r
+ }\r
+ private void rotateDirection(int i_direction)\r
+ {\r
+ int sl=i_direction*2;\r
+ int sr=8-sl;\r
+\r
+ int w1;\r
+ //RECT1\r
+ w1=this._bits[1];\r
+ this._bits[1]=(w1<<sl)|(w1>>sr);\r
+ \r
+ //RECT2\r
+ sl=i_direction*4;\r
+ sr=16-sl;\r
+ w1=this._bits[2]|(this._bits[3]<<8);\r
+ w1=(w1<<sl)|(w1>>sr);\r
+ this._bits[2]=w1 & 0xff;\r
+ this._bits[3]=(w1>>8) & 0xff;\r
+\r
+ if(this._model<2){\r
+ return;\r
+ }\r
+\r
+ //RECT3\r
+ sl=i_direction*6;\r
+ sr=24-sl; \r
+ w1=this._bits[4]|(this._bits[5]<<8)|(this._bits[6]<<16);\r
+ w1=(w1<<sl)|(w1>>sr);\r
+ this._bits[4]=w1 & 0xff;\r
+ this._bits[5]=(w1>>8) & 0xff;\r
+ this._bits[6]=(w1>>16) & 0xff;\r
+ \r
+ if(this._model<3){\r
+ return;\r
+ }\r
+ //RECT4(Lv4以降はここの制限を変える)\r
+// shiftLeft(this._bits,7,3,i_direction*);\r
+\r
+ return;\r
+ }\r
+ public void shiftLeft(int[] i_pack,int i_start,int i_length,int i_ls)\r
+ {\r
+ int[] work=this._work;\r
+ //端数シフト\r
+ final int mod_shift=i_ls%8;\r
+ for(int i=i_length-1;i>=1;i--){\r
+ work[i]=(i_pack[i+i_start]<<mod_shift)|(0xff&(i_pack[i+i_start-1]>>(8-mod_shift)));\r
+ }\r
+ work[0]=(i_pack[i_start]<<mod_shift)|(0xff&(i_pack[i_start+i_length-1]>>(8-mod_shift)));\r
+ //バイトシフト\r
+ final int byte_shift=(i_ls/8)%i_length;\r
+ for(int i=i_length-1;i>=0;i--){\r
+ i_pack[(byte_shift+i)%i_length+i_start]=0xff & work[i];\r
+ }\r
+ return;\r
+ }\r
+\r
+ \r
+}\r
+\r
+\r
+/**\r
+ * NyARColorPatt_NyIdMarkerがラスタからPerspective変換して読みだすためのクラス\r
+ *\r
+ */\r
+class PerspectivePixelReader2 extends NyARPerspectiveParamGenerator_O1\r
+{\r
+ private double[] _cparam=new double[8];\r
+\r
+ public PerspectivePixelReader2(int i_local_x,int i_local_y,int i_width, int i_height)\r
+ {\r
+ super(i_local_x,i_local_y,i_width,i_height);\r
+ this._temp1=new int[i_width];\r
+ this._temp2=new int[i_width];\r
+ this._pixcel_temp=new int[i_width*3];\r
+\r
+ return;\r
+ }\r
+ private int[] _temp1;\r
+ private int[] _temp2;\r
+ private int[] _pixcel_temp;\r
+ private INyARRgbRaster _raster;\r
+ public void setSourceRaster(INyARRgbRaster i_raster)\r
+ {\r
+ this._raster=i_raster;\r
+ return;\r
+ }\r
+ public boolean setSourceSquare(NyARIntPoint2d[] i_vertex)throws NyARException\r
+ {\r
+ return this.getParam(i_vertex, this._cparam);\r
+ }\r
+ public void rectPixels(int i_lt_x,int i_lt_y,int i_width,int i_height,int[] o_pixcel)throws NyARException\r
+ {\r
+ final double[] cpara=this._cparam;\r
+ final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+ final int[] ref_x=this._temp1;\r
+ final int[] ref_y=this._temp2;\r
+ final int[] pixcel_temp=this._pixcel_temp;\r
+ int out_index=0;\r
+\r
+ for(int i=0;i<i_height;i++){\r
+ //1列分のピクセルのインデックス値を計算する。\r
+ int cy0=1+i+i_lt_y;\r
+ double cpy0_12=cpara[1]*cy0+cpara[2];\r
+ double cpy0_45=cpara[4]*cy0+cpara[5];\r
+ double cpy0_7=cpara[7]*cy0+1.0; \r
+ int pt=0;\r
+ for(int i2=0;i2<i_width;i2++)\r
+ {\r
+ int cx0=1+i2+i_lt_x;\r
+\r
+ double cp6_0=cpara[6]*cx0;\r
+ double cpx0_0=cpara[0]*cx0;\r
+ double cpx3_0=cpara[3]*cx0;\r
+ \r
+ final double d=cp6_0+cpy0_7;\r
+ ref_x[pt]=(int)((cpx0_0+cpy0_12)/d);\r
+ ref_y[pt]=(int)((cpx3_0+cpy0_45)/d);\r
+ pt++;\r
+ }\r
+ //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)\r
+ reader.getPixelSet(ref_x,ref_y,i_width,pixcel_temp);\r
+ //グレースケールにしながら、line→mapへの転写\r
+ for(int i2=0;i2<i_width;i2++){\r
+ int index=i2*3;\r
+ o_pixcel[out_index]=(pixcel_temp[index+0]+pixcel_temp[index+1]+pixcel_temp[index+2])/3;\r
+ out_index++;\r
+ } \r
+ }\r
+ return;\r
+ }\r
+\r
+\r
+ \r
+ \r
+ //タイミングパターン用のパラメタ(FRQ_POINTS*FRQ_STEPが100を超えないようにすること)\r
+ private static int FRQ_STEP=2;\r
+ private static int FRQ_POINTS=45;\r
+ public static int FRQ_EDGE=5;\r
+\r
+ \r
+ /**\r
+ * i_y1行目とi_y2行目を平均して、タイミングパターンの周波数を得ます。\r
+ * LHLを1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを\r
+ * 検出した場合、関数は失敗します。\r
+ * \r
+ * @param i_y1\r
+ * @param i_y2\r
+ * @param i_th_h\r
+ * @param i_th_l\r
+ * @param o_edge_index\r
+ * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列です。\r
+ * [FRQ_POINTS]以上の配列を指定してください。\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public int getRowFrequency(int i_y1,int i_th_h,int i_th_l,int[] o_edge_index)throws NyARException\r
+ {\r
+ final double[] cpara=this._cparam;\r
+ final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+ final int[] ref_x=this._temp1;\r
+ final int[] ref_y=this._temp2;\r
+ final int[] pixcel_temp=this._pixcel_temp;\r
+\r
+ //2行分のピクセルインデックスを計算\r
+ int cy0=1+i_y1;\r
+ double cpy0_12=cpara[1]*cy0+cpara[2];\r
+ double cpy0_45=cpara[4]*cy0+cpara[5];\r
+ double cpy0_7=cpara[7]*cy0+1.0; \r
+\r
+\r
+ int pt=0;\r
+ for(int i2=0;i2<FRQ_POINTS;i2++)\r
+ {\r
+ double d;\r
+ final int cx0=1+i2*FRQ_STEP+FRQ_EDGE; \r
+ d=(cpara[6]*cx0)+cpy0_7;\r
+ ref_x[pt]=(int)((cpara[0]*cx0+cpy0_12)/d);\r
+ ref_y[pt]=(int)((cpara[3]*cx0+cpy0_45)/d);\r
+ pt++;\r
+ }\r
+ \r
+ //ピクセルを取得(入力画像を多様化するならここから先を調整すること)\r
+ reader.getPixelSet(ref_x,ref_y,FRQ_POINTS,pixcel_temp);\r
+ return getFreqInfo(pixcel_temp,i_th_h,i_th_l,o_edge_index);\r
+ }\r
+ public int getColFrequency(int i_x1,int i_th_h,int i_th_l,int[] o_edge_index)throws NyARException\r
+ {\r
+ final double[] cpara=this._cparam;\r
+ final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+ final int[] ref_x=this._temp1;\r
+ final int[] ref_y=this._temp2;\r
+ final int[] pixcel_temp=this._pixcel_temp;\r
+\r
+ final int cx0=1+i_x1;\r
+ final double cp6_0=cpara[6]*cx0;\r
+ final double cpx0_0=cpara[0]*cx0;\r
+ final double cpx3_0=cpara[3]*cx0;\r
+\r
+ int pt=0;\r
+ for(int i2=0;i2<FRQ_POINTS;i2++)\r
+ {\r
+ double d;\r
+ int cy=1+i2*FRQ_STEP+FRQ_EDGE;\r
+ double cpy_12=cpara[1]*cy+cpara[2];\r
+ double cpy_45=cpara[4]*cy+cpara[5];\r
+ double cpy_7=cpara[7]*cy+1.0; \r
+ \r
+ d=cp6_0+cpy_7;\r
+ ref_x[pt]=(int)((cpx0_0+cpy_12)/d);\r
+ ref_y[pt]=(int)((cpx3_0+cpy_45)/d);\r
+ pt++;\r
+ \r
+ } \r
+ \r
+ //ピクセルを取得(入力画像を多様化するならここから先を調整すること)\r
+ reader.getPixelSet(ref_x,ref_y,FRQ_POINTS,pixcel_temp);\r
+ return getFreqInfo(pixcel_temp,i_th_h,i_th_l,o_edge_index);\r
+ }\r
+\r
+ /**\r
+ * デバックすんだらstaticにしておk\r
+ * @param i_pixcels\r
+ * @param i_th_h\r
+ * @param i_th_l\r
+ * @param o_edge_index\r
+ * @return\r
+ */\r
+ private int getFreqInfo(int[] i_pixcels,int i_th_h,int i_th_l,int[] o_edge_index)\r
+ {\r
+ //トークンを解析して、周波数を計算\r
+ int i=0;\r
+ int frq_l2h=0;\r
+ int frq_h2l=0;\r
+ while(i<FRQ_POINTS){\r
+ //L->Hトークンを検出する\r
+ while(i<FRQ_POINTS){\r
+ final int index=i*3;\r
+ final int pix=(i_pixcels[index+0]+i_pixcels[index+1]+i_pixcels[index+2])/3;\r
+ if(pix>i_th_h){\r
+ //トークン発見\r
+ o_edge_index[frq_l2h+frq_h2l]=i;\r
+ frq_l2h++;\r
+ break;\r
+ }\r
+ i++;\r
+ }\r
+ i++;\r
+ //L->Hトークンを検出する\r
+ while(i<FRQ_POINTS){\r
+ final int index=i*3;\r
+ final int pix=(i_pixcels[index+0]+i_pixcels[index+1]+i_pixcels[index+2])/3;\r
+ if(pix<=i_th_l){\r
+ //トークン発見\r
+ o_edge_index[frq_l2h+frq_h2l]=i;\r
+ frq_h2l++;\r
+ break;\r
+ }\r
+ i++;\r
+ }\r
+ i++;\r
+ }\r
+ return frq_l2h==frq_h2l?frq_l2h:-1; \r
+ }\r
+\r
+\r
+\r
+ public boolean readDataBits(double[] i_index_x,double[] i_index_y,int i_size,int i_th,MarkerPattEncoder o_bitbuffer)throws NyARException\r
+ {\r
+ \r
+ assert i_size*4<this._width;\r
+ \r
+ final double[] cpara=this._cparam;\r
+\r
+ final int[] ref_x=this._temp1;\r
+ final int[] ref_y=this._temp2;\r
+ final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+ final int[] pixcel_temp=this._pixcel_temp;\r
+ \r
+ int p=0;\r
+ for(int i=0;i<i_size;i++){\r
+ //1列分のピクセルのインデックス値を計算する。\r
+ double cy0=1+i_index_y[i*2+0];\r
+ double cy1=1+i_index_y[i*2+1]; \r
+ double cpy0_12=cpara[1]*cy0+cpara[2];\r
+ double cpy0_45=cpara[4]*cy0+cpara[5];\r
+ double cpy0_7=cpara[7]*cy0+1.0;\r
+ double cpy1_12=cpara[1]*cy1+cpara[2];\r
+ double cpy1_45=cpara[4]*cy1+cpara[5];\r
+ double cpy1_7=cpara[7]*cy1+1.0;\r
+ \r
+ int pt=0;\r
+ for(int i2=0;i2<i_size;i2++)\r
+ { \r
+\r
+ double d;\r
+ double cx0=1+i_index_x[i2*2+0];\r
+ double cx1=1+i_index_x[i2*2+1];\r
+\r
+ double cp6_0=cpara[6]*cx0;\r
+ double cp6_1=cpara[6]*cx1;\r
+ double cpx0_0=cpara[0]*cx0;\r
+ double cpx3_0=cpara[3]*cx0;\r
+ \r
+ d=cp6_0+cpy0_7;\r
+ ref_x[pt]=(int)((cpx0_0+cpy0_12)/d);\r
+ ref_y[pt]=(int)((cpx3_0+cpy0_45)/d);\r
+ pt++;\r
+\r
+ d=cp6_0+cpy1_7;\r
+ ref_x[pt]=(int)((cpx0_0+cpy1_12)/d);\r
+ ref_y[pt]=(int)((cpx3_0+cpy1_45)/d);\r
+ pt++;\r
+\r
+ d=cp6_1+cpy0_7;\r
+ ref_x[pt]=(int)((cpara[0]*cx1+cpy0_12)/d);\r
+ ref_y[pt]=(int)((cpara[3]*cx1+cpy0_45)/d);\r
+ pt++;\r
+\r
+ d=cp6_1+cpy1_7;\r
+ ref_x[pt]=(int)((cpara[0]*cx1+cpy1_12)/d);\r
+ ref_y[pt]=(int)((cpara[3]*cx1+cpy1_45)/d);\r
+ pt++;\r
+ }\r
+ //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)\r
+ reader.getPixelSet(ref_x,ref_y,i_size*4,pixcel_temp);\r
+ //グレースケールにしながら、line→mapへの転写\r
+ for(int i2=0;i2<i_size;i2++){\r
+ int index=i2*3*4;\r
+ int pixel=( pixcel_temp[index+0]+pixcel_temp[index+1]+pixcel_temp[index+2]+\r
+ pixcel_temp[index+3]+pixcel_temp[index+4]+pixcel_temp[index+5]+\r
+ pixcel_temp[index+6]+pixcel_temp[index+7]+pixcel_temp[index+8]+\r
+ pixcel_temp[index+9]+pixcel_temp[index+10]+pixcel_temp[index+11])/(4*3);\r
+ o_bitbuffer.setBitByBitIndex(p,pixel>i_th?1:0);\r
+ p++;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+ \r
+ public boolean setSquare(NyARIntPoint2d[] i_vertex) throws NyARException\r
+ {\r
+ if (!getParam(i_vertex,this._cparam)) {\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+}\r
+\r
+/**\r
+ * 遠近法を使ったパースペクティブ補正付きのINyARColorPatt\r
+ *\r
+ */\r
+public class CopyOfNyARColorPatt_NyIdMarker implements INyARColorPatt\r
+{\r
+ private int[] _patdata;\r
+ private NyARBufferReader _buf_reader;\r
+ private NyARRgbPixelReader_INT1D_GLAY_8 _pixelreader;\r
+ private NyARIntSize _size;\r
+ PerspectivePixelReader2 _perspective_gen;\r
+ private static final int LOCAL_LT=1;\r
+ /**\r
+ * 例えば、64\r
+ * @param i_width\r
+ * 取得画像の解像度幅\r
+ * @param i_height\r
+ * 取得画像の解像度高さ\r
+ * @param i_edge_percentage\r
+ * エッジ幅の割合(ARToolKit標準と同じなら、25)\r
+ */\r
+ public CopyOfNyARColorPatt_NyIdMarker(int i_model)\r
+ {\r
+ //入力制限\r
+ assert i_model==2;\r
+ int resolution=i_model*2+1;\r
+ this._size=new NyARIntSize(resolution,resolution);\r
+ this._patdata = new int[resolution*resolution];\r
+ this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_GLAY_8);\r
+ this._pixelreader=new NyARRgbPixelReader_INT1D_GLAY_8(this._patdata,this._size);\r
+ this._perspective_gen=new PerspectivePixelReader2(LOCAL_LT,LOCAL_LT,100,100);\r
+ return;\r
+ } \r
+ \r
+ public final int getWidth()\r
+ {\r
+ return this._size.w;\r
+ }\r
+ public final int getHeight()\r
+ {\r
+ return this._size.h;\r
+ }\r
+ public final NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ }\r
+ public final INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buf_reader;\r
+ }\r
+ public final INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._pixelreader;\r
+ }\r
+ \r
+\r
+ public int[] vertex_x=new int[49*4];\r
+ public int[] vertex_y=new int[49*4];\r
+ public int[] vertex2_x=new int[400];\r
+ public int[] vertex2_y=new int[400];\r
+ public int[] line1=new int[45];\r
+ public int[] line2=new int[45];\r
+ public int[] sv=new int[4];\r
+ private int[] temp_pixcel=new int[144];\r
+// private NyARSingleEdgeFinder _edge_finder=new NyARSingleEdgeFinder(12,12);\r
+\r
+\r
+ /**\r
+ * マーカパラメータを格納する構造体\r
+ */\r
+ private class TMarkerParam{\r
+ int threshold;\r
+ int model;\r
+ private double[] index_x=new double[25*2];\r
+ private double[] index_y=new double[25*2];\r
+ }\r
+ /**\r
+ * 周期が等間隔か調べる。\r
+ * 次段半周期が、前段の80%より大きく、120%未満であるものを、等間隔周期であるとみなす。\r
+ * @param i_freq\r
+ * @param i_width\r
+ */\r
+ private boolean checkFreqWidth(int[] i_freq,int i_width)\r
+ {\r
+ int c=i_freq[1]-i_freq[0];\r
+ for(int i=1;i<i_width*2-1;i++){\r
+ final int n=i_freq[i+1]-i_freq[i];\r
+ final int v=n*100/c;\r
+ if(v>150 || v<50){\r
+ return false;\r
+ }\r
+ c=n;\r
+ }\r
+ return true;\r
+ }\r
+ private static int MIN_FREQ=3;\r
+ private static int MAX_FREQ=10;\r
+ \r
+ private int getRowFreq(int i_y,int i_th_h,int i_th_l,int[] o_freq_index)throws NyARException\r
+ {\r
+ //3,4,5,6,7,8,9,10\r
+ int freq_index1[]=new int[45];\r
+ int freq_count_table[]=new int[10];\r
+ //0,2,4,6,8,10,12,14,16,18,20の要素を持つ配列\r
+ int freq_table[][]=new int[10][20];\r
+ //初期化\r
+ \r
+ //10-20ピクセル目からタイミングパターンを検出\r
+ for(int i=i_y;i<i_y+10;i++){\r
+ final int freq_t=this._perspective_gen.getRowFrequency(i,i_th_h,i_th_l,freq_index1);\r
+ //周期は3-10であること\r
+ if(freq_t<MIN_FREQ || freq_t>MAX_FREQ){\r
+ continue;\r
+ }\r
+ //周期は等間隔であること\r
+ if(!checkFreqWidth(freq_index1,freq_t)){\r
+ continue;\r
+ }\r
+ //検出カウンタを追加\r
+ freq_count_table[freq_t]++;\r
+ for(int i2=0;i2<freq_t*2;i2++){\r
+ freq_table[freq_t][i2]+=freq_index1[i2];\r
+ }\r
+ }\r
+ //一番成分の大きいものを得る\r
+ int index=-1;\r
+ int max=0;\r
+ for(int i=0;i<MAX_FREQ;i++){\r
+ if(max<freq_count_table[i]){\r
+ index=i;\r
+ max=freq_count_table[i];\r
+ }\r
+ }\r
+ /*周波数インデクスを計算*/\r
+ for(int i=0;i<index*2;i++)\r
+ {\r
+ o_freq_index[i]=freq_table[index][i]/max;\r
+ }\r
+ return index;\r
+ }\r
+ private int getColFreq(int i_y,int i_th_h,int i_th_l,int[] o_freq_index)throws NyARException\r
+ {\r
+ //3,4,5,6,7,8,9,10\r
+ int freq_index1[]=new int[45];\r
+ int freq_count_table[]=new int[10];\r
+ int freq_table[][]=new int[10][20];\r
+ //初期化\r
+ \r
+ //10-20ピクセル目からタイミングパターンを検出\r
+ for(int i=i_y;i<i_y+10;i++){\r
+ final int freq_t=this._perspective_gen.getColFrequency(i,i_th_h,i_th_l,freq_index1);\r
+ //周期は3-10であること\r
+ if(freq_t<MIN_FREQ || freq_t>MAX_FREQ){\r
+ continue;\r
+ }\r
+ //周期は等間隔であること\r
+ if(!checkFreqWidth(freq_index1,freq_t)){\r
+ continue;\r
+ }\r
+ //検出カウンタを追加\r
+ freq_count_table[freq_t]++;\r
+ for(int i2=0;i2<freq_t*2;i2++){\r
+ freq_table[freq_t][i2]+=freq_index1[i2];\r
+ }\r
+ }\r
+ //一番成分の大きいものを得る\r
+ int index=-1;\r
+ int max=0;\r
+ for(int i=0;i<MAX_FREQ;i++){\r
+ if(max<freq_count_table[i]){\r
+ index=i;\r
+ max=freq_count_table[i];\r
+ }\r
+ }\r
+ for(int i=0;i<10;i++){\r
+ System.out.print(freq_count_table[i]+",");\r
+ }\r
+ System.out.println();\r
+ if(index==-1){\r
+ return -1;\r
+ }\r
+ /*周波数インデクスを計算*/\r
+ for(int i=0;i<index*2;i++)\r
+ {\r
+ o_freq_index[i]=freq_table[index][i]/max;\r
+ }\r
+ return index;\r
+ }\r
+ private boolean detectMarkerParam(INyARRgbPixelReader i_reader,TMarkerParam o_param)throws NyARException\r
+ {\r
+ TThreshold th=new TThreshold();\r
+ \r
+ detectThresholdValue(i_reader,10,10,th);\r
+ //周波数測定(最も正しい周波数を検出する)\r
+\r
+ \r
+\r
+\r
+ //左上,右下から、12x12(抽出範囲は10x10)の調査用矩形を抽出\r
+\r
+\r
+ \r
+ //周波数を測定\r
+ int freq_index1[]=new int[45];\r
+ int freq_index2[]=new int[45];\r
+ int frq_t=getRowFreq(10,th.th_h,th.th_l,freq_index1);\r
+ int frq_b=getRowFreq(80,th.th_h,th.th_l,freq_index2);\r
+ //周波数はまとも?\r
+ if((frq_t<0 && frq_b<0) || frq_t==frq_b){\r
+ System.out.print("FRQ_R");\r
+ return false;\r
+ }\r
+ //タイミングパターンからインデクスを作成\r
+ int freq;\r
+ int[] index;\r
+ if(frq_t>frq_b){\r
+ freq=frq_t;\r
+ index=freq_index1;\r
+ }else{\r
+ freq=frq_b;\r
+ index=freq_index2;\r
+ }\r
+ for(int i=0;i<freq*2-1;i++){\r
+ o_param.index_x[i*2]=((index[i+1]-index[i])*2/5+index[i])*2+PerspectivePixelReader.FRQ_EDGE;\r
+ o_param.index_x[i*2+1]=((index[i+1]-index[i])*3/5+index[i])*2+PerspectivePixelReader.FRQ_EDGE;\r
+ }\r
+ int frq_l=getColFreq(10,th.th_h,th.th_l,freq_index1);\r
+ int frq_r=getColFreq(80,th.th_h,th.th_l,freq_index2); \r
+ //周波数はまとも?\r
+ if((frq_l<0 && frq_r<0) || frq_l==frq_r){\r
+ System.out.print("FRQ_C");\r
+ return false;\r
+ }\r
+ //タイミングパターンからインデクスを作成\r
+ if(frq_l>frq_r){\r
+ freq=frq_l;\r
+ index=freq_index1;\r
+ }else{\r
+ freq=frq_r;\r
+ index=freq_index2;\r
+ }\r
+ for(int i=0;i<freq*2-1;i++){\r
+ o_param.index_y[i*2]=((index[i+1]-index[i])*2/5+index[i])*2+PerspectivePixelReader.FRQ_EDGE;\r
+ o_param.index_y[i*2+1]=((index[i+1]-index[i])*3/5+index[i])*2+PerspectivePixelReader.FRQ_EDGE;\r
+ }\r
+\r
+ \r
+ \r
+ //Lv4以上は無理\r
+ if(freq>4){\r
+ System.out.print("LVL_4");\r
+ return false;\r
+ }\r
+ o_param.model=freq-1;\r
+ o_param.threshold=th.th;\r
+ return true;\r
+ \r
+ }\r
+ private class TThreshold{\r
+ public int th_h;\r
+ public int th_l;\r
+ public int th;\r
+ }\r
+ /**\r
+ * 指定した場所のピクセル値を調査して、閾値を計算して返します。\r
+ * @param i_reader\r
+ * @param i_x\r
+ * @param i_y\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ private void detectThresholdValue(INyARRgbPixelReader i_reader,int i_x,int i_y,TThreshold o_threshold)throws NyARException\r
+ {\r
+ final int[] temp_pixel=this.temp_pixcel;\r
+ //特定エリアから画素を得る\r
+ this._perspective_gen.rectPixels(i_x,i_y,10,10,temp_pixel);\r
+ //ソート\r
+ int len=100;\r
+ int h = len *13/10;\r
+ for(;;){\r
+ int swaps = 0;\r
+ for (int i = 0; i + h < len; i++) {\r
+ if (temp_pixel[i + h] > temp_pixel[i]) {\r
+ final int temp = temp_pixel[i + h];\r
+ temp_pixel[i + h] = temp_pixel[i];\r
+ temp_pixel[i] = temp;\r
+ swaps++;\r
+ }\r
+ }\r
+ if (h == 1) {\r
+ if (swaps == 0){\r
+ break;\r
+ }\r
+ }else{\r
+ h=h*10/13;\r
+ }\r
+ }\r
+ //値の大きい方と小さい方の各4点を取得\r
+ //4点の中間を閾値中心とする\r
+ final int th_l=temp_pixel[99]+temp_pixel[98]+temp_pixel[97]+temp_pixel[96];\r
+ final int th_h=temp_pixel[0]+temp_pixel[1]+temp_pixel[2]+temp_pixel[3];\r
+ int th_sub=(th_h-th_l)/(4*5);//ヒステリシス(20%)\r
+ int th=(th_h+th_l)/8;\r
+ o_threshold.th=th;\r
+ o_threshold.th_h=th+th_sub;//ヒステリシス付き閾値\r
+ o_threshold.th_l=th-th_sub;//ヒステリシス付き閾値\r
+ System.out.println(o_threshold.th+","+o_threshold.th_h+","+o_threshold.th_l);\r
+ return;\r
+ } \r
+ \r
+\r
+ /**\r
+ * \r
+ * @param image\r
+ * @param i_marker\r
+ * @return 切り出しに失敗した\r
+ * @throws Exception\r
+ */\r
+ public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
+ {\r
+ this._perspective_gen.setSourceRaster(image);\r
+ i_square.imvertex[0].x=149;\r
+ i_square.imvertex[0].y=179;\r
+ i_square.imvertex[0].x=27;\r
+ i_square.imvertex[0].y=96;\r
+ i_square.imvertex[0].x=152;\r
+ i_square.imvertex[0].y=29;\r
+ i_square.imvertex[0].x=280;\r
+ i_square.imvertex[0].y=72;\r
+ \r
+ //遠近法のパラメータを計算\r
+ if(!this._perspective_gen.setSourceSquare(i_square.imvertex)){\r
+ return false;\r
+ };\r
+ \r
+ final INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+\r
+\r
+ TMarkerParam param=new TMarkerParam();\r
+ MarkerPattEncoder encoder=new MarkerPattEncoder();\r
+ //マーカパラメータを取得\r
+ if(!detectMarkerParam(reader,param))\r
+ {\r
+ System.out.println("E");\r
+ return false;\r
+ } \r
+ final int resolution=(param.model*2)+1;\r
+ //Threshold検出\r
+\r
+ if(!encoder.initEncoder(param.model)){\r
+ return false;\r
+ }\r
+ //int i_stx,int i_sty,int size_x,int size_y,int i_resolution,int i_th,\r
+ //this._perspective_gen.readDataBits(st_x,st_y,size_x,size_y,resolution, param.threshold, encoder);\r
+ this._perspective_gen.readDataBits(param.index_x,param.index_y,resolution, param.threshold, encoder);\r
+ encoder.encode();\r
+\r
+ for(int i=0;i<49*4;i++){\r
+ this.vertex_x[i]=0;\r
+ this.vertex_y[i]=0;\r
+ }\r
+ for(int i=0;i<resolution*2;i++){\r
+ for(int i2=0;i2<resolution*2;i2++){\r
+ this.vertex_x[i*resolution*2+i2]=(int)param.index_x[i2];\r
+ this.vertex_y[i*resolution*2+i2]=(int)param.index_y[i];\r
+ \r
+ }\r
+ }\r
+\r
+ System.out.println(param.model);\r
+/*\r
+ //マップを作りなおす\r
+ for(int i=0;i<size*size;i++){\r
+ this._patdata[i]=encoder.getBit(_role_table[i])==0?0:255;\r
+ }\r
+*/ \r
+ \r
+ \r
+ return true;\r
+ }\r
+ public static void main(String[] args)\r
+ {\r
+ try {\r
+ double[] a=new double[10];\r
+ int[] d={\r
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9\r
+ 0,0,0,0,0,0,0,1,5,1,2,0,0,0,1,2,5,2,1,0,\r
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\r
+ NyARSingleEdgeFinder px=new NyARSingleEdgeFinder(20,2);\r
+ System.out.print(px.scanEdgeLeftToRight(d,0,0,a));\r
+ System.out.print("");\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ } \r
+}
\ No newline at end of file
}
final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;
- final NyARIntPoint[] l_imvertex = o_square.imvertex;
+ final NyARIntPoint2d[] 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];
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\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.dev;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+\r
+\r
+class NyARDoubleLine2d\r
+{\r
+ double x,y;\r
+ void set(NyARDoublePoint2d i_point_a,NyARDoublePoint2d i_point_b)\r
+ {\r
+ this.x=i_point_a.x-i_point_b.x;\r
+ this.y=i_point_a.y-i_point_b.y;\r
+ return;\r
+ }\r
+ void add(NyARDoubleLine2d i_param,NyARDoubleLine2d o_result)\r
+ {\r
+ o_result.x=this.x+i_param.x;\r
+ o_result.y=this.y+i_param.y;\r
+ return;\r
+ }\r
+ void sum(NyARDoubleLine2d i_param,NyARDoubleLine2d o_result)\r
+ {\r
+ o_result.x=this.x-i_param.x;\r
+ o_result.y=this.y-i_param.y;\r
+ return;\r
+ }\r
+ /**\r
+ * i_paramとの外積を計算する。\r
+ * @param i_param\r
+ * @return\r
+ */\r
+ double cross(NyARDoubleLine2d i_param)\r
+ {\r
+ return this.x*i_param.y-this.y*i_param.x;\r
+ }\r
+ /**\r
+ * i_paramとの内積を計算する\r
+ * @param i_param\r
+ * @return\r
+ */\r
+ double dot(NyARDoubleLine2d i_param)\r
+ {\r
+ return this.x*i_param.x+this.y*i_param.y;\r
+ }\r
+ /**\r
+ * このベクトルの絶対値を計算する\r
+ * @param i_param\r
+ * @return\r
+ */\r
+ double dist()\r
+ {\r
+ return Math.sqrt(this.x*this.x+this.y*this.y);\r
+ }\r
+ \r
+ \r
+}\r
+\r
+\r
+class LineParam\r
+{\r
+ public double a;\r
+ public double b;\r
+ public static LineParam[] createArray(int i_length)\r
+ {\r
+ LineParam[] result=new LineParam[i_length];\r
+ for(int i=result.length-1;i>=0;i--){\r
+ result[i]=new LineParam();\r
+ }\r
+ return result;\r
+ }\r
+}\r
+\r
+class Complex\r
+{\r
+ public double i;\r
+ public double r;\r
+ public Complex()\r
+ {\r
+ }\r
+ public Complex(double i_r,double i_i)\r
+ {\r
+ this.r=i_r;\r
+ this.i=i_i;\r
+ }\r
+ public void add(Complex i_v)\r
+ {\r
+ this.r+=i_v.r;\r
+ this.i+=i_v.i;\r
+ }\r
+ public void sub(Complex i_v)\r
+ {\r
+ this.r-=i_v.r;\r
+ this.i-=i_v.i;\r
+ }\r
+ public void sub(Complex i_v1,Complex i_v2)\r
+ {\r
+ this.r=i_v1.r-i_v2.r;\r
+ this.i=i_v1.i-i_v2.i;\r
+ }\r
+ \r
+ public void mul(Complex i_v)\r
+ {\r
+ double r,i;\r
+ r=this.r;\r
+ i=this.i;\r
+ final double d2=Math.sqrt(r*r+i*i);\r
+ final double s2=Math.acos(r/d2);\r
+ r=i_v.r;\r
+ i=i_v.i;\r
+ final double d1=Math.sqrt(r*r+i*i);\r
+ final double s1=Math.acos(r/d1);\r
+ \r
+ this.r=d1*d2*Math.cos(s2+s1);\r
+ this.i=d1*d2*Math.sin(s2+s1);\r
+ return;\r
+ }\r
+ public void div(Complex i_v)\r
+ {\r
+ double r,i;\r
+ r=this.r;\r
+ i=this.i;\r
+ final double d2=Math.sqrt(r*r+i*i);\r
+ final double s2=Math.acos(r/d2);\r
+ r=i_v.r;\r
+ i=i_v.i;\r
+ final double d1=Math.sqrt(r*r+i*i);\r
+ final double s1=Math.acos(r/d1);\r
+ \r
+ this.r=d2/d1*Math.cos(s2/s1);\r
+ this.i=d2/d1*Math.sin(s2/s1);\r
+ return;\r
+ }\r
+ public void pow(Complex i_v,double i_base)\r
+ {\r
+ double r,i;\r
+ r=i_v.r;\r
+ i=i_v.i;\r
+ double d=Math.sqrt(r*r+i*i);\r
+ final double s=Math.acos(r/d)*i_base;\r
+ d=Math.pow(d,i_base);\r
+ this.r=d*Math.cos(s);\r
+ this.i=d*Math.sin(s);\r
+ }\r
+ public void sqrt(Complex i_v)\r
+ {\r
+ double r,i;\r
+ r=i_v.r;\r
+ i=i_v.i;\r
+ double d=Math.sqrt(r*r+i*i);\r
+ final double s=Math.acos(r/d)*0.5;\r
+ d=Math.sqrt(d);\r
+ this.r=d*Math.cos(s);\r
+ this.i=d*Math.sin(s);\r
+ }\r
+ public double dist()\r
+ {\r
+ return Math.sqrt(this.r*this.r+this.i*this.i);\r
+ }\r
+ \r
+}\r
+\r
+\r
+/**\r
+ * 24ビットカラーのマーカーを保持するために使うクラスです。 このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。\r
+ * 演算順序を含む最適化をしたもの\r
+ * \r
+ */\r
+public class NyARColorPatt_DiagonalRatio implements INyARColorPatt\r
+{\r
+ private int[] _patdata;\r
+ private NyARBufferReader _buf_reader;\r
+ private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+ private NyARIntSize _size;\r
+ \r
+ public final int getWidth()\r
+ {\r
+ return this._size.w;\r
+ }\r
+ \r
+ public final int getHeight()\r
+ {\r
+ return this._size.h;\r
+ }\r
+ \r
+ public final NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ }\r
+ \r
+ public final INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buf_reader;\r
+ }\r
+ \r
+ public final INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._pixelreader;\r
+ }\r
+ NyARDoubleMatrix44 _invmat=new NyARDoubleMatrix44();\r
+ /**\r
+ * @param i_width\r
+ * @param i_height\r
+ */\r
+ public NyARColorPatt_DiagonalRatio(int i_model)\r
+ {\r
+ int resolution=(1<<i_model)+1;\r
+ this._size=new NyARIntSize(resolution,resolution);\r
+ this._patdata = new int[resolution*resolution];\r
+ this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+ \r
+ this._vertex_map=NyARDoublePoint2d.create2dArray(this._size.h,this._size.w);\r
+\r
+ return;\r
+ } \r
+ public NyARDoublePoint2d[][] _vertex_map;\r
+ public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
+ {\r
+ NyARDoublePoint2d center=new NyARDoublePoint2d();\r
+ //中心を取得\r
+ solvCrossPoint(i_square.sqvertex[0],i_square.sqvertex[2],i_square.sqvertex[1],i_square.sqvertex[3],center);\r
+ \r
+ int[] rgb_tmp=new int[3];\r
+ INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+ //頂点マトリクスの計算(2=2分割,3=4分割,4=8分割)\r
+ NyARDoublePoint2d[][] vertex_map=this._vertex_map;\r
+ solvLinePointArray(center,this._size.h-1,i_square.sqvertex,vertex_map);\r
+ for(int i=0;i<this._size.h;i++){\r
+ for(int i2=0;i2<this._size.w;i2++){\r
+ if(vertex_map[i][i2].x>320||vertex_map[i][i2].y>240||vertex_map[i][i2].x<0||vertex_map[i][i2].y<0)\r
+ {\r
+ //System.out.println(vertex_map[i][i2].x+","+vertex_map[i][i2].y);\r
+ this._patdata[i2+i*this._size.w]=0;\r
+ continue;\r
+ }\r
+ reader.getPixel((int)vertex_map[i][i2].x,(int)vertex_map[i][i2].y,rgb_tmp);\r
+ this._patdata[i2+i*this._size.w]=(rgb_tmp[0]<<16)|(rgb_tmp[1]<<8)|rgb_tmp[2]; \r
+ } \r
+ }\r
+ return true;\r
+ }\r
+ /**\r
+ * 直線をscaleで2^n分割した配列を計算する。\r
+ * @param i_p1\r
+ * @param i_p2\r
+ * @param o_param\r
+ * @return\r
+ */\r
+ private void solvLinePointArray4(NyARDoublePoint2d i_center,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result)\r
+ {\r
+ //分割直線の計算(2=2分割,3=4分割,4=8分割)\r
+ //中心コピー\r
+ o_result[0][0].setValue(i_center);\r
+ \r
+ \r
+ //[0]->[1]のベクトルを計算\r
+ NyARDoublePoint2d vec01=new NyARDoublePoint2d();\r
+ NyARDoublePoint2d vec12=new NyARDoublePoint2d();\r
+ NyARDoublePoint2d vec03=new NyARDoublePoint2d();\r
+ NyARDoublePoint2d vec32=new NyARDoublePoint2d();\r
+ vec01.vecSub(i_vertex[1],i_vertex[0]);\r
+ vec12.vecSub(i_vertex[2],i_vertex[1]);\r
+ vec03.vecSub(i_vertex[3],i_vertex[0]);\r
+ vec32.vecSub(i_vertex[2],i_vertex[3]);\r
+\r
+ //中心点から[0]->[1]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec01_ep=new NyARDoublePoint2d();\r
+ vec01_ep.vecAdd(vec01,i_center);\r
+ //中心点から[3]->[2]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec32_ep=new NyARDoublePoint2d();\r
+ vec32_ep.vecAdd(vec32,i_center); \r
+ //平均値\r
+ NyARDoublePoint2d cx_e=new NyARDoublePoint2d();\r
+ cx_e.x=(vec01_ep.x+vec32_ep.x)/2;\r
+ cx_e.y=(vec01_ep.y+vec32_ep.y)/2;\r
+ \r
+ //ベクトル[1]->[2]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e,i_vertex[1],i_vertex[2],o_result[1][2]);\r
+ //ベクトル[3]->[0]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e,i_vertex[3],i_vertex[0],o_result[1][0]);\r
+ \r
+\r
+ \r
+ //中心点から[1]->[2]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec12_ep=new NyARDoublePoint2d();\r
+ vec12_ep.vecAdd(vec12,i_center);\r
+ //中心点から[0]->[3]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec03_ep=new NyARDoublePoint2d();\r
+ vec03_ep.vecAdd(vec03,i_center); \r
+ //平均値\r
+ NyARDoublePoint2d cx_e2=new NyARDoublePoint2d();\r
+ cx_e2.x=(vec12_ep.x+vec03_ep.x)/2;\r
+ cx_e2.y=(vec12_ep.y+vec03_ep.y)/2;\r
+ \r
+ //cx_e2とベクトル[0]->[1]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e2,i_vertex[0],i_vertex[1],o_result[0][1]);\r
+ //ベクトル[3]->[2]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e2,i_vertex[3],i_vertex[2],o_result[2][1]);\r
+ \r
+ \r
+ \r
+ \r
+ return;\r
+ }\r
+ private void solvLinePointArray(NyARDoublePoint2d i_center,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result)\r
+ {\r
+ //中心コピー\r
+ o_result[0][0].setValue(i_center);\r
+\r
+ //[0]+[1]+[c]\r
+ NyARDoublePoint2d vt=new NyARDoublePoint2d();\r
+ vt.x=(i_vertex[0].x+i_vertex[1].x)/2;\r
+ vt.y=(i_vertex[0].y+i_vertex[1].y)/2;\r
+ //[2]+[3]+[c]\r
+ NyARDoublePoint2d vb=new NyARDoublePoint2d();\r
+ vb.x=(i_vertex[2].x+i_vertex[3].x)/2;\r
+ vb.y=(i_vertex[2].y+i_vertex[3].y)/2;\r
+ \r
+ vt.vecSub(vb);\r
+ vt.vecAdd(i_center);\r
+\r
+ //[0][1]->[2][3]ベクトル\r
+ solvCrossPoint(vt,i_center,i_vertex[0],i_vertex[1],o_result[1][2]);\r
+ //[0][1]->[2][3]ベクトル:v[3][0]\r
+ solvCrossPoint(vt,i_center,i_vertex[3],i_vertex[2],o_result[1][0]);\r
+\r
+ \r
+ \r
+/* \r
+ \r
+ //[0]->[1]のベクトルを計算\r
+ NyARDoublePoint2d vec01=new NyARDoublePoint2d();\r
+ NyARDoublePoint2d vec12=new NyARDoublePoint2d();\r
+ NyARDoublePoint2d vec03=new NyARDoublePoint2d();\r
+ NyARDoublePoint2d vec32=new NyARDoublePoint2d();\r
+ vec01.vecSub(i_vertex[1],i_vertex[0]);\r
+ vec12.vecSub(i_vertex[2],i_vertex[1]);\r
+ vec03.vecSub(i_vertex[3],i_vertex[0]);\r
+ vec32.vecSub(i_vertex[2],i_vertex[3]);\r
+\r
+ //中心点から[0]->[1]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec01_ep=new NyARDoublePoint2d();\r
+ vec01_ep.vecSum(vec01,i_center);\r
+ //中心点から[3]->[2]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec32_ep=new NyARDoublePoint2d();\r
+ vec32_ep.vecSum(vec32,i_center); \r
+ //平均値\r
+ NyARDoublePoint2d cx_e=new NyARDoublePoint2d();\r
+ cx_e.x=(vec01_ep.x+vec32_ep.x)/2;\r
+ cx_e.y=(vec01_ep.y+vec32_ep.y)/2;\r
+ \r
+ //ベクトル[1]->[2]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e,i_vertex[1],i_vertex[2],o_result[1][2]);\r
+ //ベクトル[3]->[0]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e,i_vertex[3],i_vertex[0],o_result[1][0]);\r
+ \r
+\r
+ \r
+ //中心点から[1]->[2]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec12_ep=new NyARDoublePoint2d();\r
+ vec12_ep.vecSum(vec12,i_center);\r
+ //中心点から[0]->[3]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec03_ep=new NyARDoublePoint2d();\r
+ vec03_ep.vecSum(vec03,i_center); \r
+ //平均値\r
+ NyARDoublePoint2d cx_e2=new NyARDoublePoint2d();\r
+ cx_e2.x=(vec12_ep.x+vec03_ep.x)/2;\r
+ cx_e2.y=(vec12_ep.y+vec03_ep.y)/2;\r
+ \r
+ //cx_e2とベクトル[0]->[1]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e2,i_vertex[0],i_vertex[1],o_result[0][1]);\r
+ //ベクトル[3]->[2]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e2,i_vertex[3],i_vertex[2],o_result[2][1]);\r
+ \r
+ \r
+*/ \r
+ \r
+ return;\r
+ }\r
+ \r
+ \r
+ \r
+ private void solvLinePointArray3(NyARDoublePoint2d i_canter,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result)\r
+ {\r
+ NyARDoublePoint2d scale=new NyARDoublePoint2d();\r
+ //分割直線の計算(2=2分割,3=4分割,4=8分割)\r
+ int d=i_div;\r
+ NyARDoublePoint2d[] r=o_result[d/2];\r
+ //対角線Aを計算\r
+ r[0].x=i_vertex[0].x;\r
+ r[0].y=i_vertex[0].y;\r
+ r[d].x=i_vertex[2].x;\r
+ r[d].y=i_vertex[2].y;\r
+ scale.x=(i_canter.x-i_vertex[0].x)/(i_vertex[2].x-i_vertex[0].x);\r
+ scale.y=(i_canter.y-i_vertex[0].y)/(i_vertex[2].y-i_vertex[0].y);\r
+\r
+ solvLinePointArray_b(scale,0,d,r);\r
+ //対角線上にコピー\r
+ for(int i=0;i<=d;i++){\r
+ o_result[i][i].x=r[i].x; \r
+ o_result[i][i].y=r[i].y;\r
+ }\r
+ //対角線Bを計算\r
+ r[0].x=i_vertex[3].x;\r
+ r[0].y=i_vertex[3].y;\r
+ r[d].x=i_vertex[1].x;\r
+ r[d].y=i_vertex[1].y;\r
+ scale.x=(i_canter.x-i_vertex[3].x)/(i_vertex[1].x-i_vertex[3].x);\r
+ scale.y=(i_canter.y-i_vertex[3].y)/(i_vertex[1].y-i_vertex[3].y);\r
+ solvLinePointArray_b(scale,0,d,r);\r
+ //対角線上にコピー\r
+ for(int i=0;i<=d;i++){\r
+ o_result[d-i][i].x=r[i].x;\r
+ o_result[d-i][i].y=r[i].y;\r
+ }\r
+ //マップ作成\r
+ for(int i=0;i<=d;i++){\r
+ final NyARDoublePoint2d y1=o_result[i][i];\r
+ final NyARDoublePoint2d y2=o_result[d-i][i];\r
+ if(i==d/2){\r
+ continue;\r
+ }\r
+ for(int i2=0;i2<=d;i2++){\r
+ if(i==i2){\r
+ continue;\r
+ }\r
+ if(i==d-i2){\r
+ continue;\r
+ }\r
+ if(i2==d/2){\r
+ continue;\r
+ }\r
+ final NyARDoublePoint2d x1=o_result[i2][i2];\r
+ final NyARDoublePoint2d x2=o_result[i2][d-i2];\r
+ solvCrossPoint(y1,y2,x1,x2,o_result[i2][i]);\r
+ }\r
+ }\r
+\r
+ return;\r
+ } \r
+ /**\r
+ * 直線をscaleで2^n分割した配列を計算する。\r
+ * @param i_p1\r
+ * @param i_p2\r
+ * @param o_param\r
+ * @return\r
+ */\r
+ private void solvLinePointArray2(NyARDoublePoint2d i_canter,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result)\r
+ {\r
+ NyARDoublePoint2d scale=new NyARDoublePoint2d();\r
+ //分割直線の計算(2=2分割,3=4分割,4=8分割)\r
+ int d=i_div;\r
+ NyARDoublePoint2d[] r=o_result[d/2];\r
+ //対角線Aを計算\r
+ r[0].x=i_vertex[0].x;\r
+ r[0].y=i_vertex[0].y;\r
+ r[d].x=i_vertex[2].x;\r
+ r[d].y=i_vertex[2].y;\r
+// scale.x=(i_canter.x-i_vertex[0].x)/(i_vertex[2].x-i_vertex[0].x);\r
+// scale.y=(i_canter.y-i_vertex[0].y)/(i_vertex[2].y-i_vertex[0].y);\r
+ double sx,kx,lx,sy,ky,ly;\r
+\r
+ sx=i_vertex[0].x;\r
+ kx=solvK(i_canter.x-sx,i_vertex[2].x-sx);\r
+ lx=solvL(kx,i_canter.x-sx);\r
+\r
+ sy=i_vertex[0].y;\r
+ ky=solvK(i_canter.y-sy,i_vertex[2].y-sy);\r
+ ly=solvL(kx,i_canter.y-sy);\r
+ \r
+ solvLinePointArray_b(scale,0,d,r);\r
+ //対角線上にコピー\r
+ for(int i=0;i<=d;i++){\r
+ o_result[i][i].x=sx+kx*lx;\r
+ o_result[i][i].y=sy+ky*ly;\r
+ kx*=kx;\r
+ ky*=ky;\r
+ }\r
+ \r
+ sx=i_vertex[3].x;\r
+ kx=solvK(i_canter.x-sx,i_vertex[1].x-sx);\r
+ lx=solvL(kx,i_canter.x-sx);\r
+\r
+ sy=i_vertex[3].y;\r
+ ky=solvK(i_canter.y-sy,i_vertex[1].y-sy);\r
+ ly=solvL(kx,i_canter.y-sy);\r
+ \r
+ solvLinePointArray_b(scale,0,d,r);\r
+ //対角線上にコピー\r
+ for(int i=0;i<=d;i++){\r
+ o_result[d-i][i].x=sx+kx*lx;\r
+ o_result[d-i][i].y=sy+ky*ly;\r
+ kx*=kx;\r
+ ky*=ky;\r
+ }\r
+ //マップ作成\r
+ for(int i=0;i<=d;i++){\r
+ final NyARDoublePoint2d y1=o_result[i][i];\r
+ final NyARDoublePoint2d y2=o_result[d-i][i];\r
+ if(i==d/2){\r
+ continue;\r
+ }\r
+ for(int i2=0;i2<=d;i2++){\r
+ if(i==i2){\r
+ continue;\r
+ }\r
+ if(i==d-i2){\r
+ continue;\r
+ }\r
+ if(i2==d/2){\r
+ continue;\r
+ }\r
+ final NyARDoublePoint2d x1=o_result[i2][i2];\r
+ final NyARDoublePoint2d x2=o_result[i2][d-i2];\r
+ solvCrossPoint(y1,y2,x1,x2,o_result[i2][i]);\r
+ }\r
+ }\r
+\r
+ return;\r
+ } \r
+\r
+ private void solvLinePointArray_b(NyARDoublePoint2d i_scale,int i_si,int i_ei,NyARDoublePoint2d[] o_result)\r
+ {\r
+ int ci=(i_ei-i_si)/2+i_si;\r
+ o_result[ci].x=i_scale.x*(o_result[i_ei].x-o_result[i_si].x)+o_result[i_si].x;\r
+ o_result[ci].y=i_scale.y*(o_result[i_ei].y-o_result[i_si].y)+o_result[i_si].y;\r
+ \r
+ if(ci-i_si==1){\r
+ return;\r
+ }\r
+ solvLinePointArray_b(i_scale,i_si,ci,o_result);\r
+ solvLinePointArray_b(i_scale,ci,i_ei,o_result);\r
+ return;\r
+ }\r
+ \r
+ private void solvCrossPoint(NyARIntPoint2d i_p1,NyARIntPoint2d i_p2,NyARIntPoint2d i_p3,NyARIntPoint2d i_p4,NyARDoublePoint2d o_result)\r
+ {\r
+ NyARDoublePoint2d va=new NyARDoublePoint2d(i_p2);\r
+ NyARDoublePoint2d vb=new NyARDoublePoint2d(i_p4);\r
+ va.vecSub(i_p1);\r
+ vb.vecSub(i_p3);\r
+ o_result.setValue(i_p3);\r
+ o_result.vecSub(i_p1);\r
+ va.vecMul(va, vb.vecCross(o_result)/vb.vecCross(va));\r
+ o_result.setValue(va);\r
+ o_result.vecAdd(i_p1);\r
+ return;\r
+ //V a=p2-p1;\r
+ //V b=p4-p3;\r
+ //return a1 + a * cross(b, b1-a1) / cross(b, a);\r
+ }\r
+ private void solvCrossPoint(NyARDoublePoint2d i_p1,NyARDoublePoint2d i_p2,NyARDoublePoint2d i_p3,NyARDoublePoint2d i_p4,NyARDoublePoint2d o_result)\r
+ {\r
+ NyARDoublePoint2d va=new NyARDoublePoint2d(i_p2);\r
+ NyARDoublePoint2d vb=new NyARDoublePoint2d(i_p4);\r
+ va.vecSub(i_p1);\r
+ vb.vecSub(i_p3);\r
+ o_result.setValue(i_p3);\r
+ o_result.vecSub(i_p1);\r
+ va.vecMul(va, vb.vecCross(o_result)/vb.vecCross(va));\r
+ o_result.setValue(va);\r
+ o_result.vecAdd(i_p1);\r
+ return;\r
+ //V a=p2-p1;\r
+ //V b=p4-p3;\r
+ //return a1 + a * cross(b, b1-a1) / cross(b, a);\r
+ } \r
+ double pow_1_3(double a)\r
+ {\r
+ double x = Math.pow(a, 1./3);\r
+ return (2*x+a/x/x)/3; // modifier\r
+ }\r
+ /*\r
+ * \r
+ * \r
+ * */\r
+ //(Sqrt(((3*Z*((-Z)/(3*Z))^2-(2*Z^2)/(3*Z)+Z-1)/Z)^3/27+(Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)^2/(4*Z^2))-(Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)/(2*Z))^(1/3)+(-((Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)/(2*Z)+Sqrt(((3*Z*((-Z)/(3*Z))^2-(2*Z^2)/(3*Z)+Z-1)/Z)^3/27+(Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)^2/(4*Z^2))))^(1/3)-Z/(3*Z)\r
+ private double solvK(double mp,double vp)\r
+ {\r
+ double Z=mp/vp;\r
+ double a=(Z-1);\r
+ double b=(3.0*Z);\r
+ double c=(a*Z);\r
+ double d=(2.0*Z*Z);//(2*Z^2)\r
+ double e=(4.0*Z*Z);//(4*Z^2)\r
+ double f=((-Z)/b);\r
+ double g=(Z*f*f+Z*f*f*f-c/b+Z-1);//(Z*f^2+Z*f^3-c/b+Z-1)\r
+ double h=(3.0*Z*f*f-d/b+Z-1.0);//(3*Z*f^2-d/b+Z-1)\r
+ double i=(h/Z);\r
+ Complex j=new Complex(0,i*i*i/27.0+g*g/e);//(0,i*i*i/27.0+g*g/e);\r
+// j.r=0;\r
+// j.i=Math.sqrt(-i*i*i/27.0+g*g/e);\r
+// j.sqrt(j);\r
+ Complex k=new Complex();\r
+ k.r=j.r-g/(2.0*Z);\r
+ k.i=j.i;\r
+ Complex l=new Complex();\r
+ l.r=-(g/(2.0*Z)+j.r);\r
+ l.i=-j.i;\r
+ \r
+ k.pow(k,1.0/3);\r
+ l.pow(l,1.0/3);\r
+ double fi=k.dist()+l.dist()-Z/b;\r
+ return fi;\r
+ }\r
+ private double solvL(double k,double mp)\r
+ {\r
+ return 100/(1+k*k+k*k*k+k);\r
+ }\r
+ \r
+ \r
+ public static void main(String[] args)\r
+ {\r
+\r
+ try {\r
+ NyARColorPatt_DiagonalRatio t = new NyARColorPatt_DiagonalRatio(3);\r
+ double k=t.solvK(60,100);\r
+ double l=t.solvL(k,60);\r
+ \r
+ // t.Test_arGetVersion();\r
+ NyARSquare s=new NyARSquare();\r
+ s.sqvertex[0].x=10;\r
+ s.sqvertex[0].y=10;\r
+ s.sqvertex[1].x=90;\r
+ s.sqvertex[1].y=0;\r
+ s.sqvertex[2].x=100;\r
+ s.sqvertex[2].y=100;\r
+ s.sqvertex[3].x=0;\r
+ s.sqvertex[3].y=100;\r
+ //t.getLineCrossPoint(s);\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package jp.nyatla.nyartoolkit.dev;\r
+\r
+import java.awt.Color;\r
+import java.awt.Frame;\r
+import java.awt.Graphics;\r
+import java.awt.Image;\r
+import java.awt.Insets;\r
+\r
+import javax.media.Buffer;\r
+import javax.media.format.VideoFormat;\r
+import javax.media.util.BufferToImage;\r
+import java.awt.image.*;\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.NyARIdMarkerPickup;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
+import jp.nyatla.utils.j2se.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.*;\r
+\r
+public class PattPickupTest extends Frame implements JmfCaptureListener\r
+{\r
+ private final String PARAM_FILE = "../Data/camera_para.dat";\r
+\r
+ private static final long serialVersionUID = -2110888320986446576L;\r
+\r
+ private JmfCaptureDevice _capture;\r
+\r
+ private JmfNyARRaster_RGB _capraster;\r
+\r
+ private NyARSquareDetector _detector;\r
+\r
+ protected INyARRasterFilter_RgbToBin _tobin_filter;\r
+\r
+ private NyARBinRaster _bin_raster;\r
+\r
+ private NyARSquareStack _stack = new NyARSquareStack(100);\r
+\r
+ public PattPickupTest() throws NyARException\r
+ {\r
+ setTitle("JmfCaptureTest");\r
+ Insets ins = this.getInsets();\r
+ this.setSize(640 + ins.left + ins.right, 480 + ins.top + ins.bottom);\r
+ JmfCaptureDeviceList dl = new JmfCaptureDeviceList();\r
+ this._capture = dl.getDevice(0);\r
+ if (!this._capture.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_RGB, 320, 240, 30.0f)) {\r
+ if (!this._capture.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_YUV, 320, 240, 30.0f)) {\r
+ throw new NyARException("キャプチャフォーマットが見つかりません。");\r
+ }\r
+ }\r
+ NyARParam ar_param = new NyARParam();\r
+ ar_param.loadARParamFromFile(PARAM_FILE);\r
+ ar_param.changeScreenSize(320, 240);\r
+ this._capraster = new JmfNyARRaster_RGB(320, 240, this._capture.getCaptureFormat());\r
+ this._capture.setOnCapture(this);\r
+ this._detector = new NyARSquareDetector(ar_param.getDistortionFactor(), ar_param.getScreenSize());\r
+ this._bin_raster = new NyARBinRaster(320, 240);\r
+ this._tobin_filter = new NyARRasterFilter_ARToolkitThreshold(110);\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * 矩形の矩形っぽい点数を返す。\r
+ * \r
+ * @param i_sq\r
+ * @return\r
+ */\r
+ private int getSQPoint(NyARSquare i_sq)\r
+ {\r
+ int lx1 = i_sq.imvertex[0].x - i_sq.imvertex[2].x;\r
+ int ly1 = i_sq.imvertex[0].y - i_sq.imvertex[2].y;\r
+ int lx2 = i_sq.imvertex[1].x - i_sq.imvertex[3].x;\r
+ int ly2 = i_sq.imvertex[1].y - i_sq.imvertex[3].y;\r
+ return (int) Math.sqrt((lx1 * lx1) + (ly1 * ly1)) * (int) Math.sqrt(((lx2 * lx2) + (ly2 * ly2)));\r
+ }\r
+\r
+ private INyARColorPatt _patt1 = new NyARColorPatt_O3(64, 64);\r
+\r
+ private INyARColorPatt _patt2 = new NyARColorPatt_Perspective(100,100);\r
+\r
+ private NyARIdMarkerPickup _patt3 = new NyARIdMarkerPickup();\r
+\r
+ public void onUpdateBuffer(Buffer i_buffer)\r
+ {\r
+ try {\r
+ Insets ins = this.getInsets();\r
+ Graphics g = getGraphics();\r
+\r
+ {// ピックアップ画像の表示\r
+ // 矩形抽出\r
+ this._capraster.setBuffer(i_buffer);\r
+ this._tobin_filter.doFilter(this._capraster, this._bin_raster);\r
+ this._detector.detectMarker(this._bin_raster, this._stack);\r
+\r
+ int max_point = 0;\r
+ NyARSquare t = null;\r
+ // ど れ に し よ う か なー\r
+ for (int i = this._stack.getLength() - 1; i >= 0; i--) {\r
+ NyARSquare sq = (NyARSquare) this._stack.getItem(i);\r
+ int wp = getSQPoint(sq);\r
+ if (wp < max_point) {\r
+ continue;\r
+ }\r
+ t = sq;\r
+ }\r
+ if (t != null) {\r
+\r
+ BufferedImageSink sink = new BufferedImageSink(this._patt1.getWidth(), this._patt1.getHeight());\r
+ BufferedImageSink sink2 = new BufferedImageSink(this._patt2.getWidth(), this._patt2.getHeight());\r
+// BufferedImageSink sink3 = new BufferedImageSink(this._patt3.getWidth(), this._patt3.getHeight());\r
+ Graphics g1,g2,g3;\r
+ {// ARToolkit\r
+ // 一番それっぽいパターンを取得\r
+ this._patt1.pickFromRaster(this._capraster, t);\r
+ // パターンを書く\r
+ sink.sinkFromRaster(this._patt1);\r
+ g1=sink.getGraphics();\r
+ g1.setColor(Color.red);\r
+ g1.drawLine(this._patt1.getWidth()/2,0,this._patt1.getWidth()/2,this._patt1.getHeight());\r
+ g1.drawLine(0,this._patt1.getHeight()/2,this._patt1.getWidth(),this._patt1.getHeight()/2);\r
+ }\r
+ {// 疑似アフィン変換\r
+ // 一番それっぽいパターンを取得\r
+ this._patt2.pickFromRaster(this._capraster, t);\r
+ // パターンを書く\r
+ sink2.sinkFromRaster(this._patt2);\r
+ g2=sink2.getGraphics();\r
+ g2.setColor(Color.red);\r
+ g2.drawLine(this._patt1.getWidth()/2,0,this._patt1.getWidth()/2,this._patt1.getHeight());\r
+ g2.drawLine(0,this._patt1.getHeight()/2,this._patt1.getWidth(),this._patt1.getHeight()/2);\r
+ }\r
+ {// IDマーカ\r
+ NyARIdMarkerData data =new NyARIdMarkerData();\r
+ NyARIdMarkerParam param =new NyARIdMarkerParam();\r
+ \r
+ // 一番それっぽいパターンを取得\r
+ this._patt3.pickFromRaster(this._capraster, t,data,param);\r
+ System.out.println("model="+data.model);\r
+ System.out.println("domain="+data.ctrl_domain);\r
+ System.out.println("maskl="+data.ctrl_mask);\r
+ System.out.println("data= "+data.data[0]+","+data.data[1]+","+data.data[2]);\r
+ // パターンを書く\r
+/* sink3.sinkFromRaster(this._patt3);\r
+ g3=sink.getGraphics();\r
+ g3.setColor(Color.red);\r
+ g2.drawRect(10,10,10,10);\r
+ g2.drawRect(80,10,10,10);\r
+ g2.drawRect(10,80,10,10);\r
+ g2.drawRect(80,80,10,10);*/\r
+// g2.drawLine(this._patt3.sv[0]-1,this._patt3.sv[1],this._patt3.sv[0]+1,this._patt3.sv[1]);\r
+// g2.drawLine(this._patt3.sv[0],this._patt3.sv[1]-1,this._patt3.sv[0],this._patt3.sv[1]+1);\r
+// g2.drawLine(this._patt3.sv[2]-1,this._patt3.sv[3],this._patt3.sv[2]+1,this._patt3.sv[3]);\r
+// g2.drawLine(this._patt3.sv[2],this._patt3.sv[3]-1,this._patt3.sv[2],this._patt3.sv[3]+1);\r
+ \r
+ BufferedImage img=new BufferedImage(45,256, BufferedImage.TYPE_INT_RGB);\r
+\r
+ g.drawImage(img, ins.left, ins.top+240,45,256, null);\r
+/*\r
+ g2.setColor(Color.blue);\r
+ for (int i = 0; i < 225*4; i++) {\r
+ g2.drawRect(this._patt3.vertex_x[i]-1,this._patt3.vertex_y[i]-1, 2, 2);\r
+ }\r
+*/ g2.setColor(Color.red);\r
+ for (int i = 0; i <4; i++) {\r
+ g2.drawRect(this._patt3.vertex2_x[i]-1,this._patt3.vertex2_y[i]-1, 2, 2);\r
+ }\r
+ }\r
+ g.drawImage(sink, ins.left + 320, ins.top, 128, 128, null);\r
+ g.drawImage(sink2, ins.left + 320, ins.top + 128, 400, 400, null);\r
+// g.drawImage(sink3, ins.left + 100, ins.top + 240, this._patt3.getWidth() * 10, this._patt3.getHeight() * 10, null);\r
+ }\r
+\r
+ {// 撮影画像\r
+ BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());\r
+ Image img = b2i.createImage(i_buffer);\r
+ g.drawImage(img, ins.left, ins.top, this);\r
+ g.setColor(Color.blue);\r
+ for (int i = 0; i < 225*4; i++) {\r
+ g.drawRect(ins.left+this._patt3.vertex_x[i]-1,ins.top+this._patt3.vertex_y[i]-1, 2, 2);\r
+ }\r
+ \r
+ }\r
+ /*\r
+ * { //輪郭パターン NyARSquare s=new NyARSquare(); for(int i=0;i<4;i++){ s.imvertex[i].x=(int)t.sqvertex[i].x; s.imvertex[i].y=(int)t.sqvertex[i].y; }\r
+ * //一番それっぽいパターンを取得 this._patt1.pickFromRaster(this._capraster,s); //パターンを書く BufferedImageSink sink=new\r
+ * BufferedImageSink(this._patt1.getWidth(),this._patt1.getHeight()); sink.sinkFromRaster(this._patt1);\r
+ * g.drawImage(sink,ins.left+320,ins.top+128,128,128,null); }\r
+ */\r
+ {// 信号取得テスト\r
+\r
+ }\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void startCapture()\r
+ {\r
+ try {\r
+ this._capture.start();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public static void main(String[] args)\r
+ {\r
+ try {\r
+ PattPickupTest mainwin = new PattPickupTest();\r
+ mainwin.setVisible(true);\r
+ mainwin.startCapture();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ }\r
+\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.dev;\r
+\r
+\r
+\r
+public class Solver\r
+{\r
+ public String[][] _data=new String[4][6];\r
+ public String[] _temp=new String[6];\r
+ public Solver()\r
+ {\r
+ this._data[0][0]="a";\r
+ this._data[0][1]="b";\r
+ this._data[0][2]="c";\r
+ this._data[0][3]="d";\r
+ this._data[0][4]="e";\r
+ this._data[0][5]="1";\r
+ \r
+ this._data[1][0]="f";\r
+ this._data[1][1]="g";\r
+ this._data[1][2]="h";\r
+ this._data[1][3]="i";\r
+ this._data[1][4]="j";\r
+ this._data[1][5]="1";\r
+ \r
+ this._data[2][0]="k";\r
+ this._data[2][1]="l";\r
+ this._data[2][2]="m";\r
+ this._data[2][3]="n";\r
+ this._data[2][4]="o";\r
+ this._data[2][5]="1";\r
+\r
+ this._data[3][0]="p";\r
+ this._data[3][1]="q";\r
+ this._data[3][2]="r";\r
+ this._data[3][3]="s";\r
+ this._data[3][4]="t";\r
+ this._data[3][5]="1";\r
+ }\r
+ public void dump()\r
+ {\r
+ for(int i=0;i<this._data.length;i++){\r
+ for(int i2=0;i2<this._data[i].length;i2++){\r
+ System.out.print(this._data[i][i2]+" , ");\r
+ } \r
+ System.out.println(" ");\r
+ }\r
+ }\r
+ public boolean isSingle(String i_str)\r
+ {\r
+ int c=0;\r
+ for(int i=0;i<i_str.length();i++){\r
+ if(i_str.charAt(i)=='('){\r
+ c++;\r
+ }\r
+ if(i_str.charAt(i)==')'){\r
+ c--;\r
+ if(c==0 && i!=i_str.length()-1){\r
+ return false;//括弧必要\r
+ }\r
+ }\r
+ }\r
+ return true;//括弧不要\r
+ }\r
+ \r
+ public void div(int i_r,String i_e,String[] o_row) throws Exception\r
+ {\r
+ if(i_e=="0"){\r
+ throw new Exception(); \r
+ }else if(i_e=="1"){\r
+ return;\r
+ }\r
+ String[] l=this._data[i_r];\r
+ for(int i=0;i<o_row.length;i++){\r
+ if(l[i]==i_e){\r
+ o_row[i]="1";\r
+ }else if(l[i]=="0"){\r
+ o_row[i]="0";\r
+ }else{\r
+ String s1=isSingle(l[i])?l[i]:"("+l[i]+")";\r
+ String s2=isSingle(i_e)?i_e:"("+i_e+")";\r
+ o_row[i]="("+s1+"/"+s2+")";\r
+ }\r
+ }\r
+ }\r
+ public void mul(int i_r,String i_e,String[] o_row)\r
+ {\r
+ String[] l=this._data[i_r];\r
+ if(i_e=="0"){\r
+ for(int i=0;i<o_row.length;i++){\r
+ o_row[i]="0";\r
+ }\r
+ }else if(i_e=="1"){\r
+ return;\r
+ }else{\r
+ for(int i=0;i<o_row.length;i++){\r
+ if(l[i]=="0"){\r
+ o_row[i]="0";\r
+ }else if(l[i]=="1"){\r
+ o_row[i]=i_e;\r
+ }else{\r
+ String s1=isSingle(l[i])?l[i]:"("+l[i]+")";\r
+ String s2=isSingle(i_e)?i_e:"("+i_e+")";\r
+ o_row[i]="("+s1+"*"+s2+")";\r
+ }\r
+ }\r
+ }\r
+ }\r
+ public void subRow(int i_r1,String[] i_r,String[] o_row)\r
+ {\r
+ String[] l1=this._data[i_r1];\r
+ String[] l2=i_r;\r
+ for(int i=0;i<o_row.length;i++){\r
+ if(l1[i]=="0"){\r
+ o_row[i]=l2[i];\r
+ }else if(l2[i]=="0"){\r
+ o_row[i]=l1[i];\r
+ }else if(l2[i]==l1[i]){\r
+ o_row[i]="0";\r
+ }else{\r
+ String s1=isSingle(l1[i])?l1[i]:"("+l1[i]+")";\r
+ String s2=isSingle(l2[i])?l2[i]:"("+l2[i]+")";\r
+ o_row[i]="("+s1+"-"+s2+")";\r
+ }\r
+ }\r
+ }\r
+ public static void main(String[] args)\r
+ {\r
+ try {\r
+ Solver n=new Solver();\r
+\r
+ for(int i=0;i<4;i++){\r
+ for(int i2=0;i2<i;i2++){\r
+ n.mul(i2,n._data[i][i2],n._temp);\r
+ n.subRow(i,n._temp,n._data[i]); \r
+ }\r
+ n.div(i,n._data[i][i],n._data[i]);\r
+ }\r
+ n.dump();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ } \r
+}\r