public void init(GLAutoDrawable drawable)\r
{\r
this._gl = drawable.getGL();\r
+ this._gl.glEnable(GL.GL_DEPTH_TEST);\r
+\r
this._gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
//NyARToolkitの準備\r
try {\r
//NyARToolkitの準備\r
this._ar_param = new NyARParam();\r
NyARCode ar_code = new NyARCode(16, 16);\r
+ ar_code.loadARPattFromFile(CARCODE_FILE);\r
this._ar_param.loadARParamFromFile(PARAM_FILE);\r
this._ar_param.changeScreenSize(SCREEN_X, SCREEN_Y);\r
this._nya = new NyARSingleDetectMarker(this._ar_param, ar_code, 80.0);\r
this._nya.setContinueMode(false);//ここをtrueにすると、transMatContinueモード(History計算)になります。\r
- ar_code.loadARPattFromFile(CARCODE_FILE);\r
//NyARToolkit用の支援クラス\r
_glnya = new NyARGLUtil(_gl);\r
//GL対応のRGBラスタオブジェクト\r
final int[] ycoord = this._ycoord;\r
final int coord_max = this._max_coord;\r
final int[] mkvertex = this.__detectMarker_mkvertex;\r
- final int[][] buf = (int[][]) limage.getBufferReader().getBuffer();\r
+ final int[] buf = (int[]) limage.getBufferReader().getBuffer();\r
final int[] indextable = limage.getIndexArray();\r
int coord_num;\r
int label_area;\r
* @param i_label\r
* @return\r
*/\r
- private boolean hasQrEdgeFeature(int buf[][], int[] index_table, NyARLabelingLabel i_label)\r
+ private boolean hasQrEdgeFeature(int[] buf, int[] index_table, NyARLabelingLabel i_label)\r
{\r
int tx, bx;\r
int w;\r
int i_label_id = i_label.id;\r
- int[] limage_j;\r
+ int limage_j_ptr;\r
final int clip_l = i_label.clip_l;\r
final int clip_b = i_label.clip_b;\r
final int clip_r = i_label.clip_r;\r
\r
tx = bx = 0;\r
// 上接点(→)\r
- limage_j = buf[clip_t];\r
+ limage_j_ptr = clip_t*this._width;\r
for (int i = clip_l; i <= clip_r; i++) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {\r
- w = limage_j[i];\r
+ w = buf[limage_j_ptr+i];\r
if (w > 0 && index_table[w - 1] == i_label_id) {\r
tx = i;\r
break;\r
}\r
}\r
// 下接点(←)\r
- limage_j = buf[clip_b];\r
+ limage_j_ptr = clip_b*this._width;\r
for (int i = clip_r; i >= clip_l; i--) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {\r
- w = limage_j[i];\r
+ w = buf[limage_j_ptr+i];\r
if (w > 0 && index_table[w - 1] == i_label_id) {\r
bx = i;\r
break;\r
* @param i_py2\r
* @return\r
*/\r
- private boolean checkDiagonalLine(int[][] buf, int i_px1, int i_py1, int i_px2, int i_py2)\r
+ private boolean checkDiagonalLine(int[] buf, int i_px1, int i_py1, int i_px2, int i_py2)\r
{\r
int sub_y = i_py2 - i_py1;\r
int sub_x = i_px2 - i_px1;\r
for (; i < sub_y; i++) {\r
int yp = i_py1 + i;\r
int xp = i_px1 + i * sub_x / sub_y;\r
- if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) {\r
+ if (buf[yp*this._width+xp] == 0 && buf[yp*this._width+(xp-1)] == 0 && buf[yp*this._width+(xp+1)] == 0) {\r
break;\r
}\r
\r
for (; i < sub_y; i++) {\r
int yp = i_py1 + i;\r
int xp = i_px1 + i * sub_x / sub_y;\r
- if (buf[yp][xp] != 0 && buf[yp][xp-1] != 0 && buf[yp][xp+1] != 0) {\r
+ if (buf[yp*this._width+xp] != 0 && buf[yp*this._width+(xp-1)] != 0 && buf[yp*this._width+(xp+1)] != 0) {\r
break;\r
}\r
\r
for (; i < sub_y; i++) {\r
int yp = i_py1 + i;\r
int xp = i_px1 + i * sub_x / sub_y;\r
- if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) {\r
+ if (buf[yp*this._width+xp] == 0 && buf[yp*this._width+(xp-1)] == 0 && buf[yp*this._width+(xp+1)] == 0) {\r
break;\r
}\r
\r
\r
private final NyARSquareStack _square_list = new NyARSquareStack(AR_SQUARE_MAX);\r
\r
- private NyARCode _code;\r
-\r
protected INyARTransMat _transmat;\r
\r
private double _marker_width;\r
this._square_detect = new NyARSquareDetector_Quad(i_param.getDistortionFactor(),scr_size);\r
this._transmat = new NyARTransMat_X2(i_param);\r
// 比較コードを保存\r
- this._code = i_code;\r
this._marker_width = i_marker_width;\r
// 評価パターンのホルダを作る\r
- this._patt = new NyARColorPatt_O3(_code.getWidth(), _code.getHeight());\r
- // 評価器を作る。\r
- this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA();\r
+ this._patt = new NyARColorPatt_O3(i_code.getWidth(), i_code.getHeight());\r
+ // i_codeに対応する評価器を作る。\r
+ this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA(i_code);\r
//2値画像バッファを作る\r
this._bin_raster=new NyARBinRaster(scr_size.w/2,scr_size.h/2);\r
+ //差分データインスタンスの作成\r
+ this._deviation_data=new NyARMatchPattDeviationColorData(i_code.getWidth(), i_code.getHeight());\r
+ \r
return;\r
}\r
\r
// private NyARRasterFilter_ARToolkitThreshold _tobin_filter=new NyARRasterFilter_ARToolkitThreshold(100);\r
private NyARRasterFilter_ARTTh_Quad _tobin_filter=new NyARRasterFilter_ARTTh_Quad(100);\r
\r
+ private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+ private NyARMatchPattDeviationColorData _deviation_data;\r
+\r
/**\r
* i_imageにマーカー検出処理を実行し、結果を記録します。\r
* \r
return false;\r
}\r
\r
- // 評価基準になるパターンをイメージから切り出す\r
- if (!this._patt.pickFromRaster(i_raster, (NyARSquare)l_square_list.getItem(0))) {\r
- // パターンの切り出しに失敗\r
- return false;\r
- }\r
- // パターンを評価器にセット\r
- if (!this._match_patt.setPatt(this._patt)) {\r
- // 計算に失敗した。\r
- throw new NyARException();\r
- }\r
- // コードと比較する\r
- this._match_patt.evaluate(this._code);\r
+ boolean result=false;\r
+ NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
int square_index = 0;\r
- int direction = this._match_patt.getDirection();\r
- double confidence = this._match_patt.getConfidence();\r
- for (int i = 1; i < number_of_square; i++) {\r
- // 次のパターンを取得\r
- this._patt.pickFromRaster(i_raster, (NyARSquare)l_square_list.getItem(i));\r
- // 評価器にセットする。\r
- this._match_patt.setPatt(this._patt);\r
- // コードと比較する\r
- this._match_patt.evaluate(this._code);\r
- double c2 = this._match_patt.getConfidence();\r
+ int direction = NyARSquare.DIRECTION_UNKNOWN;\r
+ double confidence = 0;\r
+ for(int i=0;i<number_of_square;i++){\r
+ // 評価基準になるパターンをイメージから切り出す\r
+ if (!this._patt.pickFromRaster(i_raster, (NyARSquare)l_square_list.getItem(i))){\r
+ continue;\r
+ }\r
+ //取得パターンをカラー差分データに変換して評価する。\r
+ this._deviation_data.setRaster(this._patt);\r
+ this._match_patt.evaluate(this._deviation_data,mr);\r
+\r
+ final double c2 = mr.confidence;\r
if (confidence > c2) {\r
continue;\r
}\r
// もっと一致するマーカーがあったぽい\r
square_index = i;\r
- direction = this._match_patt.getDirection();\r
+ direction = mr.direction;\r
confidence = c2;\r
+ result=true;\r
}\r
+ \r
// マーカー情報を保存\r
this._detected_square = (NyARSquare)l_square_list.getItem(square_index);\r
this._detected_direction = direction;\r
this._detected_confidence = confidence;\r
- return true;\r
+ return false;\r
}\r
\r
/**\r
\r
\r
/**\r
- * 回転行列計算用の、3x3行列\r
+ * NyARRotMatrix_NyARToolKitのFixedFloat版です。\r
* \r
*/\r
public class NyARFixedFloatRotMatrix extends NyARFixedFloat24Matrix33\r
}\r
\r
final private NyARFixedFloatRotVector __initRot_vec1;\r
-\r
final private NyARFixedFloatRotVector __initRot_vec2;\r
+ final private NyARFixedFloat16Point3d _angle=new NyARFixedFloat16Point3d();\r
\r
public final void initRotByPrevResult(NyARTransMatResult i_prev_result)\r
{\r
this.m02 = (w02<<24) / w;\r
this.m12 = (w12<<24) / w;\r
this.m22 = (w22<<24) / w;\r
+ //Matrixからangleをロード\r
+ this.updateAngleFromMatrix();\r
+ \r
return;\r
}\r
-\r
+ public NyARFixedFloat16Point3d refAngle()\r
+ {\r
+ return this._angle;\r
+ }\r
/**\r
* int arGetAngle( double rot[3][3], double *wa, double *wb, double *wc ) Optimize:2008.04.20:STEP[481→433] 3x3変換行列から、回転角を復元して返します。\r
* \r
* @param o_angle\r
* @return\r
*/\r
- public final void getAngle(final NyARFixedFloat16Point3d o_angle)\r
+ private final void updateAngleFromMatrix()\r
{\r
int a, b, c;\r
long sina, cosa, sinb, cosb, sinc, cosc;\r
sina = -NyMath.FIXEDFLOAT24_1;\r
cosa = 0;\r
}\r
- a = (int)NyMath.acosFixedFloat16((int)cosa);\r
+ a = NyMath.acosFixedFloat16((int)cosa);\r
if (sina < 0) {\r
a = -a;\r
}\r
sinc = -NyMath.FIXEDFLOAT24_1;\r
cosc = 0;\r
}\r
- c = (int)NyMath.acosFixedFloat16((int)cosc);\r
+ c = NyMath.acosFixedFloat16((int)cosc);\r
if (sinc < 0) {\r
c = -c;\r
}\r
}\r
- o_angle.x = (long)a;// wa.value=a;//*wa = a;\r
- o_angle.y = (long)b;// wb.value=b;//*wb = b;\r
- o_angle.z = (long)c;// wc.value=c;//*wc = c;\r
+ this._angle.x = (long)a;// wa.value=a;//*wa = a;\r
+ this._angle.y = (long)b;// wb.value=b;//*wb = b;\r
+ this._angle.z = (long)c;// wc.value=c;//*wc = c;\r
return;\r
}\r
public final void setAngle(int i_x, int i_y, int i_z)\r
this.m20 =(-Sb * Cac)>>24;\r
this.m21 =(-Sb * Sac)>>24;\r
this.m22 =Cb;\r
+ //angleを逆計算せずに直接代入\r
+ this._angle.x=i_x;\r
+ this._angle.y=i_y;\r
+ this._angle.z=i_z; \r
return;\r
}\r
/**\r
}\r
\r
private final long[][] __modifyMatrix_double1D = new long[8][3];\r
- private final NyARFixedFloat16Point3d __modifyMatrix_angle = new NyARFixedFloat16Point3d();\r
private final long INITIAL_FACTOR=(long)(0x10000*5.0 * Math.PI / 180.0);\r
/**\r
* arGetRot計算を階層化したModifyMatrix 896\r
long SACASC, SACACBSC, SACACBCC, SACACC;\r
final long[][] double1D = this.__modifyMatrix_double1D;\r
\r
- final NyARFixedFloat16Point3d angle = this.__modifyMatrix_angle;\r
final long[] a_factor = double1D[1];\r
final long[] sinb = double1D[2];\r
final long[] cosb = double1D[3];\r
long w, w2;\r
long wsin, wcos;\r
\r
- io_rot.getAngle(angle);// arGetAngle( rot, &a, &b, &c );\r
+ final NyARFixedFloat16Point3d angle=io_rot.refAngle();// arGetAngle( rot, &a, &b, &c );\r
a2 =angle.x;\r
b2 =angle.y;\r
c2 =angle.z;\r
\r
private final NyARSquareStack _square_list = new NyARSquareStack(AR_SQUARE_MAX);\r
\r
- private NyARCode _code;\r
-\r
protected INyARTransMat _transmat;\r
\r
private double _marker_width;\r
// 解析オブジェクトを作る\r
this._square_detect = new NyARSquareDetector_X2(dist_map,scr_size);\r
this._transmat = new NyARTransMat_X2(i_param);\r
- // 比較コードを保存\r
- this._code = i_code;\r
this._marker_width = i_marker_width;\r
+ int cw=i_code.getWidth();\r
+ int ch=i_code.getHeight();\r
// 評価パターンのホルダを作る\r
- this._patt = new NyARColorPatt_O3(_code.getWidth(), _code.getHeight());\r
+ this._patt = new NyARColorPatt_O3(cw,ch);\r
// 評価器を作る。\r
- this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA();\r
+ this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA(i_code);\r
//2値画像バッファを作る\r
this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);\r
+ //差分データインスタンスの作成\r
+ this._deviation_data=new NyARMatchPattDeviationColorData(cw,ch);\r
return;\r
}\r
\r
private NyARBinRaster _bin_raster;\r
private NyARRasterFilter_ARToolkitThreshold _tobin_filter=new NyARRasterFilter_ARToolkitThreshold(100);\r
+ private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+ private NyARMatchPattDeviationColorData _deviation_data;\r
\r
\r
/**\r
if (number_of_square < 1) {\r
return false;\r
}\r
-\r
- // 評価基準になるパターンをイメージから切り出す\r
- if (!this._patt.pickFromRaster(i_raster, (NyARSquare)l_square_list.getItem(0))) {\r
- // パターンの切り出しに失敗\r
- return false;\r
- }\r
- // パターンを評価器にセット\r
- if (!this._match_patt.setPatt(this._patt)) {\r
- // 計算に失敗した。\r
- throw new NyARException();\r
- }\r
- // コードと比較する\r
- this._match_patt.evaluate(this._code);\r
+ NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
int square_index = 0;\r
- int direction = this._match_patt.getDirection();\r
- double confidence = this._match_patt.getConfidence();\r
- for (int i = 1; i < number_of_square; i++) {\r
- // 次のパターンを取得\r
- this._patt.pickFromRaster(i_raster, (NyARSquare)l_square_list.getItem(i));\r
- // 評価器にセットする。\r
- this._match_patt.setPatt(this._patt);\r
- // コードと比較する\r
- this._match_patt.evaluate(this._code);\r
- double c2 = this._match_patt.getConfidence();\r
+ int direction = NyARSquare.DIRECTION_UNKNOWN;\r
+ double confidence = 0;\r
+ for(int i=0;i<number_of_square;i++){\r
+ // 評価基準になるパターンをイメージから切り出す\r
+ if (!this._patt.pickFromRaster(i_raster, (NyARSquare)l_square_list.getItem(i))){\r
+ continue;\r
+ }\r
+ //取得パターンをカラー差分データに変換して評価する。\r
+ this._deviation_data.setRaster(this._patt);\r
+ this._match_patt.evaluate(this._deviation_data,mr);\r
+\r
+ final double c2 = mr.confidence;\r
if (confidence > c2) {\r
continue;\r
}\r
// もっと一致するマーカーがあったぽい\r
square_index = i;\r
- direction = this._match_patt.getDirection();\r
+ direction = mr.direction;\r
confidence = c2;\r
}\r
+ \r
// マーカー情報を保存\r
this._detected_square = (NyARSquare)l_square_list.getItem(square_index);\r
this._detected_direction = direction;\r
o_result.m21 =(double)i_rot.m21/NyMath.FIXEDFLOAT24_1;\r
o_result.m22 =(double)i_rot.m22/NyMath.FIXEDFLOAT24_1;\r
o_result.m23 =(double)(((i_rot.m20 * i_off.x + i_rot.m21 * i_off.y + i_rot.m22 * i_off.z)>>24) + i_trans.z)/NyMath.FIXEDFLOAT16_1;\r
+ \r
+ final NyARFixedFloat16Point3d angle=i_rot.refAngle();\r
\r
+ o_result.angle.x=(double)angle.x/NyMath.FIXEDFLOAT16_1;\r
+ o_result.angle.y=(double)angle.y/NyMath.FIXEDFLOAT16_1;\r
+ o_result.angle.z=(double)angle.z/NyMath.FIXEDFLOAT16_1;\r
o_result.has_value = true;\r
return;\r
} \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
// Blank_Raster ra=new Blank_Raster(320, 240);\r
\r
// 1パターンのみを追跡するクラスを作成\r
+// NyARSingleDetectMarker_Quad ar = new NyARSingleDetectMarker_Quad(ap, code, 80.0);\r
NyARSingleDetectMarker_X2 ar = new NyARSingleDetectMarker_X2(ap, code, 80.0);\r
NyARTransMatResult result_mat = new NyARTransMatResult();\r
ar.setContinueMode(false);\r
throw new NyARException();\r
}\r
return;\r
- } \r
+ }\r
+\r
}\r
\r
\r
this._yuv2rgb=new YUVToRGB();\r
this._rgb_buf=new javax.media.Buffer();\r
this._ref_buf=null;\r
- //24bit-RGBフォーマットのものを探す\r
+ //24bit-BGRフォーマットのものを探す\r
Format output_format=pickRGB24Format(this._yuv2rgb.getSupportedOutputFormats(i_input_format));\r
if(output_format==null){\r
throw new NyARException();\r
}\r
public void getPixel(int i_x, int i_y, int[] o_rgb) throws NyARException\r
{\r
- int bp = (i_x + i_y * this._ref_size.w) * 3;\r
- byte[] ref = this._ref_buf;\r
- o_rgb[0] = (ref[bp + 2] & 0xff);// B\r
+ //IN :BGRBGR\r
+ // :012012\r
+ final int bp = (i_x + i_y * this._ref_size.w) * 3;\r
+ final byte[] ref = this._ref_buf;\r
+ o_rgb[0] = (ref[bp + 2] & 0xff);// R\r
o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
- o_rgb[2] = (ref[bp + 0] & 0xff);// R\r
+ o_rgb[2] = (ref[bp + 0] & 0xff);// B\r
return;\r
}\r
public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) throws NyARException\r
{\r
- int width = this._ref_size.w;\r
- byte[] ref = this._ref_buf;\r
int bp;\r
+ final int width = this._ref_size.w;\r
+ final byte[] ref = this._ref_buf;\r
for (int i = i_num - 1; i >= 0; i--) {\r
bp = (i_x[i] + i_y[i] * width) * 3;\r
- o_rgb[i * 3 + 0] = (ref[bp + 2] & 0xff);// B\r
+ o_rgb[i * 3 + 0] = (ref[bp + 2] & 0xff);// R\r
o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
- o_rgb[i * 3 + 2] = (ref[bp + 0] & 0xff);// R\r
+ o_rgb[i * 3 + 2] = (ref[bp + 0] & 0xff);// B\r
}\r
return;\r
- } \r
+ }\r
}\r
\r
\r
import java.io.InputStreamReader;\r
import java.io.StreamTokenizer;\r
\r
-import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.match.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
\r
-\r
-\r
-/**\r
- * ARToolKitのマーカーコードを1個保持します。\r
- * \r
- */\r
-public class NyARCode\r
+class NyARCodeFileReader\r
{\r
- private int[][][][] pat;// static int\r
- // pat[AR_PATT_NUM_MAX][4][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
-\r
- private double[] patpow = new double[4];// static double patpow[AR_PATT_NUM_MAX][4];\r
-\r
- private short[][][] patBW;// static int patBW[AR_PATT_NUM_MAX][4][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
-\r
- private double[] patpowBW = new double[4];// static double patpowBW[AR_PATT_NUM_MAX][4];\r
\r
- private int width, height;\r
-\r
- public int[][][][] getPat()\r
+ /**\r
+ * ARコードファイルからデータを読み込んでo_raster[4]に格納します。\r
+ * @param i_stream\r
+ * @param o_raster\r
+ * @throws NyARException\r
+ */\r
+ public static void loadFromARToolKitFormFile(InputStream i_stream,NyARRaster[] o_raster) throws NyARException\r
{\r
- return pat;\r
+ assert o_raster.length==4;\r
+ //4個の要素をラスタにセットする。\r
+ try {\r
+ StreamTokenizer st = new StreamTokenizer(new InputStreamReader(i_stream));\r
+ //GBRAで一度読みだす。\r
+ for (int h = 0; h < 4; h++) {\r
+ assert o_raster[h].getBufferReader().isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ final NyARRaster ra=o_raster[h];\r
+ readBlock(st,ra.getWidth(),ra.getHeight(),(int[])ra.getBufferReader().getBuffer());\r
+ }\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ }\r
+ return;\r
}\r
-\r
- public double[] getPatPow()\r
+ /**\r
+ * ARコードファイルからデータを読み込んでo_codeに格納します。\r
+ * @param i_stream\r
+ * @param o_code\r
+ * @throws NyARException\r
+ */\r
+ public static void loadFromARToolKitFormFile(InputStream i_stream,NyARCode o_code) throws NyARException\r
{\r
- return patpow;\r
+ int width=o_code.getWidth();\r
+ int height=o_code.getHeight();\r
+ NyARRaster tmp_raster=new NyARRaster(new NyARIntSize(width,height),new int[width*height],INyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ //4個の要素をラスタにセットする。\r
+ try {\r
+ StreamTokenizer st = new StreamTokenizer(new InputStreamReader(i_stream));\r
+ int[] buf=(int[])tmp_raster.getBufferReader().getBuffer();\r
+ //GBRAで一度読みだす。\r
+ for (int h = 0; h < 4; h++){\r
+ readBlock(st,width,height,buf);\r
+ //ARCodeにセット(カラー)\r
+ o_code.getColorData(h).setRaster(tmp_raster);\r
+ o_code.getBlackWhiteData(h).setRaster(tmp_raster);\r
+ }\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ }\r
+ tmp_raster=null;//ポイ\r
+ return;\r
}\r
-\r
- public short[][][] getPatBW()\r
+ /**\r
+ * 1ブロック分のXRGBデータをi_stからo_bufへ読みだします。\r
+ * @param i_st\r
+ * @param o_buf\r
+ */\r
+ private static void readBlock(StreamTokenizer i_st,int i_width,int i_height,int[] o_buf) throws NyARException\r
{\r
- return patBW;\r
+ try {\r
+ final int pixels=i_width*i_height;\r
+ for (int i3 = 0; i3 < 3; i3++) {\r
+ for (int i2 = 0; i2 < pixels; i2++){\r
+ // 数値のみ読み出す\r
+ switch (i_st.nextToken()){\r
+ case StreamTokenizer.TT_NUMBER:\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ o_buf[i2]=(o_buf[i2]<<8)|((0x000000ff&(int)i_st.nval));\r
+ }\r
+ }\r
+ //GBR→RGB\r
+ for(int i3=0;i3<pixels;i3++){\r
+ o_buf[i3]=((o_buf[i3]<<16)&0xff0000)|(o_buf[i3]&0x00ff00)|((o_buf[i3]>>16)&0x0000ff);\r
+ }\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ } \r
+ return;\r
}\r
+}\r
\r
- public double[] getPatPowBW()\r
+/**\r
+ * ARToolKitのマーカーコードを1個保持します。\r
+ * \r
+ */\r
+public class NyARCode\r
+{\r
+ private NyARMatchPattDeviationColorData[] _color_pat=new NyARMatchPattDeviationColorData[4];\r
+ private NyARMatchPattDeviationBlackWhiteData[] _bw_pat=new NyARMatchPattDeviationBlackWhiteData[4];\r
+ private int _width;\r
+ private int _height;\r
+ \r
+ public NyARMatchPattDeviationColorData getColorData(int i_index)\r
{\r
- return patpowBW;\r
+ return this._color_pat[i_index];\r
}\r
-\r
+ public NyARMatchPattDeviationBlackWhiteData getBlackWhiteData(int i_index)\r
+ {\r
+ return this._bw_pat[i_index];\r
+ } \r
public int getWidth()\r
{\r
- return width;\r
+ return _width;\r
}\r
\r
public int getHeight()\r
{\r
- return height;\r
+ return _height;\r
}\r
-\r
- public NyARCode(int i_width, int i_height)\r
+ public NyARCode(int i_width, int i_height) throws NyARException\r
{\r
- width = i_width;\r
- height = i_height;\r
- pat = new int[4][height][width][3];// static int pat[AR_PATT_NUM_MAX][4][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
- patBW = new short[4][height][width];// static int patBW[AR_PATT_NUM_MAX][4][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
+ this._width = i_width;\r
+ this._height = i_height;\r
+ //空のラスタを4個作成\r
+ for(int i=0;i<4;i++){\r
+ this._color_pat[i]=new NyARMatchPattDeviationColorData(i_width,i_height);\r
+ this._bw_pat[i]=new NyARMatchPattDeviationBlackWhiteData(i_width,i_height);\r
+ }\r
+ return;\r
}\r
-\r
- /**\r
- * int arLoadPatt( const char *filename ); ARToolKitのパターンファイルをロードする。\r
- * ファイル形式はBGR形式で記録されたパターンファイルであること。\r
- * \r
- * @param filename\r
- * @return\r
- * @throws Exception\r
- */\r
public void loadARPattFromFile(String filename) throws NyARException\r
{\r
try {\r
loadARPatt(new FileInputStream(filename));\r
-\r
} catch (Exception e) {\r
throw new NyARException(e);\r
}\r
+ return;\r
+ }\r
+ public void setRaster(NyARRaster[] i_raster) throws NyARException\r
+ {\r
+ assert i_raster.length!=4;\r
+ //ラスタにパターンをロードする。\r
+ for(int i=0;i<4;i++){\r
+ this._color_pat[i].setRaster(i_raster[i]); \r
+ }\r
+ return;\r
}\r
\r
- /**\r
- * \r
- * @param i_stream\r
- * @throws NyARException\r
- */\r
public void loadARPatt(InputStream i_stream) throws NyARException\r
{\r
- try {\r
- StreamTokenizer st = new StreamTokenizer(new InputStreamReader(\r
- i_stream));\r
- // パターンデータはGBRAで並んでる。\r
- for (int h = 0; h < 4; h++) {\r
- int l = 0;\r
- for (int i3 = 0; i3 < 3; i3++) {\r
- for (int i2 = 0; i2 < height; i2++) {\r
- for (int i1 = 0; i1 < width; i1++) {\r
- // 数値のみ読み出す\r
- switch (st.nextToken()) {// if( fscanf(fp, "%d",&j) != 1 ) {\r
- case StreamTokenizer.TT_NUMBER:\r
- break;\r
- default:\r
- throw new NyARException();\r
- }\r
- short j = (short) (255 - st.nval);// j = 255-j;\r
- // 標準ファイルのパターンはBGRでならんでるからRGBに並べなおす\r
- switch (i3) {\r
- case 0:\r
- pat[h][i2][i1][2] = j;\r
- break;// pat[patno][h][(i2*Config.AR_PATT_SIZE_X+i1)*3+2]= j;break;\r
- case 1:\r
- pat[h][i2][i1][1] = j;\r
- break;// pat[patno][h][(i2*Config.AR_PATT_SIZE_X+i1)*3+1]= j;break;\r
- case 2:\r
- pat[h][i2][i1][0] = j;\r
- break;// pat[patno][h][(i2*Config.AR_PATT_SIZE_X+i1)*3+0]= j;break;\r
- }\r
- // pat[patno][h][(i2*Config.AR_PATT_SIZE_X+i1)*3+i3]= j;\r
- if (i3 == 0) {\r
- patBW[h][i2][i1] = j;// patBW[patno][h][i2*Config.AR_PATT_SIZE_X+i1] = j;\r
- } else {\r
- patBW[h][i2][i1] += j;// patBW[patno][h][i2*Config.AR_PATT_SIZE_X+i1] += j;\r
- }\r
- if (i3 == 2) {\r
- patBW[h][i2][i1] /= 3;// patBW[patno][h][i2*Config.AR_PATT_SIZE_X+i1]/= 3;\r
- }\r
- l += j;\r
- }\r
- }\r
- }\r
-\r
- l /= (height * width * 3);\r
-\r
- int m = 0;\r
- for (int i = 0; i < height; i++) {// for( i = 0; i < AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3;i++ ) {\r
- for (int i2 = 0; i2 < width; i2++) {\r
- for (int i3 = 0; i3 < 3; i3++) {\r
- pat[h][i][i2][i3] -= l;\r
- m += (pat[h][i][i2][i3] * pat[h][i][i2][i3]);\r
- }\r
- }\r
- }\r
- patpow[h] = Math.sqrt((double) m);\r
- if (patpow[h] == 0.0) {\r
- patpow[h] = 0.0000001;\r
- }\r
-\r
- m = 0;\r
- for (int i = 0; i < height; i++) {\r
- for (int i2 = 0; i2 < width; i2++) {\r
- patBW[h][i][i2] -= l;\r
- m += (patBW[h][i][i2] * patBW[h][i][i2]);\r
- }\r
- }\r
- patpowBW[h] = Math.sqrt((double) m);\r
- if (patpowBW[h] == 0.0) {\r
- patpowBW[h] = 0.0000001;\r
- }\r
- }\r
- } catch (Exception e) {\r
- throw new NyARException(e);\r
- }\r
+ //ラスタにパターンをロードする。\r
+ NyARCodeFileReader.loadFromARToolKitFormFile(i_stream,this);\r
+ return;\r
}\r
}\r
*/\r
package jp.nyatla.nyartoolkit.core.match;\r
\r
-import jp.nyatla.nyartoolkit.NyARException;\r
import jp.nyatla.nyartoolkit.core.NyARCode;\r
-import jp.nyatla.nyartoolkit.core.pickup.INyARColorPatt;\r
\r
/**\r
- * ARColorPattのマッチング計算をするインタフェイスです。 基準Patに対して、計算済みのARCodeデータとの間で比較演算をします。\r
- * pattern_match関数を分解した3種類のパターン検出クラスを定義します。\r
- * \r
+ * ARCodeとINyARColorPattの間で一致計算をするインタフェイスです。\r
*/\r
public interface INyARMatchPatt\r
{\r
- public double getConfidence();\r
-\r
- public int getDirection();\r
-\r
- public void evaluate(NyARCode i_code);\r
-\r
- public boolean setPatt(INyARColorPatt i_target_patt) throws NyARException;\r
+ public void setARCode(NyARCode i_code);\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.match;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+\r
+\r
+/**\r
+ * INyARMatchPattのColor差分ラスタを格納するクラスです。\r
+ *\r
+ */\r
+public class NyARMatchPattDeviationBlackWhiteData\r
+{\r
+ private int _data[];\r
+ private double _pow;\r
+ //\r
+ private int _number_of_pixels;\r
+ public int[] refData()\r
+ {\r
+ return this._data;\r
+ }\r
+ public double getPow()\r
+ {\r
+ return this._pow;\r
+ }\r
+ \r
+ public NyARMatchPattDeviationBlackWhiteData(int i_width,int i_height)\r
+ {\r
+ this._number_of_pixels=i_height*i_width;\r
+ this._data=new int[this._number_of_pixels];\r
+ return;\r
+ }\r
+ /**\r
+ * XRGB[width*height]の配列から、パターンデータを構築。\r
+ * @param i_buffer\r
+ */\r
+ public void setRaster(INyARRaster i_raster)\r
+ {\r
+ //i_buffer[XRGB]→差分[BW]変換 \r
+ int i;\r
+ int ave;//<PV/>\r
+ int rgb;//<PV/>\r
+ final int[] linput=this._data;//<PV/>\r
+ final int[] buf=(int[])i_raster.getBufferReader().getBuffer();\r
+\r
+ // input配列のサイズとwhも更新// input=new int[height][width][3];\r
+ final int number_of_pixels=this._number_of_pixels;\r
+\r
+ //<平均値計算(FORの1/8展開)/>\r
+ ave = 0;\r
+ for(i=number_of_pixels-1;i>=0;i--){\r
+ rgb = buf[i];\r
+ ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);\r
+ }\r
+ ave=(number_of_pixels*255*3-ave)/(3*number_of_pixels);\r
+ //\r
+ int sum = 0,w_sum;\r
+ \r
+ //<差分値計算/>\r
+ for (i = number_of_pixels-1; i >= 0;i--) {\r
+ rgb = buf[i];\r
+ w_sum =((255*3-(rgb & 0xff)-((rgb >> 8) & 0xff)-((rgb >> 16) & 0xff))/3)-ave;\r
+ linput[i] = w_sum;\r
+ sum += w_sum * w_sum;\r
+ }\r
+ final double p=Math.sqrt((double) sum);\r
+ this._pow=p!=0.0?p:0.0000001;\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.match;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+\r
+/**\r
+ * INyARMatchPattのRGBColor差分データを格納するクラスです。\r
+ *\r
+ */\r
+public class NyARMatchPattDeviationColorData\r
+{\r
+ private int _data[];\r
+ private double _pow;\r
+ //\r
+ private int _number_of_pixels;\r
+ private int _optimize_for_mod;\r
+ public int[] refData()\r
+ {\r
+ return this._data;\r
+ }\r
+ public double getPow()\r
+ {\r
+ return this._pow;\r
+ }\r
+ \r
+ public NyARMatchPattDeviationColorData(int i_width,int i_height)\r
+ {\r
+ this._number_of_pixels=i_height*i_width;\r
+ this._data=new int[this._number_of_pixels*3];\r
+ this._optimize_for_mod=this._number_of_pixels-(this._number_of_pixels%8); \r
+ return;\r
+ }\r
+\r
+ \r
+ /**\r
+ * NyARRasterからパターンデータをセットします。\r
+ * この関数は、データを元に所有するデータ領域を更新します。\r
+ * @param i_buffer\r
+ */\r
+ public void setRaster(INyARRaster i_raster)\r
+ {\r
+ //画素フォーマット、サイズ制限\r
+ assert i_raster.getBufferReader().isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ assert i_raster.getSize().isEqualSize(i_raster.getSize());\r
+\r
+ final int[] buf=(int[])i_raster.getBufferReader().getBuffer();\r
+ //i_buffer[XRGB]→差分[R,G,B]変換 \r
+ int i;\r
+ int ave;//<PV/>\r
+ int rgb;//<PV/>\r
+ final int[] linput=this._data;//<PV/>\r
+\r
+ // input配列のサイズとwhも更新// input=new int[height][width][3];\r
+ final int number_of_pixels=this._number_of_pixels;\r
+ final int for_mod=this._optimize_for_mod;\r
+\r
+ //<平均値計算(FORの1/8展開)>\r
+ ave = 0;\r
+ for(i=number_of_pixels-1;i>=for_mod;i--){\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);\r
+ }\r
+ for (;i>=0;) {\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ }\r
+ //<平均値計算(FORの1/8展開)/>\r
+ ave=number_of_pixels*255*3-ave;\r
+ ave =255-(ave/ (number_of_pixels * 3));//(255-R)-ave を分解するための事前計算\r
+\r
+ int sum = 0,w_sum;\r
+ int input_ptr=number_of_pixels*3-1;\r
+ //<差分値計算(FORの1/8展開)>\r
+ for (i = number_of_pixels-1; i >= for_mod;i--) {\r
+ rgb = buf[i];\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ }\r
+ for (; i >=0;) {\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ }\r
+ //<差分値計算(FORの1/8展開)/>\r
+ final double p=Math.sqrt((double) sum);\r
+ this._pow=p!=0.0?p:0.0000001;\r
+ return;\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 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.match;\r
+\r
+public class NyARMatchPattResult\r
+{\r
+ public double confidence;\r
+ public int direction;\r
+}
\ No newline at end of file
\r
import jp.nyatla.nyartoolkit.NyARException;\r
import jp.nyatla.nyartoolkit.core.*;\r
-import jp.nyatla.nyartoolkit.core.pickup.INyARColorPatt;\r
\r
/**\r
- * AR_TEMPLATE_MATCHING_BWã\81¨å\90\8cç\89ã\81®ã\83«ã\83¼ã\83«ã\81§ ã\83\9eã\83¼ã\82«ã\83¼ã\82\92è©\95価ã\81\97ã\81¾ã\81\99ã\80\82\r
+ * AR_TEMPLATE_MATCHING_BWと同等のルールで マーカを評価します。\r
* \r
*/\r
public class NyARMatchPatt_BlackWhite implements INyARMatchPatt\r
{\r
- private double datapow;\r
-\r
- private int width;\r
-\r
- private int height;\r
-\r
- private double cf = 0;\r
-\r
- private int dir = 0;\r
-\r
- private int ave;\r
-\r
- private int[][][] input = new int[height][width][3];\r
-\r
- public boolean setPatt(INyARColorPatt i_target_patt) throws NyARException\r
+ protected NyARCode _code_patt; \r
+ protected int _pixels;\r
+ \r
+ public NyARMatchPatt_BlackWhite(int i_width, int i_height)\r
{\r
- width = i_target_patt.getWidth();\r
- height = i_target_patt.getHeight();\r
- int[][][] data = i_target_patt.getPatArray();\r
- input = new int[height][width][3];\r
-\r
- int sum = ave = 0;\r
- for (int i = 0; i < height; i++) {// for(int\r
- // i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
- for (int i2 = 0; i2 < width; i2++) {// for(int\r
- // i2=0;i2<Config.AR_PATT_SIZE_X;i2++){\r
- ave += (255 - data[i][i2][0]) + (255 - data[i][i2][1])\r
- + (255 - data[i][i2][2]);\r
- }\r
- }\r
- ave /= (height * width * 3);\r
-\r
- for (int i = 0; i < height; i++) {// for(int\r
- // i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
- for (int i2 = 0; i2 < width; i2++) {// for(int\r
- // i2=0;i2<Config.AR_PATT_SIZE_X;i2++){\r
- input[i][i2][0] = ((255 - data[i][i2][0])\r
- + (255 - data[i][i2][1]) + (255 - data[i][i2][2]))\r
- / 3 - ave;\r
- sum += input[i][i2][0] * input[i][i2][0];\r
- }\r
- }\r
-\r
- datapow = Math.sqrt((double) sum);\r
- if (datapow == 0.0) {\r
- return false;// throw new NyARException();\r
- // dir.set(0);//*dir = 0;\r
- // cf.set(-1.0);//*cf = -1.0;\r
- // return -1;\r
- }\r
- return true;\r
+ //最適化定数の計算\r
+ this._pixels=i_height*i_width;\r
+ return;\r
}\r
-\r
- public double getConfidence()\r
+ public NyARMatchPatt_BlackWhite(NyARCode i_code_ref)\r
{\r
- return cf;\r
- }\r
-\r
- public int getDirection()\r
+ //最適化定数の計算\r
+ this._pixels=i_code_ref.getWidth()*i_code_ref.getHeight();\r
+ this._code_patt=i_code_ref;\r
+ return;\r
+ } \r
+ /**\r
+ * 比較対象のARCodeをセットします。\r
+ * @throws NyARException\r
+ */\r
+ public void setARCode(NyARCode i_code_ref)\r
{\r
- return dir;\r
+ this._code_patt=i_code_ref;\r
+ return;\r
}\r
-\r
- public void evaluate(NyARCode i_code)\r
+ /**\r
+ * 現在セットされているコードとパターンを比較して、結果値o_resultを更新します。\r
+ * 比較部分はFor文を16倍展開してあります。\r
+ */\r
+ public boolean evaluate(NyARMatchPattDeviationBlackWhiteData i_patt,NyARMatchPattResult o_result) throws NyARException\r
{\r
- short[][][] patBW = i_code.getPatBW();// static int\r
- // patBW[AR_PATT_NUM_MAX][4][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
- double[] patpowBW = i_code.getPatPowBW();// static double\r
- // patpowBW[AR_PATT_NUM_MAX][4];\r
+ assert this._code_patt!=null;\r
\r
+ final int[] linput = i_patt.refData();\r
+ int sum;\r
double max = 0.0;\r
- int res = -1;\r
- // 本家が飛ぶ。試験データで0.77767376888がが出ればOKってことで\r
+ int res = NyARSquare.DIRECTION_UNKNOWN;\r
+ \r
+\r
for (int j = 0; j < 4; j++) {\r
- int sum = 0;\r
- for (int i = 0; i < height; i++) {\r
- for (int i2 = 0; i2 < width; i2++) {\r
- sum += input[i][i2][0] * patBW[j][i][i2];\r
- }\r
+ //合計値初期化\r
+ sum=0;\r
+ final NyARMatchPattDeviationBlackWhiteData code_patt=this._code_patt.getBlackWhiteData(j);\r
+ final int[] pat_j = code_patt.refData();\r
+ //<全画素について、比較(FORの1/16展開)/>\r
+ int i;\r
+ for(i=this._pixels-1;i>=0;i--){\r
+ sum += linput[i] * pat_j[i];\r
}\r
- double sum2 = sum / patpowBW[j] / datapow;\r
+ //0.7776737688877927がでればOK\r
+ final double sum2 = sum / code_patt.getPow() / i_patt.getPow();// sum2 = sum / patpow[k][j]/ datapow;\r
if (sum2 > max) {\r
max = sum2;\r
res = j;\r
}\r
}\r
- dir = res;\r
- cf = max;\r
+ o_result.direction = res;\r
+ o_result.confidence= max;\r
+ return true;\r
}\r
}\r
\r
import jp.nyatla.nyartoolkit.NyARException;\r
import jp.nyatla.nyartoolkit.core.*;\r
-import jp.nyatla.nyartoolkit.core.pickup.INyARColorPatt;\r
\r
/**\r
* AR_TEMPLATE_MATCHING_COLORかつAR_MATCHING_WITHOUT_PCAと同等のルールで マーカーを評価します。\r
*/\r
public class NyARMatchPatt_Color_WITHOUT_PCA implements INyARMatchPatt\r
{\r
- private int[][][] input = new int[1][1][3];\r
+ protected NyARCode _code_patt;\r
\r
- private double datapow;\r
-\r
- private int width = 1;\r
-\r
- private int height = 1;\r
-\r
- private double cf = 0;\r
-\r
- private int dir = 0;\r
-\r
- public double getConfidence()\r
+ protected int _optimize_for_mod;\r
+ protected int _rgbpixels;\r
+ public NyARMatchPatt_Color_WITHOUT_PCA(NyARCode i_code_ref)\r
{\r
- return cf;\r
+ int w=i_code_ref.getWidth();\r
+ int h=i_code_ref.getHeight();\r
+ //最適化定数の計算\r
+ this._rgbpixels=w*h*3;\r
+ this._optimize_for_mod=this._rgbpixels-(this._rgbpixels%16);\r
+ this.setARCode(i_code_ref);\r
+ return;\r
}\r
-\r
- public int getDirection()\r
+ public NyARMatchPatt_Color_WITHOUT_PCA(int i_width, int i_height)\r
{\r
- return dir;\r
+ //最適化定数の計算\r
+ this._rgbpixels=i_height*i_width*3;\r
+ this._optimize_for_mod=this._rgbpixels-(this._rgbpixels%16); \r
+ return;\r
}\r
-\r
/**\r
- * input配列サイズを必要に応じて再アロケートする。\r
- * \r
- * @param i_width\r
- * @param i_height\r
+ * 比較対象のARCodeをセットします。\r
+ * @throws NyARException\r
*/\r
- private void reallocInputArray(int i_width, int i_height)\r
- {\r
- if (this.input.length < i_height || this.input[0].length < i_width) {\r
- // 配列が十分なサイズでなければ取り直す\r
- this.input = new int[i_height][i_width][3];\r
- }\r
- this.height = i_height;\r
- this.width = i_width;\r
- }\r
-\r
- public boolean setPatt(INyARColorPatt i_target_patt) throws NyARException\r
+ public void setARCode(NyARCode i_code_ref)\r
{\r
- int i, k;\r
- int[][][] data, linput;\r
-\r
- // input配列のサイズとwhも更新// input=new int[height][width][3];\r
- reallocInputArray(i_target_patt.getWidth(), i_target_patt.getHeight());\r
- int lwidth = this.width;\r
- int lheight = this.height;\r
- linput = this.input;\r
- data = i_target_patt.getPatArray();\r
-\r
- int sum = 0, l_ave = 0, w_sum;\r
- int[][] data_i, input_i;\r
- int[] data_i_k, input_i_k;\r
- for (i = lheight - 1; i >= 0; i--) {// <Optimize/>for(int i=0;i<height;i++) {\r
- //for(int i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
- data_i = data[i];\r
- for (k = lwidth - 1; k >= 0; k--) {// <Optimize/>for(int\r
- // i2=0;i2<Config.AR_PATT_SIZE_X;i2++){\r
- // <Optimize/>l_ave +=(255-data[i][i2][0])+(255-data[i][i2][1])+(255-data[i][i2][2]);\r
- data_i_k = data_i[k];\r
- l_ave += 255 * 3 - data_i_k[0] - data_i_k[1] - data_i_k[2];\r
- }\r
- }\r
- l_ave /= (lheight * lwidth * 3);\r
- for (i = lheight - 1; i >= 0; i--) {// for(i=0;i<height;i++){//for(int i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
- input_i = linput[i];\r
- data_i = data[i];\r
- for (k = lwidth - 1; k >= 0; k--) {// for(i2=0;i2<width;i2++){//for(int i2=0;i2<Config.AR_PATT_SIZE_X;i2++){\r
- // <Optimize>\r
- // for(int i3=0;i3<3;i3++){\r
- // input[i][i2][i3] = (255-data[i][i2][i3]) - l_ave;\r
- // sum += input[i][i2][i3]*input[i][i2][i3];\r
- // }\r
- data_i_k = data_i[k];\r
- input_i_k = input_i[k];\r
- w_sum = (255 - data_i_k[0]) - l_ave;\r
- input_i_k[0] = w_sum;\r
- sum += w_sum * w_sum;\r
-\r
- w_sum = (255 - data_i_k[1]) - l_ave;\r
- input_i_k[1] = w_sum;\r
- sum += w_sum * w_sum;\r
-\r
- w_sum = (255 - data_i_k[2]) - l_ave;\r
- input_i_k[2] = w_sum;\r
- sum += w_sum * w_sum;\r
- // </Optimize>\r
- }\r
- }\r
- datapow = Math.sqrt((double) sum);\r
- if (datapow == 0.0) {\r
- return false;// throw new NyARException();\r
- // dir.set(0);//*dir = 0;\r
- // cf.set(-1.0);//*cf = -1.0;\r
- // return -1;\r
- }\r
- return true;\r
+ this._code_patt=i_code_ref;\r
+ return;\r
}\r
-\r
/**\r
- * public int pattern_match(short[][][] data,IntPointer dir,DoublePointer\r
- * cf)\r
- * \r
+ * 現在セットされているARコードとi_pattを比較します。\r
*/\r
- public void evaluate(NyARCode i_code)\r
+ public boolean evaluate(NyARMatchPattDeviationColorData i_patt,NyARMatchPattResult o_result) throws NyARException\r
{\r
- int[][][][] pat = i_code.getPat();\r
- double[] patpow = i_code.getPatPow();\r
- int res = -1;\r
+ assert this._code_patt!=null;\r
+ //\r
+ final int[] linput = i_patt.refData();\r
+ int sum;\r
double max = 0.0;\r
- int[][][] pat_j, linput;\r
- int[][] pat_j_i, input_i;\r
- int[] pat_j_i_k, input_i_k;\r
- int l_width = this.width;\r
- int l_height = this.height;\r
- linput = this.input;\r
+ int res = NyARSquare.DIRECTION_UNKNOWN;\r
+ final int for_mod=this._optimize_for_mod;\r
for (int j = 0; j < 4; j++) {\r
- int sum = 0;\r
- pat_j = pat[j];\r
- for (int i = l_height - 1; i >= 0; i--) {// for(int i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
- input_i = linput[i];\r
- pat_j_i = pat_j[i];\r
- for (int k = l_width - 1; k >= 0; k--) {\r
- pat_j_i_k = pat_j_i[k];\r
- input_i_k = input_i[k];\r
- // for(int i3=0;i3<3;i3++){\r
- sum += input_i_k[0] * pat_j_i_k[0];// sum +=input[i][i2][i3]*pat[k][j][i][i2][i3];\r
- sum += input_i_k[1] * pat_j_i_k[1];// sum +=input[i][i2][i3]*pat[k][j][i][i2][i3];\r
- sum += input_i_k[2] * pat_j_i_k[2];// sum +=input[i][i2][i3]*pat[k][j][i][i2][i3];\r
- // }\r
- }\r
+ //合計値初期化\r
+ sum=0;\r
+ final NyARMatchPattDeviationColorData code_patt=this._code_patt.getColorData(j);\r
+ final int[] pat_j = code_patt.refData();\r
+ //<全画素について、比較(FORの1/16展開)>\r
+ int i;\r
+ for(i=this._rgbpixels-1;i>=for_mod;i--){\r
+ sum += linput[i] * pat_j[i];\r
+ }\r
+ for (;i>=0;) {\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
}\r
- double sum2 = sum / patpow[j] / datapow;// sum2 = sum / patpow[k][j]/ datapow;\r
+ //<全画素について、比較(FORの1/16展開)/>\r
+ final double sum2 = sum / code_patt.getPow();// sum2 = sum / patpow[k][j]/ datapow;\r
if (sum2 > max) {\r
max = sum2;\r
res = j;\r
}\r
}\r
- dir = res;\r
- cf = max;\r
+ o_result.direction = res;\r
+ o_result.confidence= max/i_patt.getPow();\r
+ return true; \r
}\r
}
\ No newline at end of file
\r
import jp.nyatla.nyartoolkit.NyARException;\r
import jp.nyatla.nyartoolkit.core.NyARCode;\r
-import jp.nyatla.nyartoolkit.core.pickup.INyARColorPatt;\r
+import jp.nyatla.nyartoolkit.core.NyARSquare;\r
\r
/**\r
* AR_TEMPLATE_MATCHING_COLORかつAR_MATCHING_WITH_PCAと同等のルールで マーカーを評価します。\r
* \r
*/\r
-public class NyARMatchPatt_Color_WITH_PCA implements INyARMatchPatt\r
+public class NyARMatchPatt_Color_WITH_PCA extends NyARMatchPatt_Color_WITHOUT_PCA\r
{\r
private final int EVEC_MAX = 10;// #define EVEC_MAX 10\r
\r
private int evec_dim;// static int evec_dim;\r
-\r
- private int[][][] input;\r
-\r
- private double[][][][] evec;// static double evec[EVEC_MAX][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
-\r
+ private double[][] evec;// static double evec[EVEC_MAX][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
private double[][] epat = new double[4][EVEC_MAX];// static double epat[AR_PATT_NUM_MAX][4][EVEC_MAX];\r
\r
- private int ave;\r
-\r
- private double datapow;\r
-\r
- private int width;\r
-\r
- private int height;\r
-\r
- private double cf = 0;\r
\r
- private int dir = 0;// 向きか!\r
-\r
- public double getConfidence()\r
+ public NyARMatchPatt_Color_WITH_PCA(int i_width, int i_height)\r
{\r
- return cf;\r
+ super(i_width,i_height);\r
+ return;\r
}\r
-\r
- public int getDirection()\r
+ public NyARMatchPatt_Color_WITH_PCA(NyARCode i_code_ref)\r
{\r
- return dir;\r
- }\r
-\r
- public boolean setPatt(INyARColorPatt i_target_patt) throws NyARException\r
+ super(i_code_ref);\r
+ return;\r
+ } \r
+ public boolean evaluate(NyARMatchPattDeviationColorData i_patt,NyARMatchPattResult o_result) throws NyARException\r
{\r
- width = i_target_patt.getWidth();\r
- height = i_target_patt.getHeight();\r
- int[][][] data = i_target_patt.getPatArray();\r
-\r
- input = new int[height][width][3];\r
- evec = new double[EVEC_MAX][height][width][3];// static double evec[EVEC_MAX][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
+ final int[] linput = i_patt.refData();\r
int sum;\r
-\r
- sum = ave = 0;\r
- for (int i = 0; i < height; i++) {// for(int i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
- for (int i2 = 0; i2 < width; i2++) {// for(int i2=0;i2<Config.AR_PATT_SIZE_X;i2++){\r
- ave += (255 - data[i][i2][0]) + (255 - data[i][i2][1])\r
- + (255 - data[i][i2][2]);\r
- }\r
- }\r
- ave /= (height * width * 3);\r
-\r
- for (int i = 0; i < height; i++) {// for(int\r
- // i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
- for (int i2 = 0; i2 < width; i2++) {// for(int\r
- // i2=0;i2<Config.AR_PATT_SIZE_X;i2++){\r
- for (int i3 = 0; i3 < 3; i3++) {\r
- input[i][i2][i3] = (255 - data[i][i2][i3]) - ave;\r
- sum += input[i][i2][i3] * input[i][i2][i3];\r
- }\r
- }\r
- }\r
- datapow = Math.sqrt((double) sum);\r
- if (datapow == 0.0) {\r
- return false;// throw new NyARException();\r
- // dir.set(0);//*dir = 0;\r
- // cf.set(-1.0);//*cf = -1.0;\r
- // return -1;\r
- }\r
- return true;\r
- }\r
-\r
- /**\r
- * public int pattern_match(short[][][] data,IntPointer dir,DoublePointer\r
- * cf)\r
- * \r
- */\r
- public void evaluate(NyARCode i_code)\r
- {\r
- int[][][][] pat = i_code.getPat();\r
- double[] patpow = i_code.getPatPow();\r
- double[] invec = new double[EVEC_MAX];\r
-\r
- double max = 0.0; // fix VC7 compiler warning: uninitialized variable\r
- // 確認\r
- for (int i = 0; i < evec_dim; i++) {\r
+ double max = 0.0;\r
+ int res = NyARSquare.DIRECTION_UNKNOWN;\r
+/* \r
+ NyARException.trap(\r
+ "NyARMatchPatt_Color_WITH_PCA\n"+\r
+ "この箇所の移植は不完全です!"+\r
+ "ARToolKitの移植条件を完全に再現できていないため、evec,epatの計算が無視されています。"+\r
+ "gen_evec(void)も含めて移植の必要があるはずですが、まだ未解析です。");\r
+*/ double[] invec = new double[EVEC_MAX];\r
+ for (int i = 0; i < this.evec_dim; i++) {\r
invec[i] = 0.0;\r
- for (int j = 0; j < height; j++) {// for(int j = 0; j<Config.AR_PATT_SIZE_Y; j++){\r
- for (int j2 = 0; j2 < width; j2++) {\r
- for (int j3 = 0; j3 < 3; j3++) {\r
- invec[i] += evec[i][j][j2][j3] * input[j][j2][j3];// invec[i]+=evec[i][j]*input[j];\r
- }\r
- }\r
+ for(int j=0;j<this._rgbpixels;i++){\r
+ invec[i] += this.evec[i][j] * linput[j];\r
}\r
- invec[i] /= datapow;\r
+ invec[i] /= i_patt.getPow();\r
}\r
-\r
double min = 10000.0;\r
- int res = -1;\r
for (int j = 0; j < 4; j++) {\r
double sum2 = 0;\r
- for (int i = 0; i < evec_dim; i++) {\r
- sum2 += (invec[i] - epat[j][i]) * (invec[i] - epat[j][i]);\r
+ for (int i = 0; i < this.evec_dim; i++) {\r
+ sum2 += (invec[i] - this.epat[j][i]) * (invec[i] - this.epat[j][i]);\r
}\r
if (sum2 < min) {\r
min = sum2;\r
// res2 = k;//kは常にインスタンスを刺すから、省略可能\r
}\r
}\r
-\r
- int sum = 0;\r
- for (int i = 0; i < height; i++) {// for(int\r
- // i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
- for (int i2 = 0; i2 < width; i2++) {// for(int\r
- // i2=0;i<Config.AR_PATT_SIZE_X;i2++){\r
- for (int i3 = 0; i3 < 3; i3++) {\r
- sum += input[i][i2][i3] * pat[res][i][i2][i3];// sum +=input[i][i2][i3]*pat[res2][res][i][i2][i3];\r
- }\r
- }\r
+ sum=0;\r
+ final int[] code_data=this._code_patt.getColorData(res).refData();\r
+ for (int i = 0; i < this._rgbpixels; i++) {// for(int\r
+ sum += linput[i] * code_data[i];// sum +=input[i][i2][i3]*pat[res2][res][i][i2][i3];\r
}\r
- max = sum / patpow[res] / datapow;\r
- dir = res;\r
- cf = max;\r
+ max = sum / this._code_patt.getColorData(res).getPow() / i_patt.getPow();\r
+ o_result.direction = res;\r
+ o_result.confidence = max;\r
+ return true;\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.raster.*;\r
\r
-public interface INyARColorPatt\r
+public interface INyARColorPatt extends INyARRaster\r
{\r
/**\r
- * カラーパターンの幅をピクセル値で返します。\r
- * \r
- * @return\r
- */\r
- public int getWidth();\r
-\r
- /**\r
- * カラーパターンの高さをピクセル値で返します。\r
- * \r
- * @return\r
- */\r
- public int getHeight();\r
- /**\r
- * カメラパターンを格納した配列への参照値を返します。 配列は最低でも[height][wight][3]のサイズを持ちますが、\r
- * 配列のlengthとwidth,heightの数は一致しないことがあります。\r
- * setSize関数を実行すると、以前に呼び出されたgetPatArrayが返した値は不定になります。\r
- * \r
- * @return\r
- */\r
- public int[][][] getPatArray();\r
-\r
- /**\r
- * ラスタイメージからi_square部分のカラーパターンを抽出して、保持します。\r
+ * ラスタイメージからi_square部分のカラーパターンを抽出して、thisメンバに格納します。\r
* \r
* @param image\r
* @param i_square\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.NyARIntSize;\r
/**\r
* 24ビットカラーのマーカーを保持するために使うクラスです。 このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。\r
* 演算順序以外の最適化をしたもの\r
*/\r
public class NyARColorPatt_O1 implements INyARColorPatt\r
{\r
- private static final int AR_PATT_SAMPLE_NUM = 64;// #define\r
- // AR_PATT_SAMPLE_NUM 64\r
+ private static final int AR_PATT_SAMPLE_NUM = 64;\r
+ \r
+ private int[] _patdata;\r
+ private NyARBufferReader _buf_reader;\r
\r
- private int extpat[][][];\r
-\r
- private int width;\r
-\r
- private int height;\r
+ private NyARIntSize _size;\r
\r
public NyARColorPatt_O1(int i_width, int i_height)\r
{\r
- this.width = i_width;\r
- this.height = i_height;\r
- this.extpat = new int[i_height][i_width][3];\r
- this.wk_pickFromRaster_ext_pat2 = new int[i_height][i_width][3];\r
- }\r
-\r
- // public void setSize(int i_new_width,int i_new_height)\r
- // {\r
- // int array_w=this.extpat[0].length;\r
- // int array_h=this.extpat.length;\r
- // //十分なサイズのバッファがあるか確認\r
- // if(array_w>=i_new_width && array_h>=i_new_height){\r
- // //OK 十分だ→サイズ調整のみ\r
- // }else{\r
- // //足りないよ→取り直し\r
- // this.wk_pickFromRaster_ext_pat2=new int[i_new_height][i_new_width][3];\r
- // this.extpat=new int[i_new_height][i_new_width][3];\r
- // }\r
- // this.width =i_new_width;\r
- // this.height=i_new_height;\r
- // return;\r
- // }\r
-\r
- public int[][][] getPatArray()\r
- {\r
- return extpat;\r
+ //入力制限\r
+ assert i_width<=64;\r
+ assert 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
+ return;\r
}\r
\r
public int getWidth()\r
{\r
- return width;\r
+ return this._size.w;\r
}\r
-\r
public int getHeight()\r
{\r
- return height;\r
+ return this._size.h;\r
+ }\r
+ public NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ }\r
+ public INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buf_reader;\r
}\r
\r
private final NyARMat wk_get_cpara_a = new NyARMat(8, 8);\r
* [3x3]\r
* @throws NyARException\r
*/\r
- private boolean get_cpara(double world[][], double vertex[][], double[] para)\r
- throws NyARException\r
+ private boolean get_cpara(double world[][], double vertex[][], double[] para)throws NyARException\r
{\r
NyARMat a = wk_get_cpara_a;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );\r
double[][] a_array = a.getArray();\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] =\r
- // -world[i][0] *\r
- // vertex[i][0];\r
- a_pt0[7] = -world_pti[1] * vertex[i][0];// a->m[i*16+7] =\r
- // -world[i][1] *\r
- // vertex[i][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_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[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] =\r
- // -world[i][0] *\r
- // vertex[i][1];\r
- a_pt1[7] = -world_pti[1] * vertex[i][1];// a->m[i*16+15] =\r
- // -world[i][1] *\r
- // vertex[i][1];\r
- b_array[i * 2 + 0][0] = vertex[i][0];// b->m[i*2+0] =\r
- // vertex[i][0];\r
- b_array[i * 2 + 1][0] = vertex[i][1];// b->m[i*2+1] =\r
- // vertex[i][1];\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
}\r
- // JartkException.trap("未チェックのパス");\r
if (!a.matrixSelfInv()) {\r
return false;// 逆行列を求められないので失敗\r
}\r
-\r
- // JartkException.trap("未チェックのパス");\r
NyARMat c = wk_get_cpara_c;// 次処理で結果を受け取るので、初期化不要//new NyARMat( 8, 1 );\r
double[][] c_array = c.getArray();\r
\r
\r
private final double[] wk_pickFromRaster_para = new double[9];// [3][3];\r
\r
- private int[][][] wk_pickFromRaster_ext_pat2 = null;// コンストラクタでint[height][width][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 },\r
- { 100.0, 100.0 + 10.0 } };\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
- * pickFromRaster関数から使う変数です。\r
- * \r
- */\r
- private static void initValue_wk_pickFromRaster_ext_pat2(\r
- int[][][] i_ext_pat2, int i_width, int i_height)\r
- {\r
- int i, i2;\r
- int[][] pt2;\r
- int[] pt1;\r
- for (i = i_height - 1; i >= 0; i--) {\r
- pt2 = i_ext_pat2[i];\r
- for (i2 = i_width - 1; i2 >= 0; i2--) {\r
- pt1 = pt2[i2];\r
- pt1[0] = 0;\r
- pt1[1] = 0;\r
- pt1[2] = 0;\r
- }\r
- }\r
- }\r
\r
private final int[] wk_pickFromRaster_rgb_tmp = new int[3];\r
\r
*/\r
public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
{\r
- double d, xw, yw;\r
- int xc, yc;\r
- int xdiv, ydiv;\r
- int xdiv2, ydiv2;\r
int lx1, lx2, ly1, ly2;\r
\r
int img_x = image.getWidth();\r
if (!get_cpara(world, local, para)) {\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])\r
- * (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])\r
- * (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])\r
- * (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])\r
- * (local[3][1] - local[0][1]));\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
if (lx2 > lx1) {\r
lx1 = lx2;\r
}\r
if (ly2 > ly1) {\r
ly1 = ly2;\r
}\r
- xdiv2 = this.width;\r
- ydiv2 = this.height;\r
+ int sample_pixel_x = this._size.w;\r
+ int sample_pixel_y = this._size.h;\r
\r
- while (xdiv2 * xdiv2 < lx1 / 4) {\r
- xdiv2 *= 2;\r
+ while (sample_pixel_x * sample_pixel_x < lx1 / 4) {\r
+ sample_pixel_x *= 2;\r
}\r
- while (ydiv2 * ydiv2 < ly1 / 4) {\r
- ydiv2 *= 2;\r
+ while (sample_pixel_y * sample_pixel_y < ly1 / 4) {\r
+ sample_pixel_y *= 2;\r
}\r
\r
- if (xdiv2 > AR_PATT_SAMPLE_NUM) {\r
- xdiv2 = AR_PATT_SAMPLE_NUM;\r
+ if (sample_pixel_x > AR_PATT_SAMPLE_NUM) {\r
+ sample_pixel_x = AR_PATT_SAMPLE_NUM;\r
}\r
- if (ydiv2 > AR_PATT_SAMPLE_NUM) {\r
- ydiv2 = AR_PATT_SAMPLE_NUM;\r
+ if (sample_pixel_y > AR_PATT_SAMPLE_NUM) {\r
+ sample_pixel_y = AR_PATT_SAMPLE_NUM;\r
}\r
\r
- xdiv = xdiv2 / width;// xdiv = xdiv2/Config.AR_PATT_SIZE_X;\r
- ydiv = ydiv2 / height;// ydiv = ydiv2/Config.AR_PATT_SIZE_Y;\r
+ final int xdiv = sample_pixel_x / this._size.w;// xdiv = xdiv2/Config.AR_PATT_SIZE_X;\r
+ final int ydiv = sample_pixel_y / this._size.h;// ydiv = ydiv2/Config.AR_PATT_SIZE_Y;\r
\r
- /* wk_pickFromRaster_ext_pat2ワーク変数を初期化する。 */\r
- int[][][] ext_pat2 = wk_pickFromRaster_ext_pat2;// ARUint32 ext_pat2[AR_PATT_SIZE_Y][AR_PATT_SIZE_X][3];\r
- int extpat_j[][], extpat_j_i[];\r
- int ext_pat2_j[][], ext_pat2_j_i[];\r
\r
- initValue_wk_pickFromRaster_ext_pat2(ext_pat2, this.width, this.height);\r
-\r
- xdiv2_reciprocal = 1.0 / xdiv2;\r
- ydiv2_reciprocal = 1.0 / ydiv2;\r
- int i, j;\r
+ xdiv2_reciprocal = 1.0 / sample_pixel_x;\r
+ ydiv2_reciprocal = 1.0 / sample_pixel_y;\r
+ int r,g,b;\r
int[] rgb_tmp = wk_pickFromRaster_rgb_tmp;\r
\r
//ピクセルリーダーを取得\r
INyARRgbPixelReader reader=image.getRgbPixelReader();\r
- \r
- // arGetCode_put_zero(ext_pat2);//put_zero( (ARUint8 *)ext_pat2,\r
- // AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3*sizeof(ARUint32) );\r
- for (j = 0; j < ydiv2; j++) {\r
- yw = 102.5 + 5.0 * (j + 0.5) * ydiv2_reciprocal;\r
- for (i = 0; i < xdiv2; i++) {\r
- xw = 102.5 + 5.0 * (i + 0.5) * xdiv2_reciprocal;\r
- d = para[2 * 3 + 0] * xw + para[2 * 3 + 1] * yw+ para[2 * 3 + 2];\r
- if (d == 0) {\r
- throw new NyARException();\r
+ final int xdiv_x_ydiv = xdiv * ydiv;\r
+\r
+ for(int iy=0;iy<this._size.h;iy++){\r
+ for(int ix=0;ix<this._size.w;ix++){\r
+ r=g=b=0;\r
+ //1ピクセルを作成\r
+ for(int j=0;j<ydiv;j++){\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
+ 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
+ \r
+ if (xc >= 0 && xc < img_x && yc >= 0 && yc < img_y) {\r
+ reader.getPixel(xc, yc, rgb_tmp);\r
+ r += rgb_tmp[0];// R\r
+ g += rgb_tmp[1];// G\r
+ b += rgb_tmp[2];// B\r
+ // System.out.println(xc+":"+yc+":"+rgb_tmp[0]+":"+rgb_tmp[1]+":"+rgb_tmp[2]);\r
+ }\r
+ }\r
}\r
- xc = (int) ((para[0 * 3 + 0] * xw + para[0 * 3 + 1] * yw + para[0 * 3 + 2]) / d);\r
- yc = (int) ((para[1 * 3 + 0] * xw + para[1 * 3 + 1] * yw + para[1 * 3 + 2]) / d);\r
-\r
- if (xc >= 0 && xc < img_x && yc >= 0 && yc < img_y) {\r
- reader.getPixel(xc, yc, rgb_tmp);\r
- ext_pat2_j_i = ext_pat2[j / ydiv][i / xdiv];\r
-\r
- ext_pat2_j_i[0] += rgb_tmp[0];// R\r
- ext_pat2_j_i[1] += rgb_tmp[1];// G\r
- ext_pat2_j_i[2] += rgb_tmp[2];// B\r
- // System.out.println(xc+":"+yc+":"+rgb_tmp[0]+":"+rgb_tmp[1]+":"+rgb_tmp[2]);\r
- }\r
- }\r
- }\r
- // short[][][] ext_pat=new short[Config.AR_PATT_SIZE_Y][Config.AR_PATT_SIZE_X][3];//ARUint32\r
- // ext_pat2[AR_PATT_SIZE_Y][AR_PATT_SIZE_X][3];\r
- /* <Optimize> */\r
- int xdiv_x_ydiv = xdiv * ydiv;\r
- for (j = this.height - 1; j >= 0; j--) {\r
- extpat_j = extpat[j];\r
- ext_pat2_j = ext_pat2[j];\r
- for (i = this.width - 1; i >= 0; i--) { // PRL 2006-06-08.\r
- ext_pat2_j_i = ext_pat2_j[i];\r
- extpat_j_i = extpat_j[i];\r
- extpat_j_i[0] = (ext_pat2_j_i[0] / xdiv_x_ydiv);// ext_pat[j][i][0]=(byte)(ext_pat2[j][i][0] / (xdiv*ydiv));\r
- extpat_j_i[1] = (ext_pat2_j_i[1] / xdiv_x_ydiv);// ext_pat[j][i][1]=(byte)(ext_pat2[j][i][1]/(xdiv*ydiv));\r
- extpat_j_i[2] = (ext_pat2_j_i[2] / xdiv_x_ydiv);// ext_pat[j][i][2]=(byte)(ext_pat2[j][i][2]/(xdiv*ydiv));\r
+ this._patdata[iy*this._size.w+ix]=(((r / xdiv_x_ydiv)&0xff)<<16)|(((g / xdiv_x_ydiv)&0xff)<<8)|(((b / xdiv_x_ydiv)&0xff));\r
}\r
}\r
return true;\r
}\r
+ \r
}
\ No newline at end of file
*/\r
public class NyARColorPatt_O3 implements INyARColorPatt\r
{\r
- private static final int AR_PATT_SAMPLE_NUM = 64;// #define\r
- // AR_PATT_SAMPLE_NUM 64\r
-\r
- private int[][][] extpat;\r
-\r
- private int width;\r
-\r
- private int height;\r
+ private static final int AR_PATT_SAMPLE_NUM = 64;\r
\r
+ private int[] _patdata;\r
+ private NyARBufferReader _buf_reader;\r
+ private NyARIntSize _size;\r
+ \r
public NyARColorPatt_O3(int i_width, int i_height)\r
{\r
- this.width = i_width;\r
- this.height = i_height;\r
- this.extpat = new int[i_height][i_width][3];\r
- }\r
-\r
- // public void setSize(int i_new_width,int i_new_height)\r
- // {\r
- // int array_w=this.extpat[0].length;\r
- // int array_h=this.extpat.length;\r
- // //十分なサイズのバッファがあるか確認\r
- // if(array_w>=i_new_width && array_h>=i_new_height){\r
- // //OK 十分だ→サイズ調整のみ\r
- // }else{\r
- // //足りないよ→取り直し\r
- // this.extpat=new int[i_new_height][i_new_width][3];\r
- // }\r
- // this.width =i_new_width;\r
- // this.height=i_new_height;\r
- // return;\r
- // }\r
- public int[][][] getPatArray()\r
- {\r
- return extpat;\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
}\r
-\r
public int getWidth()\r
{\r
- return width;\r
+ return this._size.w;\r
}\r
-\r
public int getHeight()\r
{\r
- return height;\r
+ return this._size.h;\r
+ }\r
+ public NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ }\r
+ public INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buf_reader;\r
}\r
\r
private final NyARMat wk_get_cpara_a = new NyARMat(8, 8);\r
private final int[][] wk_pickFromRaster_world = {// double world[4][2];\r
{ 100, 100 }, { 100 + 10, 100 }, { 100 + 10, 100 + 10 }, { 100, 100 + 10 } };\r
\r
- /**\r
- * pickFromRaster関数から使う変数です。\r
- * \r
- */\r
- private static void initValue_wk_pickFromRaster_ext_pat2(int[][][] i_ext_pat2, int i_width, int i_height)\r
- {\r
- int i, i2;\r
- int[][] pt2;\r
- int[] pt1;\r
- for (i = i_height - 1; i >= 0; i--) {\r
- pt2 = i_ext_pat2[i];\r
- for (i2 = i_width - 1; i2 >= 0; i2--) {\r
- pt1 = pt2[i2];\r
- pt1[0] = 0;\r
- pt1[1] = 0;\r
- pt1[2] = 0;\r
- }\r
- }\r
- }\r
\r
private final NyARMat wk_pickFromRaster_cpara = new NyARMat(8, 1);\r
\r
{\r
NyARMat cpara = this.wk_pickFromRaster_cpara;\r
NyARIntPoint[] local = i_square.imvertex;\r
- // //localの計算\r
- // int[] local_0=wk_pickFromRaster_local[0];//double local[4][2];\r
- // int[] local_1=wk_pickFromRaster_local[1];//double local[4][2];\r
- // //\r
- // for(int i = 0; i < 4; i++ ) {\r
- // local_0[i] = i_square.imvertex[i][0];\r
- // local_1[i] = i_square.imvertex[i][1];\r
- // }\r
// xdiv2,ydiv2の計算\r
int xdiv2, ydiv2;\r
int l1, l2;\r
int w1, w2;\r
-\r
// x計算\r
w1 = local[0].x - local[1].x;\r
w2 = local[0].y - local[1].y;\r
l1 = l2;\r
}\r
l1 = l1 / 4;\r
- xdiv2 = this.width;\r
+ xdiv2 = this._size.w;\r
while (xdiv2 * xdiv2 < l1) {\r
xdiv2 *= 2;\r
}\r
if (l2 > l1) {\r
l1 = l2;\r
}\r
- ydiv2 = this.height;\r
+ ydiv2 = this._size.h;\r
l1 = l1 / 4;\r
while (ydiv2 * ydiv2 < l1) {\r
ydiv2 *= 2;\r
\r
return true;\r
}\r
-\r
- // かなり大きいワークバッファを取るな…。\r
- private double[] wk_updateExtpat_para00_xw;\r
-\r
- private double[] wk_updateExtpat_para10_xw;\r
-\r
- private double[] wk_updateExtpat_para20_xw;\r
-\r
- private int[] wk_updateExtpat_rgb_buf;\r
-\r
- private int[] wk_updateExtpat_x_rgb_index;\r
-\r
- private int[] wk_updateExtpat_y_rgb_index;\r
-\r
- private int[] wk_updateExtpat_i_rgb_index;\r
-\r
- private int wk_updateExtpat_buffer_size = 0;\r
-\r
- /**\r
- * ワークバッファを予約する\r
- * \r
- * @param i_xdiv2\r
- */\r
- private void reservWorkBuffers(int i_xdiv2)\r
+ private int[] __updateExtpat_rgbset;\r
+ private int[] __updateExtpat_xc;\r
+ private int[] __updateExtpat_yc;\r
+ private double[] __updateExtpat_xw;\r
+ private double[] __updateExtpat_yw;\r
+ private int _last_pix_resolution_x=0;\r
+ private int _last_pix_resolution_y=0;\r
+ private void reservWorkBuffers(int i_xdiv,int i_ydiv)\r
{\r
- if (this.wk_updateExtpat_buffer_size < i_xdiv2) {\r
- wk_updateExtpat_para00_xw = new double[i_xdiv2];\r
- wk_updateExtpat_para10_xw = new double[i_xdiv2];\r
- wk_updateExtpat_para20_xw = new double[i_xdiv2];\r
- wk_updateExtpat_rgb_buf = new int[i_xdiv2 * 3];\r
- wk_updateExtpat_x_rgb_index = new int[i_xdiv2];\r
- wk_updateExtpat_y_rgb_index = new int[i_xdiv2];\r
- wk_updateExtpat_i_rgb_index = new int[i_xdiv2];\r
- this.wk_updateExtpat_buffer_size = i_xdiv2;\r
+ if(this._last_pix_resolution_x<i_xdiv || this._last_pix_resolution_y<i_ydiv){\r
+ this.__updateExtpat_xc=new int[i_xdiv*i_ydiv];\r
+ this.__updateExtpat_yc=new int[i_xdiv*i_ydiv];\r
+ this.__updateExtpat_xw=new double[i_xdiv];\r
+ this.__updateExtpat_yw=new double[i_ydiv];\r
+ this.__updateExtpat_rgbset=new int[i_xdiv*i_ydiv*3];\r
}\r
- // 十分なら何もしない。\r
return;\r
- }\r
-\r
+ } \r
+ \r
+ //分割数16未満になると少し遅くなるかも。\r
private void updateExtpat(INyARRgbRaster image, NyARMat i_cpara, int i_xdiv2,int i_ydiv2) throws NyARException\r
{\r
- int img_x = image.getWidth();\r
- int img_y = image.getHeight();\r
- final int[][][] L_extpat = this.extpat;\r
- final int L_WIDTH = this.width;\r
- final int L_HEIGHT = this.height;\r
- /* wk_pickFromRaster_ext_pat2ワーク変数を初期化する。 */\r
- // int[][][] ext_pat2=wk_pickFromRaster_ext_pat2;//ARUint32\r
- // ext_pat2[AR_PATT_SIZE_Y][AR_PATT_SIZE_X][3];\r
- int[][] extpat_j;\r
- int[] extpat_j_i;\r
- // int ext_pat2_j[][],ext_pat2_j_i[];\r
-\r
- initValue_wk_pickFromRaster_ext_pat2(L_extpat, L_WIDTH, L_HEIGHT);\r
\r
- double[][] cpara_array = i_cpara.getArray();\r
- double para21_x_yw, para01_x_yw, para11_x_yw;\r
- double para00, para01, para02, para10, para11, para12, para20, para21;\r
- para00 = cpara_array[0 * 3 + 0][0];// para[i][0] = c->m[i*3+0];\r
- para01 = cpara_array[0 * 3 + 1][0];// para[i][1] = c->m[i*3+1];\r
- para02 = cpara_array[0 * 3 + 2][0];// para[i][2] = c->m[i*3+2];\r
- para10 = cpara_array[1 * 3 + 0][0];// para[i][0] = c->m[i*3+0];\r
- para11 = cpara_array[1 * 3 + 1][0];// para[i][1] = c->m[i*3+1];\r
- para12 = cpara_array[1 * 3 + 2][0];// para[i][2] = c->m[i*3+2];\r
- para20 = cpara_array[2 * 3 + 0][0];// para[2][0] = c->m[2*3+0];\r
- para21 = cpara_array[2 * 3 + 1][0];// para[2][1] = c->m[2*3+1];\r
+ int i,j;\r
+ int r,g,b;\r
+ //ピクセルリーダーを取得\r
+ final int pat_size_w=this._size.w;\r
+ final int xdiv = i_xdiv2 / pat_size_w;// xdiv = xdiv2/Config.AR_PATT_SIZE_X;\r
+ final int ydiv = i_ydiv2 / this._size.h;// ydiv = ydiv2/Config.AR_PATT_SIZE_Y;\r
+ final int xdiv_x_ydiv = xdiv * ydiv;\r
+ double reciprocal;\r
+ final double[][] para=i_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
\r
- double d, yw;\r
- int xc, yc;\r
- int i, j;\r
- // arGetCode_put_zero(ext_pat2);//put_zero( (ARUint8 *)ext_pat2,\r
- // AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3*sizeof(ARUint32) );\r
- int xdiv = i_xdiv2 / L_WIDTH;// xdiv = xdiv2/Config.AR_PATT_SIZE_X;\r
- int ydiv = i_ydiv2 / L_HEIGHT;// ydiv = ydiv2/Config.AR_PATT_SIZE_Y;\r
+ INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+ final int img_width=image.getWidth();\r
+ final int img_height=image.getHeight();\r
\r
- // 計算バッファを予約する\r
- this.reservWorkBuffers(i_xdiv2);\r
- double[] para00_xw = this.wk_updateExtpat_para00_xw;\r
- double[] para10_xw = this.wk_updateExtpat_para10_xw;\r
- double[] para20_xw = this.wk_updateExtpat_para20_xw;\r
- int[] x_rgb_index = this.wk_updateExtpat_x_rgb_index;\r
- int[] y_rgb_index = this.wk_updateExtpat_y_rgb_index;\r
- int[] i_rgb_index = this.wk_updateExtpat_i_rgb_index;\r
- int[] rgb_buf = this.wk_updateExtpat_rgb_buf;\r
- double xw;\r
- for (i = 0; i < i_xdiv2; i++) {\r
- xw = 102.5 + 5.0 * ((double) i + 0.5) / i_xdiv2;\r
- para20_xw[i] = para20 * xw;\r
- para00_xw[i] = para00 * xw;\r
- para10_xw[i] = para10 * xw;\r
- }\r
+ //ワークバッファの準備\r
+ reservWorkBuffers(xdiv,ydiv);\r
+ final double xw[]=this.__updateExtpat_xw;\r
+ final double yw[]=this.__updateExtpat_yw;\r
+ final int[] xc=this.__updateExtpat_xc;\r
+ final int[] yc=this.__updateExtpat_yc;\r
+ int[] rgb_set = this.__updateExtpat_rgbset;\r
\r
- int index_num;\r
- //ピクセルリーダーを取得\r
- INyARRgbPixelReader reader=image.getRgbPixelReader();\r
\r
- for (j = 0; j < i_ydiv2; j++) {\r
- yw = 102.5 + 5.0 * ((double) j + 0.5) / i_ydiv2;\r
- para21_x_yw = para21 * yw + 1.0;\r
- para11_x_yw = para11 * yw + para12;\r
- para01_x_yw = para01 * yw + para02;\r
- extpat_j = L_extpat[j / ydiv];\r
- index_num = 0;\r
- // ステップ1.RGB取得用のマップを作成\r
- for (i = 0; i < i_xdiv2; i++) {\r
- d = para20_xw[i] + para21_x_yw;\r
- if (d == 0) {\r
- throw new NyARException();\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
}\r
- xc = (int) ((para00_xw[i] + para01_x_yw) / d);\r
- yc = (int) ((para10_xw[i] + para11_x_yw) / d);\r
- // 範囲外は無視\r
- if (xc < 0 || xc >= img_x || yc < 0 || yc >= img_y) {\r
- continue;\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
}\r
- // ピクセル値の計算\r
- // image.getPixel(xc,yc,rgb_buf);\r
- // ext_pat2_j_i=ext_pat2_j[i/xdiv];\r
- // ext_pat2_j_i[0] += rgb_buf[0];//R\r
- // ext_pat2_j_i[1] += rgb_buf[1];//G\r
- // ext_pat2_j_i[2] += rgb_buf[2];//B\r
-\r
- x_rgb_index[index_num] = xc;\r
- y_rgb_index[index_num] = yc;\r
- i_rgb_index[index_num] = i / xdiv;\r
- index_num++;\r
- }\r
- // //ステップ2.ピクセル配列を取得\r
- reader.getPixelSet(x_rgb_index, y_rgb_index, index_num, rgb_buf);\r
- // //ピクセル値の計算\r
- for (i = index_num - 1; i >= 0; i--) {\r
- extpat_j_i = extpat_j[i_rgb_index[i]];\r
- extpat_j_i[0] += rgb_buf[i * 3 + 0];// R\r
- extpat_j_i[1] += rgb_buf[i * 3 + 1];// G\r
- extpat_j_i[2] += rgb_buf[i * 3 + 2];// B\r
- }\r
- }\r
- /* <Optimize> */\r
- int xdiv_x_ydiv = xdiv * ydiv;\r
- for (j = L_HEIGHT - 1; j >= 0; j--) {\r
- extpat_j = L_extpat[j];\r
- for (i = L_WIDTH - 1; i >= 0; i--) { // PRL 2006-06-08.\r
- extpat_j_i = extpat_j[i];\r
- extpat_j_i[0] /= (xdiv_x_ydiv);// ext_pat[j][i][0] =(byte)(ext_pat2[j][i][0] /(xdiv*ydiv));\r
- extpat_j_i[1] /= (xdiv_x_ydiv);// ext_pat[j][i][1] =(byte)(ext_pat2[j][i][1] /(xdiv*ydiv));\r
- extpat_j_i[2] /= (xdiv_x_ydiv);// ext_pat[j][i][2] =(byte)(ext_pat2[j][i][2] /(xdiv*ydiv));\r
+ //xc,ycマップを作成\r
+ int number_of_pix=0;\r
+ for(i=ydiv-1;i>=0;i--)\r
+ {\r
+ final double para01_x_yw_para02=para01 * yw[i] + para02;\r
+ final double para11_x_yw_para12=para11 * yw[i] + para12;\r
+ final double para12_x_yw_para22=para21 * yw[i]+ 1.0;\r
+ for(j=xdiv-1;j>=0;j--){\r
+ \r
+ final double d = para20 * xw[j] + para12_x_yw_para22;\r
+ if (d == 0) {\r
+ throw new NyARException();\r
+ }\r
+ final int xcw= (int) ((para00 * xw[j] + para01_x_yw_para02) / d);\r
+ final int ycw= (int) ((para10 * xw[j] + para11_x_yw_para12) / d);\r
+ if(xcw<0 || xcw>=img_width || ycw<0 ||ycw>=img_height){\r
+ continue;\r
+ }\r
+ xc[number_of_pix] =xcw;\r
+ yc[number_of_pix] =ycw;\r
+ number_of_pix++;\r
+ }\r
+ }\r
+ //ピクセル取得とピクセル値の計算\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
+ r += rgb_set[i-2];// R\r
+ g += rgb_set[i-1];// G\r
+ b += rgb_set[i];// B\r
+ }\r
+ //1ピクセル確定\r
+ this._patdata[iy*pat_size_w+ix]=(((r / xdiv_x_ydiv)&0xff)<<16)|(((g / xdiv_x_ydiv)&0xff)<<8)|(((b / xdiv_x_ydiv)&0xff));\r
}\r
}\r
return;\r
import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
import jp.nyatla.nyartoolkit.core.types.*;\r
\r
-public final class NyARBinRaster extends NyARRaster_BasicClass\r
+public class NyARBinRaster extends NyARRaster_BasicClass\r
{\r
private INyARBufferReader _buffer_reader;\r
protected int[] _ref_buf;\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.raster;\r
+\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**このクラスは、単機能のNyARRasterです。\r
+ * 特定タイプのバッファをラップする、INyARBufferReaderインタフェイスを提供します。\r
+ *\r
+ */\r
+public final class NyARRaster extends NyARRaster_BasicClass\r
+{\r
+ private NyARBufferReader _reader;\r
+ public INyARBufferReader getBufferReader()\r
+ {\r
+ return this._reader;\r
+ }\r
+ public NyARRaster(NyARIntSize i_size,Object i_ref_buf,int i_buf_type)\r
+ {\r
+ super(i_size);\r
+ this._reader=new NyARBufferReader(i_ref_buf,i_buf_type);\r
+ return;\r
+ }\r
+}
\ No newline at end of file
\r
public void getPixel(int i_x, int i_y, int[] o_rgb)\r
{\r
- byte[] ref_buf = this._parent._ref_buf;\r
- int bp = (i_x + i_y * this._parent._size.w) * 4;\r
+ final byte[] ref_buf = this._parent._ref_buf;\r
+ final int bp = (i_x + i_y * this._parent._size.w) * 4;\r
o_rgb[0] = (ref_buf[bp + 2] & 0xff);// R\r
o_rgb[1] = (ref_buf[bp + 1] & 0xff);// G\r
o_rgb[2] = (ref_buf[bp + 0] & 0xff);// B\r
\r
public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
{\r
- int width = _parent._size.w;\r
- byte[] ref_buf = _parent._ref_buf;\r
int bp;\r
+ final int width = _parent._size.w;\r
+ final byte[] ref_buf = _parent._ref_buf;\r
for (int i = i_num - 1; i >= 0; i--) {\r
bp = (i_x[i] + i_y[i] * width) * 4;\r
o_rgb[i * 3 + 0] = (ref_buf[bp + 2] & 0xff);// R\r
o_rgb[i * 3 + 1] = (ref_buf[bp + 1] & 0xff);// G\r
o_rgb[i * 3 + 2] = (ref_buf[bp + 0] & 0xff);// B\r
}\r
+ return;\r
}\r
}\r
\r
package jp.nyatla.nyartoolkit.core.raster.rgb;\r
\r
import jp.nyatla.nyartoolkit.NyARException;\r
-import jp.nyatla.nyartoolkit.core.raster.NyARRaster_BasicClass;\r
import jp.nyatla.nyartoolkit.core.rasterreader.INyARRgbPixelReader;\r
import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
\r
* \r
* \r
*/\r
-public abstract class NyARRgbRaster_BasicClass extends NyARRaster_BasicClass implements INyARRgbRaster\r
+public abstract class NyARRgbRaster_BasicClass implements INyARRgbRaster\r
{\r
+ final protected NyARIntSize _size;\r
+ final public int getWidth()\r
+ {\r
+ return this._size.w;\r
+ }\r
+\r
+ final public int getHeight()\r
+ {\r
+ return this._size.h;\r
+ }\r
+\r
+ final public NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ } \r
protected NyARRgbRaster_BasicClass(final NyARIntSize i_size)\r
{\r
- super(i_size);\r
+ this._size= i_size;\r
}\r
public INyARRgbPixelReader getRgbPixcelReader() throws NyARException\r
{\r
o_rgb[i * 3 + 1] = 0;// G\r
o_rgb[i * 3 + 2] = 0;// B\r
}\r
- }\r
+ } \r
}\r
\r
private INyARRgbPixelReader _reader;\r
public void getPixel(int i_x, int i_y, int[] i_rgb) throws NyARException;\r
\r
/**\r
- * 複数のピクセル値をi_rgbへ返します。\r
+ * 複数のピクセル値をint配列に返します。\r
+ * 配列には、[R1][G1][B1][R2][G2][B2]の順でピクセル値が格納されます。\r
* \r
* @param i_x\r
* xのインデックス配列\r
* @param i_y\r
* yのインデックス配列\r
- * @param i_num\r
- * 返すピクセル値の数\r
- * @param i_rgb\r
- * ピクセル値を返すバッファ\r
*/\r
- public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] i_rgb) throws NyARException;\r
+ public void getPixelSet(int i_x[], int i_y[], int i_num, int[] i_intrgb) throws NyARException;\r
}\r
*/\r
package jp.nyatla.nyartoolkit.core.rasterreader;\r
\r
-public class NyARBufferReader implements INyARBufferReader\r
+public final class NyARBufferReader implements INyARBufferReader\r
{\r
- protected Object _buffer;\r
- protected int _buffer_type;\r
- protected NyARBufferReader()\r
+ private Object _buffer;\r
+ private int _buffer_type;\r
+ private NyARBufferReader()\r
{\r
return;\r
}\r
*/\r
package jp.nyatla.nyartoolkit.core.rasterreader;\r
\r
+import jp.nyatla.nyartoolkit.NyARException;\r
import jp.nyatla.nyartoolkit.core.types.*;\r
/**\r
* byte[]配列に、パディング無しの8bit画素値が、RGBRGBの順で並んでいる\r
\r
public void getPixel(int i_x, int i_y, int[] o_rgb)\r
{\r
- byte[] ref_buf = this._ref_buf;\r
- int bp = (i_x + i_y * this._size.w) * 3;\r
+ final byte[] ref_buf = this._ref_buf;\r
+ final int bp = (i_x + i_y * this._size.w) * 3;\r
o_rgb[0] = (ref_buf[bp + 0] & 0xff);// R\r
o_rgb[1] = (ref_buf[bp + 1] & 0xff);// G\r
o_rgb[2] = (ref_buf[bp + 2] & 0xff);// B\r
\r
public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
{\r
- int width = this._size.w;\r
- byte[] ref_buf = this._ref_buf;\r
int bp;\r
+ final int width = this._size.w;\r
+ final byte[] ref_buf = this._ref_buf;\r
for (int i = i_num - 1; i >= 0; i--) {\r
bp = (i_x[i] + i_y[i] * width) * 3;\r
o_rgb[i * 3 + 0] = (ref_buf[bp + 0] & 0xff);// R\r
o_rgb[i * 3 + 1] = (ref_buf[bp + 1] & 0xff);// G\r
o_rgb[i * 3 + 2] = (ref_buf[bp + 2] & 0xff);// B\r
}\r
- }\r
+ return;\r
+ } \r
}
\ No newline at end of file
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
+ * 変換行列を求めるには、detectMarkerLite関数にラスタイメージを入力して、計算対象の矩形を特定します。\r
+ * detectMarkerLiteが成功すると、getTransmationMatrix等の関数が使用可能な状態になり、変換行列を求めることができます。\r
+ * \r
* \r
*/\r
public class NyARCustomSingleDetectMarker\r
\r
private final NyARSquareStack _square_list = new NyARSquareStack(AR_SQUARE_MAX);\r
\r
- private NyARCode _code;\r
-\r
protected INyARTransMat _transmat;\r
\r
private double _marker_width;\r
private NyARBinRaster _bin_raster;\r
protected INyARRasterFilter_RgbToBin _tobin_filter;\r
\r
+ private NyARMatchPattDeviationColorData _deviation_data;\r
/**\r
* 検出するARCodeとカメラパラメータから、1個のARCodeを検出するNyARSingleDetectMarkerインスタンスを作ります。\r
* \r
this._square_detect = new NyARSquareDetector(i_param.getDistortionFactor(),scr_size);\r
this._transmat = new NyARTransMat(i_param);\r
// 比較コードを保存\r
- this._code = i_code;\r
this._marker_width = i_marker_width;\r
- // 評価パターンのホルダを作る\r
- this._patt = new NyARColorPatt_O3(_code.getWidth(), _code.getHeight());\r
- // 評価器を作る。\r
- this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA();\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
+ //取得パターンの差分データ器を作成\r
+ this._deviation_data=new NyARMatchPattDeviationColorData(i_code.getWidth(),i_code.getHeight());\r
+ //i_code用の評価器を作成\r
+ this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA(i_code);\r
+ \r
//2値画像バッファを作る\r
this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);\r
this._tobin_filter=i_filter;\r
+ return;\r
}\r
\r
+ private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
\r
/**\r
* i_imageにマーカー検出処理を実行し、結果を記録します。\r
if (number_of_square < 1) {\r
return false;\r
}\r
-\r
- // 評価基準になるパターンをイメージから切り出す\r
- if (!this._patt.pickFromRaster(i_raster, (NyARSquare)l_square_list.getItem(0))) {\r
- // パターンの切り出しに失敗\r
- return false;\r
- }\r
- // パターンを評価器にセット\r
- if (!this._match_patt.setPatt(this._patt)) {\r
- // 計算に失敗した。\r
- throw new NyARException();\r
- }\r
- // コードと比較する\r
- this._match_patt.evaluate(this._code);\r
+ \r
+ boolean result=false;\r
+ NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
int square_index = 0;\r
- int direction = this._match_patt.getDirection();\r
- double confidence = this._match_patt.getConfidence();\r
- for (int i = 1; i < number_of_square; i++) {\r
- // 次のパターンを取得\r
- this._patt.pickFromRaster(i_raster, (NyARSquare)l_square_list.getItem(i));\r
- // 評価器にセットする。\r
- this._match_patt.setPatt(this._patt);\r
- // コードと比較する\r
- this._match_patt.evaluate(this._code);\r
- double c2 = this._match_patt.getConfidence();\r
+ int direction = NyARSquare.DIRECTION_UNKNOWN;\r
+ double confidence = 0;\r
+ for(int i=0;i<number_of_square;i++){\r
+ // 評価基準になるパターンをイメージから切り出す\r
+ if (!this._patt.pickFromRaster(i_raster, (NyARSquare)l_square_list.getItem(i))){\r
+ continue;\r
+ }\r
+ //取得パターンをカラー差分データに変換して評価する。\r
+ this._deviation_data.setRaster(this._patt);\r
+ if(!this._match_patt.evaluate(this._deviation_data,mr)){\r
+ continue;\r
+ }\r
+ final double c2 = mr.confidence;\r
if (confidence > c2) {\r
continue;\r
}\r
// もっと一致するマーカーがあったぽい\r
square_index = i;\r
- direction = this._match_patt.getDirection();\r
+ direction = mr.direction;\r
confidence = c2;\r
+ result=true;\r
}\r
+ \r
// マーカー情報を保存\r
this._detected_square = (NyARSquare)l_square_list.getItem(square_index);\r
this._detected_direction = direction;\r
this._detected_confidence = confidence;\r
- return true;\r
+ return result;\r
}\r
\r
/**\r
\r
private boolean _is_continue = false;\r
\r
- private NyARMatchPatt_Color_WITHOUT_PCA _match_patt;\r
+ private NyARMatchPatt_Color_WITHOUT_PCA[] _match_patt;\r
\r
private INyARSquareDetector _square_detect;\r
\r
private final NyARSquareStack _square_list = new NyARSquareStack(AR_SQUARE_MAX);\r
\r
- private NyARCode[] _codes;\r
-\r
protected INyARTransMat _transmat;\r
\r
- private double[] _marker_width;\r
-\r
- private int _number_of_code;\r
+ private double[] _marker_width; \r
\r
// 検出結果の保存用\r
private INyARColorPatt _patt;\r
\r
private NyARDetectMarkerResultHolder _result_holder = new NyARDetectMarkerResultHolder();\r
-\r
+ private NyARMatchPattDeviationColorData _deviation_data;\r
/**\r
* 複数のマーカーを検出し、最も一致するARCodeをi_codeから検索するオブジェクトを作ります。\r
* \r
* @param i_param\r
* カメラパラメータを指定します。\r
* @param i_code\r
- * 検出するマーカーのARCode配列を指定します。配列要素のインデックス番号が、そのままgetARCodeIndex関数で 得られるARCodeインデックスになります。 例えば、要素[1]のARCodeに一致したマーカーである場合は、getARCodeIndexは1を返します。\r
- * 先頭からi_number_of_code個の要素には、有効な値を指定する必要があります。\r
+ * 検出するマーカーのARCode配列を指定します。\r
+ * 配列要素のインデックス番号が、そのままgetARCodeIndex関数で得られるARCodeインデックスになります。 \r
+ * 例えば、要素[1]のARCodeに一致したマーカーである場合は、getARCodeIndexは1を返します。\r
* @param i_marker_width\r
* i_codeのマーカーサイズをミリメートルで指定した配列を指定します。 先頭からi_number_of_code個の要素には、有効な値を指定する必要があります。\r
* @param i_number_of_code\r
* i_codeに含まれる、ARCodeの数を指定します。\r
* @throws NyARException\r
*/\r
- public NyARDetectMarker(NyARParam i_param, NyARCode[] i_code, double[] i_marker_width, int i_number_of_code) throws NyARException\r
+ public NyARDetectMarker(NyARParam i_param,NyARCode[] i_code,double[] i_marker_width, int i_number_of_code) throws NyARException\r
{\r
final NyARIntSize scr_size=i_param.getScreenSize();\r
// 解析オブジェクトを作る\r
this._square_detect = new NyARSquareDetector(i_param.getDistortionFactor(),scr_size);\r
this._transmat = new NyARTransMat(i_param);\r
- // 比較コードを保存\r
- this._codes = i_code;\r
- // 比較コードの解像度は全部同じかな?(違うとパターンを複数種つくらないといけないから)\r
+\r
+ //各コード用の比較器を作る。\r
+ this._match_patt=new NyARMatchPatt_Color_WITHOUT_PCA[i_number_of_code];\r
final int cw = i_code[0].getWidth();\r
final int ch = i_code[0].getHeight();\r
- for (int i = 1; i < i_number_of_code; i++) {\r
+ this._match_patt[0]=new NyARMatchPatt_Color_WITHOUT_PCA(i_code[0]);\r
+ for (int i = 1; i < i_number_of_code; i++){\r
+ //解像度チェック\r
if (cw != i_code[i].getWidth() || ch != i_code[i].getHeight()) {\r
- // 違う解像度のが混ざっている。\r
throw new NyARException();\r
}\r
- }\r
+ this._match_patt[i]=new NyARMatchPatt_Color_WITHOUT_PCA(i_code[i]);\r
+ } \r
// 評価パターンのホルダを作る\r
this._patt = new NyARColorPatt_O3(cw, ch);\r
- this._number_of_code = i_number_of_code;\r
-\r
+ //実サイズ保存\r
this._marker_width = i_marker_width;\r
- // 評価器を作る。\r
- this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA();\r
+ //差分データインスタンスの作成\r
+ this._deviation_data=new NyARMatchPattDeviationColorData(cw,ch);\r
//2値画像バッファを作る\r
- this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h); \r
+ this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);\r
+ return;\r
}\r
\r
private NyARBinRaster _bin_raster;\r
\r
private NyARRasterFilter_ARToolkitThreshold _tobin_filter = new NyARRasterFilter_ARToolkitThreshold(100);\r
+ private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
\r
/**\r
* i_imageにマーカー検出処理を実行し、結果を記録します。\r
}\r
// 保持リストのサイズを調整\r
this._result_holder.reservHolder(number_of_square);\r
+ NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
\r
// 1スクエア毎に、一致するコードを決定していく\r
for (int i = 0; i < number_of_square; i++) {\r
NyARSquare square = (NyARSquare)l_square_list.getItem(i);\r
+\r
// 評価基準になるパターンをイメージから切り出す\r
if (!this._patt.pickFromRaster(i_raster, square)) {\r
// イメージの切り出しは失敗することもある。\r
continue;\r
}\r
- // パターンを評価器にセット\r
- if (!this._match_patt.setPatt(this._patt)) {\r
- // 計算に失敗した。\r
- throw new NyARException();\r
- }\r
- // コードと順番に比較していく\r
- int code_index = 0;\r
- _match_patt.evaluate(_codes[0]);\r
- double confidence = _match_patt.getConfidence();\r
- int direction = _match_patt.getDirection();\r
- for (int i2 = 1; i2 < this._number_of_code; i2++) {\r
- // コードと比較する\r
- _match_patt.evaluate(_codes[i2]);\r
- double c2 = _match_patt.getConfidence();\r
+ //取得パターンをカラー差分データに変換する。\r
+ this._deviation_data.setRaster(this._patt);\r
+ int square_index = 0;\r
+ int direction = NyARSquare.DIRECTION_UNKNOWN;\r
+ double confidence = 0;\r
+ for(int i2=0;i2<this._match_patt.length;i2++){\r
+ this._match_patt[i2].evaluate(this._deviation_data,mr);\r
+\r
+ final double c2 = mr.confidence;\r
if (confidence > c2) {\r
continue;\r
}\r
- // ã\82\88ã\82\8aä¸\80è\87´ã\81\99ã\82\8bARCodeã\81®æ\83\85å ±ã\82\92ä¿\9då\98\r
- code_index = i2;\r
- direction = _match_patt.getDirection();\r
+ // ã\82\82ã\81£ã\81¨ä¸\80è\87´ã\81\99ã\82\8bã\83\9eã\83¼ã\82«ã\83¼ã\81\8cã\81\82ã\81£ã\81\9fã\81½ã\81\84\r
+ square_index = i2;\r
+ direction = mr.direction;\r
confidence = c2;\r
}\r
- // i番目のパターン情報を保存する。\r
+ // i番目のパターン情報を記録する。\r
final NyARDetectMarkerResult result = this._result_holder.result_array[i];\r
- result.arcode_id = code_index;\r
+ result.arcode_id = square_index;\r
result.confidence = confidence;\r
result.direction = direction;\r
result.ref_square = square;\r
--- /dev/null
+/* \r
+ * Capture Test NyARToolkitCSサンプルプログラム\r
+ * --------------------------------------------------------------------------------\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.processor;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.match.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**このクラスは、同時に1個のマーカを処理することのできる、アプリケーションプロセッサです。\r
+ * マーカの出現・移動・消滅を、イベントで通知することができます。\r
+ * クラスには複数のマーカを登録できます。一つのマーカが見つかると、プロセッサは継続して同じマーカを\r
+ * 1つだけ認識し続け、見失うまでの間は他のマーカを認識しません。\r
+ * \r
+ * イベントは、 OnEnter→OnUpdate[n]→OnLeaveの順で発生します。\r
+ * マーカが見つかるとまずOnEnterが1度発生して、何番のマーカが発見されたかがわかります。\r
+ * 次にOnUpdateにより、現在の変換行列が連続して渡されます。最後にマーカを見失うと、OnLeave\r
+ * イベントがコールされます。\r
+ * \r
+ */\r
+public abstract class SingleARMarkerProcesser\r
+{\r
+ /**selectARCodeIndexFromListが値を返す時に使う変数型です。\r
+ */\r
+\r
+ private class TResult_selectARCodeIndex\r
+ {\r
+ public int direction;\r
+\r
+ public double confidence;\r
+\r
+ public int code_index;\r
+ }\r
+ /**オーナーが自由に使えるタグ変数です。\r
+ */\r
+ public Object tag;\r
+\r
+ private int _lost_delay_count = 0;\r
+\r
+ private int _lost_delay = 5;\r
+\r
+ private NyARSquareDetector _square_detect;\r
+\r
+ protected NyARTransMat _transmat;\r
+\r
+ private double _marker_width;\r
+\r
+ private NyARMatchPatt_Color_WITHOUT_PCA[] _match_patt;\r
+\r
+ private NyARSquareStack _square_list = new NyARSquareStack(100);\r
+\r
+ private NyARColorPatt_O3 _patt = null;\r
+\r
+ private double _cf_threshold_new = 0.30;\r
+\r
+ private double _cf_threshold_exist = 0.15;\r
+ \r
+ private int _threshold = 110;\r
+ // [AR]検出結果の保存用\r
+ private NyARBinRaster _bin_raster;\r
+\r
+ private NyARRasterFilter_ARToolkitThreshold _tobin_filter = new NyARRasterFilter_ARToolkitThreshold(110);\r
+\r
+ protected int _current_arcode_index = -1;\r
+\r
+ private NyARMatchPattDeviationColorData _deviation_data;\r
+\r
+\r
+ public SingleARMarkerProcesser(NyARParam i_param) throws NyARException\r
+ {\r
+ NyARIntSize scr_size = i_param.getScreenSize();\r
+ // 解析オブジェクトを作る\r
+ this._square_detect = new NyARSquareDetector(i_param.getDistortionFactor(), scr_size);\r
+ this._transmat = new NyARTransMat(i_param);\r
+ this._deviation_data=new NyARMatchPattDeviationColorData(scr_size.w,scr_size.h);\r
+\r
+ // 2値画像バッファを作る\r
+ this._bin_raster = new NyARBinRaster(scr_size.w / 2, scr_size.h / 2);\r
+ return;\r
+ }\r
+\r
+ public void setThreshold(int i_threshold)\r
+ {\r
+ this._threshold = i_threshold;\r
+ return;\r
+ }\r
+\r
+ /**検出するマーカコードの配列を指定します。 検出状態でこの関数を実行すると、\r
+ * オブジェクト状態に強制リセットがかかります。\r
+ */\r
+ public void setARCodeTable(NyARCode[] i_ref_code_table, int i_code_resolution, double i_marker_width)\r
+ {\r
+ if (this._current_arcode_index != -1) {\r
+ // 強制リセット\r
+ reset(true);\r
+ }\r
+ // 検出するマーカセット、情報、検出器を作り直す。\r
+ this._patt = new NyARColorPatt_O3(i_code_resolution, i_code_resolution);\r
+ this._marker_width = i_marker_width;\r
+\r
+ this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA[i_ref_code_table.length];\r
+ for(int i=0;i<i_ref_code_table.length;i++){\r
+ this._match_patt[i]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code_table[i]);\r
+ }\r
+ return;\r
+ }\r
+\r
+ public void reset(boolean i_is_force)\r
+ {\r
+ if (this._current_arcode_index != -1 && i_is_force == false) {\r
+ // 強制書き換えでなければイベントコール\r
+ this.onLeaveHandler();\r
+ }\r
+ // カレントマーカをリセット\r
+ this._current_arcode_index = -1;\r
+ return;\r
+ }\r
+\r
+ public void detectMarker(INyARRgbRaster i_raster) throws NyARException\r
+ {\r
+ // サイズチェック\r
+ if (!this._bin_raster.getSize().isEqualSize(i_raster.getSize().w / 2, i_raster.getSize().h / 2)) {\r
+ throw new NyARException();\r
+ }\r
+\r
+ // コードテーブルが無ければここで終わり\r
+ if (this._match_patt== null) {\r
+ return;\r
+ }\r
+\r
+ // ラスタを(1/4の画像の)2値イメージに変換する.\r
+ this._tobin_filter.setThreshold(this._threshold);\r
+ this._tobin_filter.doFilter(i_raster, this._bin_raster);\r
+\r
+ NyARSquareStack square_stack = this._square_list;\r
+ // スクエアコードを探す\r
+ this._square_detect.detectMarker(this._bin_raster, square_stack);\r
+ // 認識処理\r
+ if (this._current_arcode_index == -1) { // マーカ未認識\r
+ detectNewMarker(i_raster, square_stack);\r
+ } else { // マーカ認識中\r
+ detectExistMarker(i_raster, square_stack, this._current_arcode_index);\r
+ }\r
+ return;\r
+ }\r
+\r
+ \r
+ private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+ \r
+ /**ARCodeのリストから、最も一致するコード番号を検索します。\r
+ */\r
+ private boolean selectARCodeIndexFromList(INyARRgbRaster i_raster, NyARSquare i_square, TResult_selectARCodeIndex o_result) throws NyARException\r
+ {\r
+ // 現在コードテーブルはアクティブ?\r
+ if (this._match_patt==null) {\r
+ return false;\r
+ }\r
+ // 評価基準になるパターンをイメージから切り出す\r
+ if (!this._patt.pickFromRaster(i_raster, i_square)) {\r
+ return false;\r
+ }\r
+ //評価データを作成して、評価器にセット\r
+ this._deviation_data.setRaster(this._patt); \r
+ final NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
+ int code_index = 0;\r
+ int dir = 0;\r
+ double c1 = 0;\r
+ // コードと比較する\r
+ for (int i = 0; i < this._match_patt.length; i++) {\r
+ this._match_patt[i].evaluate(this._deviation_data,mr);\r
+ double c2 = mr.confidence;\r
+ if (c1 < c2) {\r
+ code_index = i;\r
+ c1 = c2;\r
+ dir = mr.direction;\r
+ }\r
+ }\r
+ o_result.code_index = code_index;\r
+ o_result.direction = dir;\r
+ o_result.confidence = c1;\r
+ return true;\r
+ }\r
+\r
+ private TResult_selectARCodeIndex __detect_X_Marker_detect_result = new TResult_selectARCodeIndex();\r
+\r
+ /**新規マーカ検索 現在認識中のマーカがないものとして、最も認識しやすいマーカを1個認識します。\r
+ */\r
+ private void detectNewMarker(INyARRgbRaster i_raster, NyARSquareStack i_stack) throws NyARException\r
+ {\r
+ int number_of_square = i_stack.getLength();\r
+ double cf = 0;\r
+ int dir = 0;\r
+ int code_index = -1;\r
+ int square_index = 0;\r
+ TResult_selectARCodeIndex detect_result = this.__detect_X_Marker_detect_result;\r
+ for (int i = 0; i < number_of_square; i++) {\r
+ if (!selectARCodeIndexFromList(i_raster, (NyARSquare) i_stack.getItem(i), detect_result)) {\r
+ // 見つからない。\r
+ return;\r
+ }\r
+ if (detect_result.confidence < this._cf_threshold_new) {\r
+ continue;\r
+ }\r
+ if (detect_result.confidence < cf) {\r
+ // 一致度が低い。\r
+ continue;\r
+ }\r
+ cf = detect_result.confidence;\r
+ code_index = detect_result.code_index;\r
+ square_index = i;\r
+ dir = detect_result.direction;\r
+ }\r
+ // 認識状態を更新\r
+ updateStatus((NyARSquare) this._square_list.getItem(square_index), code_index, cf, dir);\r
+ }\r
+\r
+ /**マーカの継続認識 現在認識中のマーカを優先して認識します。 \r
+ * (注)この機能はたぶん今後いろいろ発展するからNewと混ぜないこと。\r
+ */\r
+ private void detectExistMarker(INyARRgbRaster i_raster, NyARSquareStack i_stack, int i_current_id) throws NyARException\r
+ {\r
+ int number_of_square = i_stack.getLength();\r
+ double cf = 0;\r
+ int dir = 0;\r
+ int code_index = -1;\r
+ int square_index = 0;\r
+ TResult_selectARCodeIndex detect_result = this.__detect_X_Marker_detect_result;\r
+ for (int i = 0; i < number_of_square; i++) {\r
+ if (!selectARCodeIndexFromList(i_raster, (NyARSquare) i_stack.getItem(i), detect_result)) {\r
+ // 見つからない。\r
+ return;\r
+ }\r
+ // 現在のマーカを認識したか?\r
+ if (detect_result.code_index != i_current_id) {\r
+ // 認識中のマーカではないので無視\r
+ continue;\r
+ }\r
+ if (detect_result.confidence < this._cf_threshold_exist) {\r
+ continue;\r
+ }\r
+ if (detect_result.confidence < cf) {\r
+ // 一致度が高い方を選ぶ\r
+ continue;\r
+ }\r
+ cf = detect_result.confidence;\r
+ code_index = detect_result.code_index;\r
+ dir = detect_result.direction;\r
+ square_index = i;\r
+ }\r
+ // 認識状態を更新\r
+ updateStatus((NyARSquare) this._square_list.getItem(square_index), code_index, cf, dir);\r
+ }\r
+\r
+ private NyARTransMatResult __NyARSquare_result = new NyARTransMatResult();\r
+\r
+ /**オブジェクトのステータスを更新し、必要に応じてハンドル関数を駆動します。\r
+ */\r
+ private void updateStatus(NyARSquare i_square, int i_code_index, double i_cf, int i_dir) throws NyARException\r
+ {\r
+ NyARTransMatResult result = this.__NyARSquare_result;\r
+ if (this._current_arcode_index < 0) {// 未認識中\r
+ if (i_code_index < 0) {// 未認識から未認識の遷移\r
+ // なにもしないよーん。\r
+ } else {// 未認識から認識の遷移\r
+ this._current_arcode_index = i_code_index;\r
+ // イベント生成\r
+ // OnEnter\r
+ this.onEnterHandler(i_code_index);\r
+ // 変換行列を作成\r
+ this._transmat.transMat(i_square, i_dir, this._marker_width, result);\r
+ // OnUpdate\r
+ this.onUpdateHandler(i_square, result);\r
+ this._lost_delay_count = 0;\r
+ }\r
+ } else {// 認識中\r
+ if (i_code_index < 0) {// 認識から未認識の遷移\r
+ this._lost_delay_count++;\r
+ if (this._lost_delay < this._lost_delay_count) {\r
+ // OnLeave\r
+ this._current_arcode_index = -1;\r
+ this.onLeaveHandler();\r
+ }\r
+ } else if (i_code_index == this._current_arcode_index) {// 同じARCodeの再認識\r
+ // イベント生成\r
+ // 変換行列を作成\r
+ this._transmat.transMat(i_square, i_dir, this._marker_width, result);\r
+ // OnUpdate\r
+ this.onUpdateHandler(i_square, result);\r
+ this._lost_delay_count = 0;\r
+ } else {// 異なるコードの認識→今はサポートしない。\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ return;\r
+ }\r
+\r
+ protected abstract void onEnterHandler(int i_code);\r
+\r
+ protected abstract void onLeaveHandler();\r
+\r
+ protected abstract void onUpdateHandler(NyARSquare i_square, NyARTransMatResult result);\r
+}\r
\r
// マーカーを検出\r
Date d2 = new Date();\r
- for (int i = 0; i < 1000; i++) {\r
+ for (int i = 0; i < 10000; i++) {\r
// 変換行列を取得\r
ar.detectMarkerLite(ra, 100);\r
ar.getTransmationMatrix(result_mat);\r