ARToolKit Java class library NyARToolkit.\r
Copyright (C)2008 R.Iizuka\r
\r
-version 2.4.0\r
+version 2.4.1\r
\r
http://nyatla.jp/nyartoolkit/\r
airmail(at)ebony.plala.or.jp\r
import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
import jp.nyatla.nyartoolkit.core.squaredetect.ContourPickup;\r
-import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareDetector;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareContourDetector;\r
import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;\r
-import jp.nyatla.nyartoolkit.core.squaredetect.SquareContourDetector;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.Coord2Linear;\r
import jp.nyatla.nyartoolkit.core.types.*;\r
\r
-public class NyARQrCodeDetector implements INyARSquareDetector\r
+public class NyARQrCodeDetector implements INyARSquareContourDetector\r
{\r
private NyARQrCodeSymbolBinder _binder;\r
\r
\r
private final NyARLabelingImage _limage;\r
\r
- private final SquareContourDetector _sqconvertor;\r
+ private final Coord2Linear _sqconvertor;\r
private final ContourPickup _cpickup=new ContourPickup();\r
\r
/**\r
this._labeling = new NyARLabeling_ARToolKit();\r
this._limage = new NyARLabelingImage(this._width, this._height);\r
this._binder=new NyARQrCodeSymbolBinder(i_dist_factor_ref);\r
- this._sqconvertor=new SquareContourDetector(i_size,i_dist_factor_ref);\r
+ this._sqconvertor=new Coord2Linear(i_size,i_dist_factor_ref);\r
\r
// 輪郭の最大長はMAX_COORD_NUMの2倍に制限\r
int number_of_coord = MAX_COORD_NUM* 2;\r
continue;\r
}\r
//輪郭分析用に正規化する。\r
- final int vertex1 = SquareContourDetector.normalizeCoord(xcoord, ycoord, coord_num);\r
+ final int vertex1 = Coord2Linear.normalizeCoord(xcoord, ycoord, coord_num);\r
\r
//ここから先が輪郭分析\r
NyARSquare square_ptr = o_square_stack.prePush();\r
\r
import jp.nyatla.nyartoolkit.NyARException;\r
import jp.nyatla.nyartoolkit.core.raster.*;\r
-import jp.nyatla.nyartoolkit.core.rasterfilter.INyARRasterFilter_GsToBin;\r
import jp.nyatla.nyartoolkit.core.types.*;\r
\r
/**\r
import jp.nyatla.nyartoolkit.core.rasterfilter.*;\r
import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs.INyARRasterFilter_RgbToGs;\r
import jp.nyatla.nyartoolkit.core.raster.*;\r
-import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareDetector;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareContourDetector;\r
import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;\r
import jp.nyatla.nyartoolkit.core.transmat.*;\r
private static final int AR_SQUARE_MAX = 100;\r
\r
private boolean _is_continue = false;\r
- private INyARSquareDetector _square_detect;\r
+ private INyARSquareContourDetector _square_detect;\r
\r
private final NyARSquareStack _square_list = new NyARSquareStack(AR_SQUARE_MAX);\r
\r
this._detected_square = null;\r
NyARSquareStack l_square_list = this._square_list;\r
// スクエアコードを探す\r
- this._square_detect.detectMarker(this._bin_raster, l_square_list);\r
+ this._square_detect.detectMarkerCB(this._bin_raster, l_square_list);\r
//変換する\r
\r
\r
import jp.nyatla.nyartoolkit.core.pickup.*;\r
import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
import jp.nyatla.nyartoolkit.core.raster.*;\r
-import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareDetector;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareContourDetector;\r
import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;\r
import jp.nyatla.nyartoolkit.core.transmat.*;\r
\r
private boolean _is_continue = false;\r
private NyARMatchPatt_Color_WITHOUT_PCA _match_patt;\r
- private INyARSquareDetector _square_detect;\r
+ private INyARSquareContourDetector _square_detect;\r
\r
private final NyARSquareStack _square_list = new NyARSquareStack(AR_SQUARE_MAX);\r
\r
this._detected_square = null;\r
NyARSquareStack l_square_list = this._square_list;\r
// スクエアコードを探す\r
- this._square_detect.detectMarker(this._bin_raster, l_square_list);\r
+ this._square_detect.detectMarkerCB(this._bin_raster, l_square_list);\r
\r
\r
int number_of_square = l_square_list.getLength();\r
import jp.nyatla.nyartoolkit.core.labeling.artoolkit.*;\r
import jp.nyatla.nyartoolkit.core.raster.*;\r
import jp.nyatla.nyartoolkit.core.squaredetect.ContourPickup;\r
-import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareDetector;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareContourDetector;\r
import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;\r
-import jp.nyatla.nyartoolkit.core.squaredetect.SquareContourDetector;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.Coord2Linear;\r
import jp.nyatla.nyartoolkit.core.types.*;\r
import jp.nyatla.nyartoolkit.core.param.*;\r
\r
* 1/4に解像度を落して解析するNyARSquareDetector_X2\r
* 与えるBinRasterが既に1/4のサイズになっていないといけないことに注意\r
*/\r
-public class NyARSquareDetector_Quad implements INyARSquareDetector\r
+public class NyARSquareDetector_Quad implements INyARSquareContourDetector\r
{\r
private static int AR_AREA_MAX = 25000;// #define AR_AREA_MAX 100000\r
\r
private NyARLabelingImage _limage;\r
\r
private final LabelOverlapChecker<NyARLabelingLabel> _overlap_checker = new LabelOverlapChecker<NyARLabelingLabel>(32,NyARLabelingLabel.class);\r
- private final SquareContourDetector _sqconvertor;\r
+ private final Coord2Linear _sqconvertor;\r
private final ContourPickup _cpickup=new ContourPickup();\r
/**\r
* 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
this._height = i_size.h / 2;\r
this._labeling = new NyARLabeling_ARToolKit();\r
this._limage = new NyARLabelingImage(this._width, this._height);\r
- this._sqconvertor=new SquareContourDetector(i_size,i_dist_factor_ref); \r
+ this._sqconvertor=new Coord2Linear(i_size,i_dist_factor_ref); \r
\r
// 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
int number_of_coord = (this._width + this._height) * 2;\r
continue;\r
}\r
//輪郭分析用に正規化する。\r
- final int vertex1 = SquareContourDetector.normalizeCoord(xcoord, ycoord, coord_num);\r
+ final int vertex1 = Coord2Linear.normalizeCoord(xcoord, ycoord, coord_num);\r
\r
//ここから先が輪郭分析\r
NyARSquare square_ptr = o_square_stack.prePush();\r
* PCAではなく、頂点座標そのものからSquare位置を計算するクラス\r
*\r
*/\r
-public class NyARVertexDetector implements INyARSquareDetector\r
+public class NyARVertexDetector implements INyARSquareContourDetector\r
{\r
private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
\r
private final NyARLabelingImage _limage;\r
\r
private final LabelOverlapChecker<NyARLabelingLabel> _overlap_checker = new LabelOverlapChecker<NyARLabelingLabel>(32,NyARLabelingLabel.class);\r
- private final SquareContourDetector _sqconvertor;\r
+ private final Coord2Linear _sqconvertor;\r
private final ContourPickup _cpickup=new ContourPickup();\r
\r
/**\r
this._height = i_size.h;\r
this._labeling = new NyARLabeling_ARToolKit();\r
this._limage = new NyARLabelingImage(this._width, this._height);\r
- this._sqconvertor=new SquareContourDetector(i_size,i_dist_factor_ref); \r
+ this._sqconvertor=new Coord2Linear(i_size,i_dist_factor_ref); \r
\r
// 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
int number_of_coord = (this._width + this._height) * 2;\r
continue;\r
}\r
//輪郭分析用に正規化する。\r
- final int vertex1 = SquareContourDetector.normalizeCoord(xcoord, ycoord, coord_num);\r
+ final int vertex1 = Coord2Linear.normalizeCoord(xcoord, ycoord, coord_num);\r
\r
//ここから先が輪郭分析\r
NyARSquare square_ptr = o_square_stack.prePush();\r
import jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin.*;\r
import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilterBuilder_RgbToBin;\r
import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilter_ARToolkitThreshold;\r
-import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareDetector;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareContourDetector;\r
import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;\r
\r
\r
private boolean _is_continue = false;\r
private NyARMatchPatt_Color_WITHOUT_PCA _match_patt;\r
- private INyARSquareDetector _square_detect;\r
+ private INyARSquareContourDetector _square_detect;\r
\r
private final NyARSquareStack _square_list = new NyARSquareStack(AR_SQUARE_MAX);\r
\r
this._detected_square = null;\r
NyARSquareStack l_square_list = this._square_list;\r
// スクエアコードを探す\r
- this._square_detect.detectMarker(this._bin_raster, l_square_list);\r
+ this._square_detect.detectMarkerCB(this._bin_raster, l_square_list);\r
\r
\r
int number_of_square = l_square_list.getLength();\r
* このクラスは、arDetectMarker2.cとの置き換えになります。\r
* \r
*/\r
-public class NyARSquareDetector_X2 implements INyARSquareDetector\r
+public class NyARSquareDetector_X2 implements INyARSquareContourDetector\r
{\r
private final int _width;\r
private final int _height;\r
\r
private int _lost_delay = 5;\r
\r
- private INyARSquareDetector _square_detect;\r
+ private INyARSquareContourDetector _square_detect;\r
\r
//<X2 patch>\r
protected NyARTransMat_X2 _transmat;\r
\r
NyARSquareStack square_stack = this._square_list;\r
// スクエアコードを探す\r
- this._square_detect.detectMarker(this._bin_raster, square_stack);\r
+ this._square_detect.detectMarkerCB(this._bin_raster, square_stack);\r
// 認識処理\r
if (this._current_arcode_index == -1) { // マーカ未認識\r
detectNewMarker(i_raster, square_stack);\r
* \r
*/\r
package jp.nyatla.nyartoolkit.core.match;\r
+\r
+\r
+\r
/**\r
* [[Strage class]]\r
*\r
*/\r
public class NyARMatchPattResult\r
{\r
+ public static final int DIRECTION_UNKNOWN=-1;\r
public double confidence;\r
public int direction;\r
}
\ No newline at end of file
final int[] linput = i_patt.refData();\r
int sum;\r
double max = 0.0;\r
- int res = NyARSquare.DIRECTION_UNKNOWN;\r
+ int res = NyARMatchPattResult.DIRECTION_UNKNOWN;\r
\r
\r
for (int j = 0; j < 4; j++) {\r
//\r
final int[] linput = i_patt.refData();\r
int sum;\r
- double max = 0.0;\r
- int res = NyARSquare.DIRECTION_UNKNOWN;\r
+ double max = Double.MIN_VALUE;\r
+ int res = NyARMatchPattResult.DIRECTION_UNKNOWN;\r
final int for_mod=this._optimize_for_mod;\r
for (int j = 0; j < 4; j++) {\r
//合計値初期化\r
final int[] linput = i_patt.refData();\r
int sum;\r
double max = 0.0;\r
- int res = NyARSquare.DIRECTION_UNKNOWN;\r
+ int res = NyARMatchPattResult.DIRECTION_UNKNOWN;\r
/* \r
NyARException.trap(\r
"NyARMatchPatt_Color_WITH_PCA\n"+\r
import jp.nyatla.nyartoolkit.core.raster.*;\r
import jp.nyatla.nyartoolkit.core.labeling.artoolkit.*;\r
\r
+/**\r
+ * 輪郭線を取得するクラスです。\r
+ *\r
+ */\r
public class ContourPickup\r
{\r
//巡回参照できるように、テーブルを二重化\r
* 輪郭線の長さを返します。\r
* @throws NyARException\r
*/\r
- public int impl_getContour(INyARRaster i_raster,int i_th,int i_entry_x,int i_entry_y,int i_array_size,int[] o_coord_x,int[] o_coord_y) throws NyARException\r
+ private int impl_getContour(INyARRaster i_raster,int i_th,int i_entry_x,int i_entry_y,int i_array_size,int[] o_coord_x,int[] o_coord_y) throws NyARException\r
{\r
final int[] xdir = _getContour_xdir;// static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};\r
final int[] ydir = _getContour_ydir;// static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};\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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
+import jp.nyatla.nyartoolkit.core.param.NyARObserv2IdealMap;\r
+import jp.nyatla.nyartoolkit.core.pca2d.INyARPca2d;\r
+import jp.nyatla.nyartoolkit.core.pca2d.NyARPca2d_MatrixPCA_O2;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+import jp.nyatla.nyartoolkit.core.types.NyARLinear;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;\r
+\r
+\r
+\r
+/**\r
+ * 頂点集合を一次方程式のパラメータに変換します。\r
+ * \r
+ *\r
+ */\r
+public class Coord2Linear\r
+{\r
+ private final double[] _xpos;\r
+ private final double[] _ypos; \r
+ private final INyARPca2d _pca;\r
+ private final NyARDoubleMatrix22 __getSquareLine_evec=new NyARDoubleMatrix22();\r
+ private final double[] __getSquareLine_mean=new double[2];\r
+ private final double[] __getSquareLine_ev=new double[2];\r
+ private final NyARObserv2IdealMap _dist_factor;\r
+ public Coord2Linear(NyARIntSize i_size,NyARCameraDistortionFactor i_distfactor_ref)\r
+ {\r
+ //歪み計算テーブルを作ると、8*width/height*2の領域を消費します。\r
+ //領域を取りたくない場合は、i_dist_factor_refの値をそのまま使ってください。\r
+ this._dist_factor = new NyARObserv2IdealMap(i_distfactor_ref,i_size);\r
+\r
+\r
+ // 輪郭バッファ\r
+ this._pca=new NyARPca2d_MatrixPCA_O2();\r
+ this._xpos=new double[i_size.w+i_size.h];//最大辺長はthis._width+this._height\r
+ this._ypos=new double[i_size.w+i_size.h];//最大辺長はthis._width+this._height\r
+ return;\r
+ }\r
+\r
+\r
+ /**\r
+ * 輪郭点集合からay+bx+c=0の直線式を計算します。\r
+ * @param i_st\r
+ * @param i_ed\r
+ * @param i_xcoord\r
+ * @param i_ycoord\r
+ * @param i_cood_num\r
+ * @param o_line\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public boolean coord2Line(int i_st,int i_ed,int[] i_xcoord, int[] i_ycoord,int i_cood_num, NyARLinear o_line) throws NyARException\r
+ {\r
+ //頂点を取得\r
+ int n,st,ed;\r
+ double w1;\r
+ \r
+ //探索区間の決定\r
+ if(i_ed>=i_st){\r
+ //頂点[i]から頂点[i+1]までの輪郭が、1区間にあるとき\r
+ w1 = (double) (i_ed - i_st + 1) * 0.05 + 0.5;\r
+ //探索区間の決定\r
+ st = (int) (i_st+w1);\r
+ ed = (int) (i_ed - w1);\r
+ }else{\r
+ //頂点[i]から頂点[i+1]までの輪郭が、2区間に分かれているとき\r
+ w1 = (double) (i_ed+i_cood_num-i_st+1)%i_cood_num * 0.05 + 0.5;\r
+ //探索区間の決定\r
+ st = (int) (i_st+w1)%i_cood_num;\r
+ ed = (int) (i_ed+i_cood_num-w1)%i_cood_num;\r
+ }\r
+ //探索区間数を確認\r
+ if(st<=ed){\r
+ //探索区間は1区間\r
+ n = ed - st + 1;\r
+ this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st, n,this._xpos,this._ypos,0);\r
+ }else{\r
+ //探索区間は2区間\r
+ n=ed+1+i_cood_num-st;\r
+ this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st,i_cood_num-st,this._xpos,this._ypos,0);\r
+ this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, 0,ed+1,this._xpos,this._ypos,i_cood_num-st);\r
+ }\r
+ //要素数の確認\r
+ if (n < 2) {\r
+ // nが2以下でmatrix.PCAを計算することはできないので、エラー\r
+ return false;\r
+ }\r
+ //主成分分析する。\r
+ final NyARDoubleMatrix22 evec=this.__getSquareLine_evec;\r
+ final double[] mean=this.__getSquareLine_mean;\r
+\r
+ \r
+ this._pca.pca(this._xpos,this._ypos,n,evec, this.__getSquareLine_ev,mean);\r
+ o_line.dy = evec.m01;// line[i][0] = evec->m[1];\r
+ o_line.dx = -evec.m00;// line[i][1] = -evec->m[0];\r
+ o_line.c = -(o_line.dy * mean[0] + o_line.dx * mean[1]);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);\r
+\r
+ return true;\r
+ }\r
+}
\ No newline at end of file
package jp.nyatla.nyartoolkit.core.squaredetect;\r
\r
/**\r
- * 座標店集合(輪郭線)から、頂点リストを計算します。\r
+ * 座標店集合(輪郭線)から、四角系の頂点候補点を計算します。\r
*\r
*/\r
public class Coord2SquareVertexIndexes\r
} \r
return ret;\r
} \r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+ * get_vertex関数を切り離すためのクラス\r
+ * \r
+ */\r
+final class NyARVertexCounter\r
+{\r
+ public final int[] vertex = new int[10];// 6まで削れる\r
+\r
+ public int number_of_vertex;\r
+\r
+ private double thresh;\r
+\r
+ private int[] x_coord;\r
+\r
+ private int[] y_coord;\r
+\r
+ public boolean getVertex(int[] i_x_coord, int[] i_y_coord,int i_coord_len,int st, int ed, double i_thresh)\r
+ {\r
+ this.number_of_vertex = 0;\r
+ this.thresh = i_thresh;\r
+ this.x_coord = i_x_coord;\r
+ this.y_coord = i_y_coord;\r
+ return get_vertex(st, ed,i_coord_len);\r
+ }\r
+\r
+ /**\r
+ * static int get_vertex( int x_coord[], int y_coord[], int st, int ed,double thresh, int vertex[], int *vnum) 関数の代替関数\r
+ * \r
+ * @param x_coord\r
+ * @param y_coord\r
+ * @param st\r
+ * @param ed\r
+ * @param thresh\r
+ * @return\r
+ */\r
+ private boolean get_vertex(int st, int ed,int i_coord_len)\r
+ {\r
+ //メモ:座標値は65536を超えなければint32で扱って大丈夫なので変更。\r
+ //dmaxは4乗なのでやるとしてもint64じゃないとマズイ\r
+ int v1 = 0;\r
+ final int[] lx_coord = this.x_coord;\r
+ final int[] ly_coord = this.y_coord;\r
+ final int a = ly_coord[ed] - ly_coord[st];\r
+ final int b = lx_coord[st] - lx_coord[ed];\r
+ final int c = lx_coord[ed] * ly_coord[st] - ly_coord[ed] * lx_coord[st];\r
+ double dmax = 0;\r
+ if(st<ed){\r
+ //stとedが1区間\r
+ for (int i = st + 1; i < ed; i++) {\r
+ final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
+ if (d * d > dmax) {\r
+ dmax = d * d;\r
+ v1 = i;\r
+ }\r
+ }\r
+ }else{\r
+ //stとedが2区間\r
+ for (int i = st + 1; i < i_coord_len; i++) {\r
+ final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
+ if (d * d > dmax) {\r
+ dmax = d * d;\r
+ v1 = i;\r
+ }\r
+ }\r
+ for (int i = 0; i < ed; i++) {\r
+ final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
+ if (d * d > dmax) {\r
+ dmax = d * d;\r
+ v1 = i;\r
+ }\r
+ }\r
+ }\r
+\r
+ \r
+ if (dmax / (double)(a * a + b * b) > thresh) {\r
+ if (!get_vertex(st, v1,i_coord_len)) {\r
+ return false;\r
+ }\r
+ if (number_of_vertex > 5) {\r
+ return false;\r
+ }\r
+ vertex[number_of_vertex] = v1;// vertex[(*vnum)] = v1;\r
+ number_of_vertex++;// (*vnum)++;\r
+\r
+ if (!get_vertex(v1, ed,i_coord_len)) {\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
}
\ No newline at end of file
import jp.nyatla.nyartoolkit.NyARException;\r
import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
\r
-public interface INyARSquareDetector\r
+public interface INyARSquareContourDetector\r
{\r
- public void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException;\r
+ public interface DetectMarkerCallback\r
+ {\r
+ public void onSquareDetect(INyARSquareContourDetector i_sender,int[] i_coordx,int[] i_coordy,int i_coor_num,int[] i_vertex_index) throws NyARException;\r
+ }\r
+ /**\r
+ *\r
+ * @param i_raster\r
+ * @param o_square_stack\r
+ * @throws NyARException\r
+ */\r
+ public void detectMarkerCB(NyARBinRaster i_raster, DetectMarkerCallback i_callback) throws NyARException;\r
}\r
+\r
*/\r
public class NyARSquare\r
{\r
- public final static int DIRECTION_UNKNOWN=-1;\r
- public int direction;\r
public NyARLinear[] line = NyARLinear.createArray(4);\r
public NyARDoublePoint2d[] sqvertex = NyARDoublePoint2d.createArray(4);\r
public NyARIntPoint2d[] imvertex = NyARIntPoint2d.createArray(4);\r
\r
\r
\r
-public class NyARSquareDetector_ARToolKit implements INyARSquareDetector\r
+public class NyARSquareContourDetector_ARToolKit implements INyARSquareContourDetector\r
{\r
private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70\r
private final NyARLabelingImage _limage;\r
\r
private final LabelOverlapChecker<NyARLabelingLabel> _overlap_checker = new LabelOverlapChecker<NyARLabelingLabel>(32,NyARLabelingLabel.class);\r
- private final SquareContourDetector _sqconvertor;\r
private final ContourPickup _cpickup=new ContourPickup();\r
+ private final Coord2SquareVertexIndexes _coord2vertex=new Coord2SquareVertexIndexes();\r
\r
private final int _max_coord;\r
private final int[] _xcoord;\r
private final int[] _ycoord; \r
+ private final int[] __detectMarker_mkvertex = new int[4];\r
/**\r
* 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
* \r
* @param i_param\r
*/\r
- public NyARSquareDetector_ARToolKit(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
+ public NyARSquareContourDetector_ARToolKit(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
{\r
this._width = i_size.w;\r
this._height = i_size.h;\r
this._labeling = new NyARLabeling_ARToolKit();\r
- this._sqconvertor=new SquareContourDetector(i_size,i_dist_factor_ref);\r
this._limage = new NyARLabelingImage(this._width, this._height);\r
\r
// 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
* 抽出した正方形候補を格納するリスト\r
* @throws NyARException\r
*/\r
- public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException\r
+ public final void detectMarkerCB(NyARBinRaster i_raster, DetectMarkerCallback i_callback) throws NyARException\r
{\r
final NyARLabelingImage limage = this._limage;\r
\r
- // 初期化\r
-\r
- // マーカーホルダをリセット\r
- o_square_stack.clear();\r
-\r
- // ラベル数が0ならここまで(Labeling内部でソートするようにした。)\r
+ // ラベル数が0ならここまで\r
final int label_num = this._labeling.labeling(i_raster,this._limage);\r
if (label_num < 1) {\r
return;\r
break;\r
}\r
}\r
-\r
final int xsize = this._width;\r
final int ysize = this._height;\r
final int[] xcoord = this._xcoord;\r
final int[] ycoord = this._ycoord;\r
final int coord_max = this._max_coord;\r
+ final int[] mkvertex =this.__detectMarker_mkvertex;\r
+ \r
final LabelOverlapChecker<NyARLabelingLabel> overlap = this._overlap_checker;\r
\r
//重なりチェッカの最大数を設定\r
overlap.setMaxLabels(label_num);\r
-\r
for (; i < label_num; i++) {\r
final NyARLabelingLabel label_pt = labels[i];\r
final int label_area = label_pt.area;\r
// 輪郭が大きすぎる。\r
continue;\r
}\r
- //ここから先が輪郭分析\r
- NyARSquare square_ptr = o_square_stack.prePush();\r
- if(!this._sqconvertor.coordToSquare(xcoord,ycoord,coord_num,label_area,square_ptr)){\r
- o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
- continue; \r
+ //輪郭線をチェックして、矩形かどうかを判定。矩形ならばmkvertexに取得\r
+ if (!this._coord2vertex.getVertexIndexes(xcoord, ycoord,coord_num,label_area, mkvertex)) {\r
+ // 頂点の取得が出来なかった\r
+ continue;\r
}\r
+ //矩形を発見したことをコールバック関数で通知\r
+ i_callback.onSquareDetect(this,xcoord,ycoord,coord_num,mkvertex);\r
+\r
// 検出済の矩形の属したラベルを重なりチェックに追加する。\r
overlap.push(label_pt);\r
+ \r
}\r
return;\r
}\r
import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.*;\r
import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
-import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import java.util.*;\r
\r
\r
-\r
-public class NyARSquareDetector_Rle implements INyARSquareDetector\r
+public class NyARSquareContourDetector_Rle implements INyARSquareContourDetector\r
{\r
private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70\r
private final NyARLabeling_Rle _labeling;\r
\r
private final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> _overlap_checker = new LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo>(32,RleLabelFragmentInfoStack.RleLabelFragmentInfo.class);\r
- private final SquareContourDetector _sqconvertor;\r
private final ContourPickup _cpickup=new ContourPickup();\r
private final RleLabelFragmentInfoStack _stack;\r
+ private final Coord2SquareVertexIndexes _coord2vertex=new Coord2SquareVertexIndexes();\r
\r
private final int _max_coord;\r
private final int[] _xcoord;\r
* \r
* @param i_param\r
*/\r
- public NyARSquareDetector_Rle(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
+ public NyARSquareContourDetector_Rle(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
{\r
this._width = i_size.w;\r
this._height = i_size.h;\r
//ラベリングのサイズを指定したいときはsetAreaRangeを使ってね。\r
this._labeling = new NyARLabeling_Rle(this._width,this._height);\r
this._labeling.setAreaRange(AR_AREA_MAX, AR_AREA_MIN);\r
- this._sqconvertor=new SquareContourDetector(i_size,i_dist_factor_ref);\r
this._stack=new RleLabelFragmentInfoStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数\r
\r
\r
return;\r
}\r
\r
- /**\r
- * arDetectMarker2を基にした関数\r
- * この関数はNyARSquare要素のうち、directionを除くパラメータを取得して返します。\r
- * directionの確定は行いません。\r
- * @param i_raster\r
- * 解析する2値ラスタイメージを指定します。\r
- * @param o_square_stack\r
- * 抽出した正方形候補を格納するリスト\r
- * @throws NyARException\r
- */\r
- public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException\r
+ private final int[] __detectMarker_mkvertex = new int[4];\r
+ \r
+ public void detectMarkerCB(NyARBinRaster i_raster, DetectMarkerCallback i_callback) throws NyARException\r
{\r
final RleLabelFragmentInfoStack flagment=this._stack;\r
final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> overlap = this._overlap_checker;\r
\r
- // マーカーホルダをリセット\r
- o_square_stack.clear();\r
-\r
// ラベル数が0ならここまで\r
final int label_num=this._labeling.labeling(i_raster, 0, i_raster.getHeight(), flagment);\r
if (label_num < 1) {\r
int[] xcoord = this._xcoord;\r
int[] ycoord = this._ycoord;\r
final int coord_max = this._max_coord;\r
+ final int[] mkvertex =this.__detectMarker_mkvertex;\r
\r
\r
//重なりチェッカの最大数を設定\r
// 重なっているようだ。\r
continue;\r
}\r
-\r
- // 輪郭を取得\r
+ \r
+ //輪郭を取得\r
int coord_num = _cpickup.getContour(i_raster,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);\r
if (coord_num == coord_max) {\r
// 輪郭が大きすぎる。\r
continue;\r
}\r
- \r
- NyARSquare square_ptr = o_square_stack.prePush();\r
-\r
- //ここから先が輪郭分析\r
- if(!this._sqconvertor.coordToSquare(xcoord,ycoord,coord_num,label_area,square_ptr)){\r
- o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
- continue; \r
+ //輪郭線をチェックして、矩形かどうかを判定。矩形ならばmkvertexに取得\r
+ if (!this._coord2vertex.getVertexIndexes(xcoord, ycoord,coord_num,label_area, mkvertex)) {\r
+ // 頂点の取得が出来なかった\r
+ continue;\r
}\r
- \r
- \r
+ //矩形を発見したことをコールバック関数で通知\r
+ i_callback.onSquareDetect(this,xcoord,ycoord,coord_num,mkvertex);\r
+\r
// 検出済の矩形の属したラベルを重なりチェックに追加する。\r
overlap.push(label_pt);\r
+ \r
}\r
return;\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 edition ARToolKit class library.\r
- * Copyright (C)2008-2009 Ryo Iizuka\r
- *\r
- * This program is free software: you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation, either version 3 of the License, or\r
- * (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 program. If not, see <http://www.gnu.org/licenses/>.\r
- * \r
- * For further information please contact.\r
- * http://nyatla.jp/nyatoolkit/\r
- * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
- * \r
- */\r
-package jp.nyatla.nyartoolkit.core.squaredetect;\r
-\r
-/**\r
- * get_vertex関数を切り離すためのクラス\r
- * \r
- */\r
-final public class NyARVertexCounter\r
-{\r
- public final int[] vertex = new int[10];// 6まで削れる\r
-\r
- public int number_of_vertex;\r
-\r
- private double thresh;\r
-\r
- private int[] x_coord;\r
-\r
- private int[] y_coord;\r
-\r
- public boolean getVertex(int[] i_x_coord, int[] i_y_coord,int i_coord_len,int st, int ed, double i_thresh)\r
- {\r
- this.number_of_vertex = 0;\r
- this.thresh = i_thresh;\r
- this.x_coord = i_x_coord;\r
- this.y_coord = i_y_coord;\r
- return get_vertex(st, ed,i_coord_len);\r
- }\r
-\r
- /**\r
- * static int get_vertex( int x_coord[], int y_coord[], int st, int ed,double thresh, int vertex[], int *vnum) 関数の代替関数\r
- * \r
- * @param x_coord\r
- * @param y_coord\r
- * @param st\r
- * @param ed\r
- * @param thresh\r
- * @return\r
- */\r
- private boolean get_vertex(int st, int ed,int i_coord_len)\r
- {\r
- //メモ:座標値は65536を超えなければint32で扱って大丈夫なので変更。\r
- //dmaxは4乗なのでやるとしてもint64じゃないとマズイ\r
- int v1 = 0;\r
- final int[] lx_coord = this.x_coord;\r
- final int[] ly_coord = this.y_coord;\r
- final int a = ly_coord[ed] - ly_coord[st];\r
- final int b = lx_coord[st] - lx_coord[ed];\r
- final int c = lx_coord[ed] * ly_coord[st] - ly_coord[ed] * lx_coord[st];\r
- double dmax = 0;\r
- if(st<ed){\r
- //stとedが1区間\r
- for (int i = st + 1; i < ed; i++) {\r
- final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
- if (d * d > dmax) {\r
- dmax = d * d;\r
- v1 = i;\r
- }\r
- }\r
- }else{\r
- //stとedが2区間\r
- for (int i = st + 1; i < i_coord_len; i++) {\r
- final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
- if (d * d > dmax) {\r
- dmax = d * d;\r
- v1 = i;\r
- }\r
- }\r
- for (int i = 0; i < ed; i++) {\r
- final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
- if (d * d > dmax) {\r
- dmax = d * d;\r
- v1 = i;\r
- }\r
- }\r
- }\r
-\r
- \r
- if (dmax / (double)(a * a + b * b) > thresh) {\r
- if (!get_vertex(st, v1,i_coord_len)) {\r
- return false;\r
- }\r
- if (number_of_vertex > 5) {\r
- return false;\r
- }\r
- vertex[number_of_vertex] = v1;// vertex[(*vnum)] = v1;\r
- number_of_vertex++;// (*vnum)++;\r
-\r
- if (!get_vertex(v1, ed,i_coord_len)) {\r
- return false;\r
- }\r
- }\r
- return true;\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/* \r
- * PROJECT: NyARToolkit\r
- * --------------------------------------------------------------------------------\r
- * This work is based on the original ARToolKit developed by\r
- * Hirokazu Kato\r
- * Mark Billinghurst\r
- * HITLab, University of Washington, Seattle\r
- * http://www.hitl.washington.edu/artoolkit/\r
- *\r
- * The NyARToolkit is Java edition ARToolKit class library.\r
- * Copyright (C)2008-2009 Ryo Iizuka\r
- *\r
- * This program is free software: you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation, either version 3 of the License, or\r
- * (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 program. If not, see <http://www.gnu.org/licenses/>.\r
- * \r
- * For further information please contact.\r
- * http://nyatla.jp/nyatoolkit/\r
- * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
- * \r
- */\r
-package jp.nyatla.nyartoolkit.core.squaredetect;\r
-\r
-import jp.nyatla.nyartoolkit.NyARException;\r
-import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
-import jp.nyatla.nyartoolkit.core.param.NyARObserv2IdealMap;\r
-import jp.nyatla.nyartoolkit.core.pca2d.INyARPca2d;\r
-import jp.nyatla.nyartoolkit.core.pca2d.NyARPca2d_MatrixPCA_O2;\r
-import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
-import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
-import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
-import jp.nyatla.nyartoolkit.core.types.NyARLinear;\r
-import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;\r
-\r
-\r
-\r
-\r
-public class SquareContourDetector\r
-{\r
- private final double[] _xpos;\r
- private final double[] _ypos; \r
- private final int[] __detectMarker_mkvertex = new int[4];\r
- private final INyARPca2d _pca;\r
- private final NyARDoubleMatrix22 __getSquareLine_evec=new NyARDoubleMatrix22();\r
- private final double[] __getSquareLine_mean=new double[2];\r
- private final double[] __getSquareLine_ev=new double[2];\r
- private final Coord2SquareVertexIndexes _coord2vertex=new Coord2SquareVertexIndexes();\r
- private final NyARObserv2IdealMap _dist_factor;\r
- public SquareContourDetector(NyARIntSize i_size,NyARCameraDistortionFactor i_distfactor_ref)\r
- {\r
- //歪み計算テーブルを作ると、8*width/height*2の領域を消費します。\r
- //領域を取りたくない場合は、i_dist_factor_refの値をそのまま使ってください。\r
- this._dist_factor = new NyARObserv2IdealMap(i_distfactor_ref,i_size);\r
-\r
-\r
- // 輪郭バッファ\r
- this._pca=new NyARPca2d_MatrixPCA_O2();\r
- this._xpos=new double[i_size.w+i_size.h];//最大辺長はthis._width+this._height\r
- this._ypos=new double[i_size.w+i_size.h];//最大辺長はthis._width+this._height\r
- return;\r
- }\r
-\r
- public boolean coordToSquare(int[] i_xcoord,int[] i_ycoord,int i_coord_num,int i_label_area,NyARSquare o_square) throws NyARException\r
- {\r
-\r
- final int[] mkvertex = this.__detectMarker_mkvertex;\r
- // 頂点情報を取得\r
- if (!this._coord2vertex.getVertexIndexes(i_xcoord, i_ycoord, i_coord_num, i_label_area, mkvertex)) {\r
- // 頂点の取得が出来なかったので破棄\r
- return false;\r
- }\r
- // マーカーを検出\r
- if (!getSquareLine(mkvertex, i_xcoord, i_ycoord,i_coord_num-1, o_square)){\r
- // 矩形が成立しなかった。\r
- return false;\r
- }\r
- return true;\r
- }\r
- \r
- private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord,int i_cood_num, NyARSquare o_square) throws NyARException\r
- {\r
- final NyARLinear[] l_line = o_square.line;\r
- final NyARDoubleMatrix22 evec=this.__getSquareLine_evec;\r
- final double[] mean=this.__getSquareLine_mean;\r
- final double[] ev=this.__getSquareLine_ev;\r
- \r
- double w1;\r
- for (int i = 0; i < 4; i++){\r
- //頂点を取得\r
- int ver1=i_mkvertex[i];\r
- int ver2=i_mkvertex[(i+1)%4];\r
- int n,st,ed;\r
- //探索区間の決定\r
- if(ver2>=i_mkvertex[i]){\r
- //頂点[i]から頂点[i+1]までの輪郭が、1区間にあるとき\r
- w1 = (double) (ver2 - ver1 + 1) * 0.05 + 0.5;\r
- //探索区間の決定\r
- st = (int) (ver1+w1);\r
- ed = (int) (ver2 - w1);\r
- }else{\r
- //頂点[i]から頂点[i+1]までの輪郭が、2区間に分かれているとき\r
- w1 = (double) (ver2+i_cood_num-ver1+1)%i_cood_num * 0.05 + 0.5;\r
- //探索区間の決定\r
- st = (int) (ver1+w1)%i_cood_num;\r
- ed = (int) (ver2+i_cood_num-w1)%i_cood_num;\r
- }\r
- //探索区間数を確認\r
- if(st<=ed){\r
- //探索区間は1区間\r
- n = ed - st + 1;\r
- this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st, n,this._xpos,this._ypos,0);\r
- }else{\r
- //探索区間は2区間\r
- n=ed+1+i_cood_num-st;\r
- this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st,i_cood_num-st,this._xpos,this._ypos,0);\r
- this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, 0,ed+1,this._xpos,this._ypos,i_cood_num-st);\r
- }\r
- //要素数の確認\r
- if (n < 2) {\r
- // nが2以下でmatrix.PCAを計算することはできないので、エラー\r
- return false;\r
- }\r
- //主成分分析する。\r
- this._pca.pca(this._xpos,this._ypos,n,evec, ev,mean);\r
- final NyARLinear l_line_i = l_line[i];\r
- l_line_i.dy = evec.m01;// line[i][0] = evec->m[1];\r
- l_line_i.dx = -evec.m00;// line[i][1] = -evec->m[0];\r
- l_line_i.c = -(l_line_i.dy * mean[0] + l_line_i.dx * mean[1]);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);\r
- }\r
-\r
- final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;\r
- final NyARIntPoint2d[] l_imvertex = o_square.imvertex;\r
- for (int i = 0; i < 4; i++) {\r
- //直線同士の交点計算\r
- if(!NyARLinear.crossPos(l_line[i],l_line[(i + 3) % 4],l_sqvertex[i])){\r
- return false;\r
- }\r
- // 頂点インデクスから頂点座標を得て保存\r
- l_imvertex[i].x = i_xcoord[i_mkvertex[i]];\r
- l_imvertex[i].y = i_ycoord[i_mkvertex[i]];\r
- }\r
- return true;\r
- } \r
-}
\ No newline at end of file
public interface INyARTransMat\r
{\r
public void setCenter(double i_x, double i_y);\r
- public void transMat(NyARSquare i_square, int i_direction, double i_width, NyARTransMatResult o_result) throws NyARException;\r
- public void transMatContinue(NyARSquare i_square, int i_direction, double i_width, NyARTransMatResult io_result_conv) throws NyARException;\r
+ public void transMat(NyARSquare i_square, double i_width, NyARTransMatResult o_result) throws NyARException;\r
+ public void transMatContinue(NyARSquare i_square, double i_width, NyARTransMatResult io_result_conv) throws NyARException;\r
}\r
\r
\r
\r
- /**\r
- * 頂点順序をi_directionに対応して並べ替えます。\r
- * @param i_square\r
- * @param i_direction\r
- * @param o_sqvertex_ref\r
- * @param o_liner_ref\r
- */\r
- private final void initVertexOrder(NyARSquare i_square, int i_direction, NyARDoublePoint2d[] o_sqvertex_ref, NyARLinear[] o_liner_ref)\r
- {\r
- //頂点順序を考慮した矩形の頂点情報\r
- o_sqvertex_ref[0]= i_square.sqvertex[(4 - i_direction) % 4];\r
- o_sqvertex_ref[1]= i_square.sqvertex[(5 - i_direction) % 4];\r
- o_sqvertex_ref[2]= i_square.sqvertex[(6 - i_direction) % 4];\r
- o_sqvertex_ref[3]= i_square.sqvertex[(7 - i_direction) % 4]; \r
- o_liner_ref[0]=i_square.line[(4 - i_direction) % 4];\r
- o_liner_ref[1]=i_square.line[(5 - i_direction) % 4];\r
- o_liner_ref[2]=i_square.line[(6 - i_direction) % 4];\r
- o_liner_ref[3]=i_square.line[(7 - i_direction) % 4];\r
- return;\r
- }\r
\r
\r
- private final NyARDoublePoint2d[] __transMat_sqvertex_ref = new NyARDoublePoint2d[4];\r
private final NyARDoublePoint2d[] __transMat_vertex_2d = NyARDoublePoint2d.createArray(4);\r
private final NyARDoublePoint3d[] __transMat_vertex_3d = NyARDoublePoint3d.createArray(4);\r
- private final NyARLinear[] __transMat_linear_ref=new NyARLinear[4];\r
private final NyARDoublePoint3d __transMat_trans=new NyARDoublePoint3d();\r
\r
/**\r
* @return\r
* @throws NyARException\r
*/\r
- public void transMat(final NyARSquare i_square, int i_direction, double i_width, NyARTransMatResult o_result_conv) throws NyARException\r
+ public void transMat(final NyARSquare i_square, double i_width, NyARTransMatResult o_result_conv) throws NyARException\r
{\r
- final NyARDoublePoint2d[] sqvertex_ref = __transMat_sqvertex_ref;\r
- final NyARLinear[] linear_ref=__transMat_linear_ref;\r
final NyARDoublePoint3d trans=this.__transMat_trans;\r
\r
double err_threshold=makeErrThreshold(i_square.sqvertex);\r
- //計算用に頂点情報を初期化(順番調整)\r
- initVertexOrder(i_square, i_direction, sqvertex_ref,linear_ref);\r
\r
//平行移動量計算機に、2D座標系をセット\r
NyARDoublePoint2d[] vertex_2d=this.__transMat_vertex_2d;\r
NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
- this._ref_dist_factor.ideal2ObservBatch(sqvertex_ref, vertex_2d,4); \r
+ this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4); \r
this._transsolver.set2dVertex(vertex_2d,4);\r
\r
//基準矩形の3D座標系を作成\r
this._offset.setSquare(i_width,this._center);\r
\r
//回転行列を計算\r
- this._rotmatrix.initRotBySquare(linear_ref,sqvertex_ref);\r
+ this._rotmatrix.initRotBySquare(i_square.line,i_square.sqvertex);\r
\r
//回転後の3D座標系から、平行移動量を計算\r
this._rotmatrix.getPoint3dBatch(this._offset.vertex,vertex_3d,4);\r
* (non-Javadoc)\r
* @see jp.nyatla.nyartoolkit.core.transmat.INyARTransMat#transMatContinue(jp.nyatla.nyartoolkit.core.NyARSquare, int, double, jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult)\r
*/\r
- public void transMatContinue(NyARSquare i_square, int i_direction, double i_width, NyARTransMatResult o_result_conv) throws NyARException\r
+ public void transMatContinue(NyARSquare i_square, double i_width, NyARTransMatResult o_result_conv) throws NyARException\r
{\r
- final NyARDoublePoint2d[] sqvertex_ref = __transMat_sqvertex_ref;\r
- final NyARLinear[] linear_ref=__transMat_linear_ref;\r
final NyARDoublePoint3d trans=this.__transMat_trans;\r
\r
// io_result_convが初期値なら、transMatで計算する。\r
if (!o_result_conv.has_value) {\r
- this.transMat(i_square, i_direction, i_width, o_result_conv);\r
+ this.transMat(i_square,i_width, o_result_conv);\r
return;\r
}\r
\r
//最適化計算の閾値を決定\r
double err_threshold=makeErrThreshold(i_square.sqvertex);\r
- //計算用に頂点情報を初期化(順番調整)\r
- initVertexOrder(i_square, i_direction, sqvertex_ref,linear_ref);\r
\r
\r
//平行移動量計算機に、2D座標系をセット\r
NyARDoublePoint2d[] vertex_2d=this.__transMat_vertex_2d;\r
NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
- this._ref_dist_factor.ideal2ObservBatch(sqvertex_ref, vertex_2d,4); \r
+ this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4); \r
this._transsolver.set2dVertex(vertex_2d,4);\r
\r
//基準矩形の3D座標系を作成\r
this.updateMatrixValue(this._rotmatrix, this._offset.point, trans,o_result_conv);\r
}else{\r
//回転行列を計算\r
- this._rotmatrix.initRotBySquare(linear_ref,sqvertex_ref);\r
+ this._rotmatrix.initRotBySquare(i_square.line,i_square.sqvertex);\r
\r
//回転後の3D座標系から、平行移動量を計算\r
this._rotmatrix.getPoint3dBatch(this._offset.vertex,vertex_3d,4);\r
import jp.nyatla.nyartoolkit.core.param.*;\r
import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
import jp.nyatla.nyartoolkit.core.transmat.solver.*;\r
-import jp.nyatla.nyartoolkit.core.transmat.optimize.*;\r
import jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit.INyARRotMatrixOptimize;\r
import jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit.NyARRotMatrixOptimize_O2;\r
import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
}\r
\r
\r
-\r
-\r
- /**\r
- * 頂点順序をi_directionに対応して並べ替えます。\r
- * @param i_square\r
- * @param i_direction\r
- * @param o_sqvertex_ref\r
- * @param o_liner_ref\r
- */\r
- private final void initVertexOrder(NyARSquare i_square, int i_direction, NyARDoublePoint2d[] o_sqvertex_ref, NyARLinear[] o_liner_ref)\r
- {\r
- //頂点順序を考慮した矩形の頂点情報\r
- o_sqvertex_ref[0]= i_square.sqvertex[(4 - i_direction) % 4];\r
- o_sqvertex_ref[1]= i_square.sqvertex[(5 - i_direction) % 4];\r
- o_sqvertex_ref[2]= i_square.sqvertex[(6 - i_direction) % 4];\r
- o_sqvertex_ref[3]= i_square.sqvertex[(7 - i_direction) % 4]; \r
- o_liner_ref[0]=i_square.line[(4 - i_direction) % 4];\r
- o_liner_ref[1]=i_square.line[(5 - i_direction) % 4];\r
- o_liner_ref[2]=i_square.line[(6 - i_direction) % 4];\r
- o_liner_ref[3]=i_square.line[(7 - i_direction) % 4];\r
- return;\r
- }\r
-\r
-\r
- private final NyARDoublePoint2d[] __transMat_sqvertex_ref = new NyARDoublePoint2d[4];\r
private final NyARDoublePoint2d[] __transMat_vertex_2d = NyARDoublePoint2d.createArray(4);\r
private final NyARDoublePoint3d[] __transMat_vertex_3d = NyARDoublePoint3d.createArray(4);\r
- private final NyARLinear[] __transMat_linear_ref=new NyARLinear[4];\r
private final NyARDoublePoint3d __transMat_trans=new NyARDoublePoint3d();\r
/**\r
* double arGetTransMat( ARMarkerInfo *marker_info,double center[2], double width, double conv[3][4] )\r
* \r
* @param i_square\r
* 計算対象のNyARSquareオブジェクト\r
- * @param i_direction\r
* @param i_width\r
* @return\r
* @throws NyARException\r
*/\r
- public void transMat(final NyARSquare i_square, int i_direction, double i_width, NyARTransMatResult o_result_conv) throws NyARException\r
+ public void transMat(final NyARSquare i_square, double i_width, NyARTransMatResult o_result_conv) throws NyARException\r
{\r
- final NyARDoublePoint2d[] sqvertex_ref = __transMat_sqvertex_ref;\r
- final NyARLinear[] linear_ref=__transMat_linear_ref;\r
final NyARDoublePoint3d trans=this.__transMat_trans;\r
\r
- //計算用に頂点情報を初期化(順番調整)\r
- initVertexOrder(i_square, i_direction, sqvertex_ref,linear_ref);\r
- \r
//平行移動量計算機に、2D座標系をセット\r
NyARDoublePoint2d[] vertex_2d=this.__transMat_vertex_2d;\r
NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
- this._ref_dist_factor.ideal2ObservBatch(sqvertex_ref, vertex_2d,4); \r
+ this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4); \r
this._transsolver.set2dVertex(vertex_2d,4);\r
\r
//基準矩形の3D座標系を作成\r
this._offset.setSquare(i_width,this._center);\r
\r
//回転行列を計算\r
- this._rotmatrix.initRotBySquare(linear_ref,sqvertex_ref);\r
+ this._rotmatrix.initRotBySquare(i_square.line,i_square.sqvertex);\r
\r
//回転後の3D座標系から、平行移動量を計算\r
this._rotmatrix.getPoint3dBatch(this._offset.vertex,vertex_3d,4);\r
* (non-Javadoc)\r
* @see jp.nyatla.nyartoolkit.core.transmat.INyARTransMat#transMatContinue(jp.nyatla.nyartoolkit.core.NyARSquare, int, double, jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult)\r
*/\r
- public void transMatContinue(NyARSquare i_square, int i_direction, double i_width, NyARTransMatResult o_result_conv) throws NyARException\r
+ public void transMatContinue(NyARSquare i_square, double i_width, NyARTransMatResult o_result_conv) throws NyARException\r
{\r
- final NyARDoublePoint2d[] sqvertex_ref = __transMat_sqvertex_ref;\r
- final NyARLinear[] linear_ref=__transMat_linear_ref;\r
final NyARDoublePoint3d trans=this.__transMat_trans;\r
\r
// io_result_convが初期値なら、transMatで計算する。\r
if (!o_result_conv.has_value) {\r
- this.transMat(i_square, i_direction, i_width, o_result_conv);\r
+ this.transMat(i_square, i_width, o_result_conv);\r
return;\r
}\r
-\r
- //計算用に頂点情報を初期化(順番調整)\r
- initVertexOrder(i_square, i_direction, sqvertex_ref,linear_ref);\r
-\r
\r
//平行移動量計算機に、2D座標系をセット\r
NyARDoublePoint2d[] vertex_2d=this.__transMat_vertex_2d;\r
NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
- this._ref_dist_factor.ideal2ObservBatch(sqvertex_ref, vertex_2d,4); \r
+ this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4); \r
this._transsolver.set2dVertex(vertex_2d,4);\r
\r
//基準矩形の3D座標系を作成\r
// エラー値が許容範囲でなければTransMatをやり直し\r
if (err > AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR) {\r
// rotationを矩形情報で初期化\r
- this._rotmatrix.initRotBySquare(linear_ref,sqvertex_ref);\r
+ this._rotmatrix.initRotBySquare(i_square.line,i_square.sqvertex);\r
//回転行列の平行移動量の計算\r
this._rotmatrix.getPoint3dBatch(this._offset.vertex,vertex_3d,4);\r
this._transsolver.solveTransportVector(vertex_3d,trans);\r
/**\r
* サンプリング値の格納変数\r
*/\r
- public int[] data;\r
+ public final int[] data;\r
/**\r
* 有効なサンプリング値の範囲。[0-data.length-1]\r
*/\r
* 有効なサンプルの総数 data[i]\r
*/\r
public int total_of_data;\r
+ \r
+ \r
+ \r
public NyARHistgram(int i_length)\r
{\r
this.data=new int[i_length];\r
import jp.nyatla.nyartoolkit.core.raster.*;\r
import jp.nyatla.nyartoolkit.core.transmat.*;\r
import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+import jp.nyatla.nyartoolkit.core.types.NyARLinear;\r
import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
import jp.nyatla.nyartoolkit.core.types.*;\r
import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
* \r
*/\r
public class NyARCustomSingleDetectMarker\r
-{ \r
- private static final int AR_SQUARE_MAX = 100;\r
-\r
+{\r
+ /**\r
+ * detectMarkerのコールバック関数\r
+ */\r
+ private class DetectSquareCB implements INyARSquareContourDetector.DetectMarkerCallback\r
+ {\r
+ //公開プロパティ\r
+ public double confidence;\r
+ public NyARSquare square=new NyARSquare();\r
+ \r
+ //参照インスタンス\r
+ private INyARRgbRaster _ref_raster;\r
+ //所有インスタンス\r
+ private INyARColorPatt _inst_patt;\r
+ private NyARMatchPattDeviationColorData _deviation_data;\r
+ private NyARMatchPatt_Color_WITHOUT_PCA _match_patt;\r
+ private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+ private Coord2Linear _coordline;\r
+ \r
+ public DetectSquareCB(INyARColorPatt i_inst_patt,NyARCode i_ref_code,NyARParam i_param)\r
+ {\r
+ this._inst_patt=i_inst_patt;\r
+ this._deviation_data=new NyARMatchPattDeviationColorData(i_ref_code.getWidth(),i_ref_code.getHeight());\r
+ this._coordline=new Coord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());\r
+ this._match_patt=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code);\r
+ return;\r
+ }\r
+ private NyARIntPoint2d[] __tmp_vertex=NyARIntPoint2d.createArray(4);\r
+ /**\r
+ * 矩形が見付かるたびに呼び出されます。\r
+ * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。\r
+ */\r
+ public void onSquareDetect(INyARSquareContourDetector i_sender,int[] i_coordx,int[] i_coordy,int i_coor_num,int[] i_vertex_index) throws NyARException\r
+ {\r
+ NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
+ //輪郭座標から頂点リストに変換\r
+ NyARIntPoint2d[] vertex=this.__tmp_vertex;\r
+ vertex[0].x=i_coordx[i_vertex_index[0]];\r
+ vertex[0].y=i_coordy[i_vertex_index[0]];\r
+ vertex[1].x=i_coordx[i_vertex_index[1]];\r
+ vertex[1].y=i_coordy[i_vertex_index[1]];\r
+ vertex[2].x=i_coordx[i_vertex_index[2]];\r
+ vertex[2].y=i_coordy[i_vertex_index[2]];\r
+ vertex[3].x=i_coordx[i_vertex_index[3]];\r
+ vertex[3].y=i_coordy[i_vertex_index[3]];\r
+ \r
+ //画像を取得\r
+ if (!this._inst_patt.pickFromRaster(this._ref_raster,vertex)){\r
+ return;\r
+ }\r
+ //取得パターンをカラー差分データに変換して評価する。\r
+ this._deviation_data.setRaster(this._inst_patt);\r
+ if(!this._match_patt.evaluate(this._deviation_data,mr)){\r
+ return;\r
+ }\r
+ //現在の一致率より低ければ終了\r
+ if (this.confidence > mr.confidence){\r
+ return;\r
+ }\r
+ //一致率の高い矩形があれば、方位を考慮して頂点情報を作成\r
+ NyARSquare sq=this.square;\r
+ this.confidence = mr.confidence;\r
+ //directionを考慮して、squareを更新する。\r
+ for(int i=0;i<4;i++){\r
+ int idx=(i+4 - mr.direction) % 4;\r
+ sq.imvertex[i].x=vertex[idx].x;\r
+ sq.imvertex[i].y=vertex[idx].y;\r
+ this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coordx,i_coordy,i_coor_num,sq.line[i]);\r
+ }\r
+ for (int i = 0; i < 4; i++) {\r
+ //直線同士の交点計算\r
+ if(!NyARLinear.crossPos(sq.line[i],sq.line[(i + 3) % 4],sq.sqvertex[i])){\r
+ throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK\r
+ }\r
+ }\r
+ }\r
+ public final void init(INyARRgbRaster i_raster)\r
+ {\r
+ this.confidence=0;\r
+ this._ref_raster=i_raster;\r
+ \r
+ }\r
+ }\r
+ \r
private boolean _is_continue = false;\r
- private NyARMatchPatt_Color_WITHOUT_PCA _match_patt;\r
- private INyARSquareDetector _square_detect;\r
-\r
- private final NyARSquareStack _square_list = new NyARSquareStack(AR_SQUARE_MAX);\r
-\r
+ private INyARSquareContourDetector _square_detect;\r
protected INyARTransMat _transmat;\r
-\r
private double _marker_width;\r
- // 検出結果の保存用\r
- private int _detected_direction;\r
- private double _detected_confidence;\r
- private NyARSquare _detected_square;\r
- private INyARColorPatt _patt;\r
//画処理用\r
private NyARBinRaster _bin_raster;\r
protected INyARRasterFilter_RgbToBin _tobin_filter;\r
+ private DetectSquareCB _detect_cb;\r
\r
- private NyARMatchPattDeviationColorData _deviation_data;\r
\r
protected NyARCustomSingleDetectMarker()\r
{\r
}\r
protected void initInstance(\r
INyARColorPatt i_patt_inst,\r
- INyARSquareDetector i_sqdetect_inst,\r
+ INyARSquareContourDetector i_sqdetect_inst,\r
INyARTransMat i_transmat_inst,\r
INyARRasterFilter_RgbToBin i_filter,\r
NyARParam i_ref_param,\r
this._tobin_filter=i_filter;\r
// 比較コードを保存\r
this._marker_width = i_marker_width;\r
- //パターンピックアップを作成\r
- this._patt = i_patt_inst;\r
- //取得パターンの差分データ器を作成\r
- this._deviation_data=new NyARMatchPattDeviationColorData(i_ref_code.getWidth(),i_ref_code.getHeight());\r
- //i_code用の評価器を作成\r
- this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code);\r
//2値画像バッファを作る\r
this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);\r
+ //_detect_cb\r
+ this._detect_cb=new DetectSquareCB(i_patt_inst,i_ref_code,i_ref_param);\r
return;\r
\r
}\r
\r
- private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+ \r
\r
+ \r
/**\r
* i_imageにマーカー検出処理を実行し、結果を記録します。\r
* \r
//ラスタを2値イメージに変換する.\r
this._tobin_filter.doFilter(i_raster,this._bin_raster);\r
\r
- \r
- this._detected_square = null;\r
- NyARSquareStack l_square_list = this._square_list;\r
- // スクエアコードを探す\r
- this._square_detect.detectMarker(this._bin_raster, l_square_list);\r
-\r
-\r
- int number_of_square = l_square_list.getLength();\r
- // コードは見つかった?\r
- if (number_of_square < 1) {\r
+ //コールバックハンドラの準備\r
+ this._detect_cb.init(i_raster);\r
+ //矩形を探す(戻り値はコールバック関数で受け取る。)\r
+ this._square_detect.detectMarkerCB(this._bin_raster,_detect_cb);\r
+ if(this._detect_cb.confidence==0){\r
return false;\r
}\r
- \r
- boolean result=false;\r
- NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
- int square_index = 0;\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, l_square_list.getItem(i).imvertex)){\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 = mr.direction;\r
- confidence = c2;\r
- result=true;\r
- }\r
- \r
- // マーカー情報を保存\r
- this._detected_square = l_square_list.getItem(square_index);\r
- this._detected_direction = direction;\r
- this._detected_confidence = confidence;\r
- return result;\r
+ return true;\r
}\r
\r
/**\r
{\r
// 一番一致したマーカーの位置とかその辺を計算\r
if (this._is_continue) {\r
- this._transmat.transMatContinue(this._detected_square,this._detected_direction,this._marker_width, o_result);\r
+ this._transmat.transMatContinue(this._detect_cb.square,this._marker_width, o_result);\r
} else {\r
- this._transmat.transMat(this._detected_square,this._detected_direction,this._marker_width, o_result);\r
+ this._transmat.transMat(this._detect_cb.square,this._marker_width, o_result);\r
}\r
return;\r
}\r
*/\r
public void getSquarePosition(NyARIntPoint2d[] o_point)\r
{\r
- NyARIntPoint2d.copyArray(this._detected_square.imvertex,o_point);\r
+ NyARIntPoint2d.copyArray(this._detect_cb.square.imvertex,o_point);\r
return;\r
}\r
/**\r
*/\r
public NyARIntPoint2d[] refSquarePosition()\r
{\r
- return this._detected_square.imvertex;\r
+ return this._detect_cb.square.imvertex;\r
}\r
\r
\r
*/\r
public double getConfidence()\r
{\r
- return this._detected_confidence;\r
+ return this._detect_cb.confidence;\r
}\r
-\r
- /**\r
- * 検出したマーカーの方位を返します。\r
- * \r
- * @return 0,1,2,3の何れかを返します。\r
- */\r
- public int getDirection()\r
- {\r
- return this._detected_direction;\r
- }\r
-\r
/**\r
* getTransmationMatrixの計算モードを設定します。 初期値はTRUEです。\r
* \r
{\r
this._is_continue = i_is_continue;\r
}\r
+ \r
+ \r
+ \r
+ \r
}\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.squaredetect.INyARSquareDetector;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.Coord2Linear;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareContourDetector;\r
import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
-import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareDetector_Rle;\r
-import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareContourDetector_Rle;\r
import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.utils.NyObjectStack;\r
\r
class NyARDetectMarkerResult\r
{\r
public int arcode_id;\r
-\r
- public int direction;\r
-\r
public double confidence;\r
\r
- public NyARSquare ref_square;\r
+ public NyARSquare square=new NyARSquare();\r
}\r
\r
-class NyARDetectMarkerResultHolder\r
-{\r
- public NyARDetectMarkerResult[] result_array = new NyARDetectMarkerResult[1];\r
\r
- /**\r
- * result_holderを最大i_reserve_size個の要素を格納できるように予約します。\r
- * \r
- * @param i_reserve_size\r
- */\r
- public void reservHolder(int i_reserve_size)\r
+class NyARDetectMarkerResultStack extends NyObjectStack<NyARDetectMarkerResult>\r
+{\r
+ public NyARDetectMarkerResultStack(int i_length)\r
{\r
- if (i_reserve_size >= result_array.length) {\r
- int new_size = i_reserve_size + 5;\r
- result_array = new NyARDetectMarkerResult[new_size];\r
- for (int i = 0; i < new_size; i++) {\r
- result_array[i] = new NyARDetectMarkerResult();\r
- }\r
- }\r
+ super(i_length,NyARDetectMarkerResult.class);\r
+ return;\r
}\r
+ protected NyARDetectMarkerResult createElement()\r
+ {\r
+ return new NyARDetectMarkerResult();\r
+ } \r
}\r
\r
+\r
/**\r
* 複数のマーカーを検出し、それぞれに最も一致するARコードを、コンストラクタで登録したARコードから 探すクラスです。最大300個を認識しますが、ゴミラベルを認識したりするので100個程度が限界です。\r
* \r
*/\r
public class NyARDetectMarker\r
{\r
- private static final int AR_SQUARE_MAX = 300;\r
+ /**\r
+ * detectMarkerのコールバック関数\r
+ */\r
+ private class DetectSquareCB implements INyARSquareContourDetector.DetectMarkerCallback\r
+ {\r
+ //公開プロパティ\r
+ public NyARDetectMarkerResultStack result_stack=new NyARDetectMarkerResultStack(NyARDetectMarker.AR_SQUARE_MAX);\r
+ //参照インスタンス\r
+ public INyARRgbRaster _ref_raster;\r
+ //所有インスタンス\r
+ private INyARColorPatt _inst_patt;\r
+ private NyARMatchPattDeviationColorData _deviation_data;\r
+ private NyARMatchPatt_Color_WITHOUT_PCA[] _match_patt;\r
+ private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+ private Coord2Linear _coordline;\r
+ \r
+ public DetectSquareCB(INyARColorPatt i_inst_patt,NyARCode[] i_ref_code,int i_num_of_code,NyARParam i_param) throws NyARException\r
+ {\r
+ final int cw = i_ref_code[0].getWidth();\r
+ final int ch = i_ref_code[0].getHeight();\r
+\r
+ this._inst_patt=i_inst_patt;\r
+ this._coordline=new Coord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());\r
+ this._deviation_data=new NyARMatchPattDeviationColorData(cw,ch);\r
+\r
+ //NyARMatchPatt_Color_WITHOUT_PCA[]の作成\r
+ this._match_patt=new NyARMatchPatt_Color_WITHOUT_PCA[i_num_of_code];\r
+ this._match_patt[0]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[0]);\r
+ for (int i = 1; i < i_num_of_code; i++){\r
+ //解像度チェック\r
+ if (cw != i_ref_code[i].getWidth() || ch != i_ref_code[i].getHeight()) {\r
+ throw new NyARException();\r
+ }\r
+ this._match_patt[i]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[i]);\r
+ }\r
+ return;\r
+ }\r
+ private NyARIntPoint2d[] __tmp_vertex=NyARIntPoint2d.createArray(4);\r
+ /**\r
+ * 矩形が見付かるたびに呼び出されます。\r
+ * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。\r
+ */\r
+ public void onSquareDetect(INyARSquareContourDetector i_sender,int[] i_coordx,int[] i_coordy,int i_coor_num,int[] i_vertex_index) throws NyARException\r
+ {\r
+ NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
+ //輪郭座標から頂点リストに変換\r
+ NyARIntPoint2d[] vertex=this.__tmp_vertex;\r
+ vertex[0].x=i_coordx[i_vertex_index[0]];\r
+ vertex[0].y=i_coordy[i_vertex_index[0]];\r
+ vertex[1].x=i_coordx[i_vertex_index[1]];\r
+ vertex[1].y=i_coordy[i_vertex_index[1]];\r
+ vertex[2].x=i_coordx[i_vertex_index[2]];\r
+ vertex[2].y=i_coordy[i_vertex_index[2]];\r
+ vertex[3].x=i_coordx[i_vertex_index[3]];\r
+ vertex[3].y=i_coordy[i_vertex_index[3]];\r
+ \r
+ //画像を取得\r
+ if (!this._inst_patt.pickFromRaster(this._ref_raster,vertex)){\r
+ return;\r
+ }\r
+ //取得パターンをカラー差分データに変換して評価する。\r
+ this._deviation_data.setRaster(this._inst_patt);\r
+\r
+ //最も一致するパターンを割り当てる。\r
+ int square_index,direction;\r
+ double confidence;\r
+ this._match_patt[0].evaluate(this._deviation_data,mr);\r
+ square_index=0;\r
+ direction=mr.direction;\r
+ confidence=mr.confidence;\r
+ //2番目以降\r
+ for(int i=1;i<this._match_patt.length;i++){\r
+ this._match_patt[i].evaluate(this._deviation_data,mr);\r
+ if (confidence > mr.confidence) {\r
+ continue;\r
+ }\r
+ // もっと一致するマーカーがあったぽい\r
+ square_index = i;\r
+ direction = mr.direction;\r
+ confidence = mr.confidence;\r
+ }\r
+ //最も一致したマーカ情報を、この矩形の情報として記録する。\r
+ final NyARDetectMarkerResult result = this.result_stack.prePush();\r
+ result.arcode_id = square_index;\r
+ result.confidence = confidence;\r
\r
+ final NyARSquare sq=result.square;\r
+ //directionを考慮して、squareを更新する。\r
+ for(int i=0;i<4;i++){\r
+ int idx=(i+4 - direction) % 4;\r
+ sq.imvertex[i].x=vertex[idx].x;\r
+ sq.imvertex[i].y=vertex[idx].y;\r
+ this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coordx,i_coordy,i_coor_num,sq.line[i]);\r
+ }\r
+ for (int i = 0; i < 4; i++) {\r
+ //直線同士の交点計算\r
+ if(!NyARLinear.crossPos(sq.line[i],sq.line[(i + 3) % 4],sq.sqvertex[i])){\r
+ throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK\r
+ }\r
+ }\r
+ }\r
+ public void init(INyARRgbRaster i_raster)\r
+ {\r
+ this._ref_raster=i_raster;\r
+ this.result_stack.clear();\r
+ \r
+ }\r
+ } \r
+ private DetectSquareCB _detect_cb;\r
+ \r
+ \r
+ private static final int AR_SQUARE_MAX = 300;\r
private boolean _is_continue = false;\r
-\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 INyARSquareContourDetector _square_detect;\r
protected INyARTransMat _transmat;\r
-\r
private double[] _marker_width; \r
\r
- // 検出結果の保存用\r
- private INyARColorPatt _patt;\r
\r
- private NyARDetectMarkerResultHolder _result_holder = new NyARDetectMarkerResultHolder();\r
- private NyARMatchPattDeviationColorData _deviation_data;\r
/**\r
* 複数のマーカーを検出し、最も一致するARCodeをi_codeから検索するオブジェクトを作ります。\r
* \r
\r
final NyARIntSize scr_size=i_ref_param.getScreenSize();\r
// 解析オブジェクトを作る\r
-\r
- this._transmat = new NyARTransMat(i_ref_param);\r
- //各コード用の比較器を作る。\r
- this._match_patt=new NyARMatchPatt_Color_WITHOUT_PCA[i_number_of_code];\r
final int cw = i_ref_code[0].getWidth();\r
final int ch = i_ref_code[0].getHeight();\r
- this._match_patt[0]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[0]);\r
- for (int i = 1; i < i_number_of_code; i++){\r
- //解像度チェック\r
- if (cw != i_ref_code[i].getWidth() || ch != i_ref_code[i].getHeight()) {\r
- throw new NyARException();\r
- }\r
- this._match_patt[i]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[i]);\r
- }\r
+\r
+ //detectMarkerのコールバック関数\r
+ this._detect_cb=new DetectSquareCB(\r
+ new NyARColorPatt_Perspective_O2(cw, ch,4,25),\r
+ i_ref_code,i_number_of_code,i_ref_param);\r
+ this._transmat = new NyARTransMat(i_ref_param);\r
//NyARToolkitプロファイル\r
- this._patt =new NyARColorPatt_Perspective_O2(cw, ch,4,25);\r
- this._square_detect =new NyARSquareDetector_Rle(i_ref_param.getDistortionFactor(),i_ref_param.getScreenSize());\r
+ this._square_detect =new NyARSquareContourDetector_Rle(i_ref_param.getDistortionFactor(),i_ref_param.getScreenSize());\r
this._tobin_filter=new NyARRasterFilter_ARToolkitThreshold(100,i_input_raster_type);\r
\r
//実サイズ保存\r
this._marker_width = i_marker_width;\r
- //差分データインスタンスの作成\r
- this._deviation_data=new NyARMatchPattDeviationColorData(cw,ch);\r
//2値画像バッファを作る\r
this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);\r
return; \r
private NyARBinRaster _bin_raster;\r
\r
private INyARRasterFilter_RgbToBin _tobin_filter;\r
- private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
\r
/**\r
* i_imageにマーカー検出処理を実行し、結果を記録します。\r
((NyARRasterFilter_ARToolkitThreshold)this._tobin_filter).setThreshold(i_threshold);\r
this._tobin_filter.doFilter(i_raster, this._bin_raster);\r
\r
- NyARSquareStack l_square_list = this._square_list;\r
- // スクエアコードを探す\r
- this._square_detect.detectMarker(this._bin_raster, l_square_list);\r
-\r
- final int number_of_square = l_square_list.getLength();\r
- // コードは見つかった?\r
- if (number_of_square < 1) {\r
- // ないや。おしまい。\r
- return 0;\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 = (l_square_list.getItem(i));\r
-\r
- // 評価基準になるパターンをイメージから切り出す\r
- if (!this._patt.pickFromRaster(i_raster, square.imvertex)) {\r
- // イメージの切り出しは失敗することもある。\r
- continue;\r
- }\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
+ //detect\r
+ this._detect_cb.init(i_raster);\r
+ this._square_detect.detectMarkerCB(this._bin_raster,this._detect_cb);\r
\r
- final double c2 = mr.confidence;\r
- if (confidence > c2) {\r
- continue;\r
- }\r
- // もっと一致するマーカーがあったぽい\r
- square_index = i2;\r
- direction = mr.direction;\r
- confidence = c2;\r
- }\r
- // i番目のパターン情報を記録する。\r
- final NyARDetectMarkerResult result = this._result_holder.result_array[i];\r
- result.arcode_id = square_index;\r
- result.confidence = confidence;\r
- result.direction = direction;\r
- result.ref_square = square;\r
- }\r
- return number_of_square;\r
+ //見付かった数を返す。\r
+ return this._detect_cb.result_stack.getLength();\r
}\r
\r
/**\r
*/\r
public void getTransmationMatrix(int i_index, NyARTransMatResult o_result) throws NyARException\r
{\r
- final NyARDetectMarkerResult result = this._result_holder.result_array[i_index];\r
+ final NyARDetectMarkerResult result = this._detect_cb.result_stack.getItem(i_index);\r
// 一番一致したマーカーの位置とかその辺を計算\r
if (_is_continue) {\r
- _transmat.transMatContinue(result.ref_square, result.direction, _marker_width[result.arcode_id], o_result);\r
+ _transmat.transMatContinue(result.square, _marker_width[result.arcode_id], o_result);\r
} else {\r
- _transmat.transMat(result.ref_square, result.direction, _marker_width[result.arcode_id], o_result);\r
+ _transmat.transMat(result.square, _marker_width[result.arcode_id], o_result);\r
}\r
return;\r
}\r
*/\r
public double getConfidence(int i_index)\r
{\r
- return this._result_holder.result_array[i_index].confidence;\r
+ return this._detect_cb.result_stack.getItem(i_index).confidence;\r
}\r
-\r
- /**\r
- * i_indexのマーカーの方位を返します。\r
- * \r
- * @param i_index\r
- * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。\r
- * @return 0,1,2,3の何れかを返します。\r
- */\r
- public int getDirection(int i_index)\r
- {\r
- return this._result_holder.result_array[i_index].direction;\r
- }\r
-\r
/**\r
* i_indexのマーカーのARCodeインデックスを返します。\r
* \r
*/\r
public int getARCodeIndex(int i_index)\r
{\r
- return this._result_holder.result_array[i_index].arcode_id;\r
+ return this._detect_cb.result_stack.getItem(i_index).arcode_id;\r
}\r
\r
/**\r
{\r
final NyARRasterFilter_ARToolkitThreshold th=new NyARRasterFilter_ARToolkitThreshold(100,i_input_raster_type);\r
INyARColorPatt patt_inst;\r
- INyARSquareDetector sqdetect_inst;\r
+ INyARSquareContourDetector sqdetect_inst;\r
INyARTransMat transmat_inst;\r
\r
switch(i_profile_id){\r
case PF_ARTOOLKIT_COMPATIBLE:\r
patt_inst=new NyARColorPatt_O3(i_ref_code.getWidth(), i_ref_code.getHeight());\r
- sqdetect_inst=new NyARSquareDetector_ARToolKit(i_ref_param.getDistortionFactor(),i_ref_param.getScreenSize());\r
+ sqdetect_inst=new NyARSquareContourDetector_ARToolKit(i_ref_param.getDistortionFactor(),i_ref_param.getScreenSize());\r
transmat_inst=new NyARTransMat_ARToolKit(i_ref_param);\r
break;\r
case PF_NYARTOOLKIT_ARTOOLKIT_FITTING:\r
patt_inst=new NyARColorPatt_Perspective_O2(i_ref_code.getWidth(), i_ref_code.getHeight(),4,25);\r
- sqdetect_inst=new NyARSquareDetector_Rle(i_ref_param.getDistortionFactor(),i_ref_param.getScreenSize());\r
+ sqdetect_inst=new NyARSquareContourDetector_Rle(i_ref_param.getDistortionFactor(),i_ref_param.getScreenSize());\r
transmat_inst=new NyARTransMat_ARToolKit(i_ref_param);\r
break;\r
case PF_NYARTOOLKIT://default\r
patt_inst=new NyARColorPatt_Perspective_O2(i_ref_code.getWidth(), i_ref_code.getHeight(),4,25);\r
- sqdetect_inst=new NyARSquareDetector_Rle(i_ref_param.getDistortionFactor(),i_ref_param.getScreenSize());\r
+ sqdetect_inst=new NyARSquareContourDetector_Rle(i_ref_param.getDistortionFactor(),i_ref_param.getScreenSize());\r
transmat_inst=new NyARTransMat(i_ref_param);\r
break;\r
default:\r
* @return\r
* @throws NyARException\r
*/\r
- public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square,NyIdMarkerPattern o_data,NyIdMarkerParam o_param)throws NyARException\r
+ public boolean pickFromRaster(INyARRgbRaster image, NyARIntPoint2d[] i_vertex,NyIdMarkerPattern o_data,NyIdMarkerParam o_param)throws NyARException\r
{\r
\r
//遠近法のパラメータを計算\r
- if(!this._perspective_reader.setSourceSquare(i_square.imvertex)){\r
+ if(!this._perspective_reader.setSourceSquare(i_vertex)){\r
return false;\r
};\r
\r
return false;\r
}\r
for(int i=s.length-1;i>=0;i--){\r
- if(s.packet[i]!=s.packet[i]){\r
+ if(s.packet[i]!=this.packet[i]){\r
return false;\r
}\r
}\r
*/\r
public abstract class SingleARMarkerProcesser\r
{\r
- /**selectARCodeIndexFromListが値を返す時に使う変数型です。\r
+ /**\r
+ * detectMarkerのコールバック関数\r
*/\r
-\r
- private class TResult_selectARCodeIndex\r
+ private class DetectSquareCB implements INyARSquareContourDetector.DetectMarkerCallback\r
{\r
- public int direction;\r
-\r
- public double confidence;\r
+ //公開プロパティ\r
+ public final NyARSquare square=new NyARSquare();\r
+ public double confidence=0.0;\r
+ public int code_index=-1; \r
+ public double cf_threshold_new = 0.30;\r
+ public double cf_threshold_exist = 0.15;\r
+ \r
+ //参照\r
+ private INyARRgbRaster _ref_raster;\r
+ //所有インスタンス\r
+ private INyARColorPatt _inst_patt;\r
+ private NyARMatchPattDeviationColorData _deviation_data;\r
+ private NyARMatchPatt_Color_WITHOUT_PCA[] _match_patt;\r
+ private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+ private Coord2Linear _coordline;\r
+ \r
+ public DetectSquareCB(NyARParam i_param)\r
+ {\r
+ this._match_patt=null;\r
+ this._coordline=new Coord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());\r
+ return;\r
+ }\r
+ public void setNyARCodeTable(NyARCode[] i_ref_code,int i_code_resolution)\r
+ {\r
+ /*unmanagedで実装するときは、ここでリソース解放をすること。*/\r
+ this._deviation_data=new NyARMatchPattDeviationColorData(i_code_resolution,i_code_resolution);\r
+ this._inst_patt=new NyARColorPatt_Perspective_O2(i_code_resolution,i_code_resolution,4,25);\r
+ this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA[i_ref_code.length];\r
+ for(int i=0;i<i_ref_code.length;i++){\r
+ this._match_patt[i]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[i]);\r
+ }\r
+ }\r
+ private NyARIntPoint2d[] __tmp_vertex=NyARIntPoint2d.createArray(4);\r
+ /**\r
+ * Initialize call back handler.\r
+ */\r
+ public void init(INyARRgbRaster i_raster)\r
+ {\r
+ this._ref_raster=i_raster;\r
+ this.code_index=-1;\r
+ this.confidence=Double.MIN_NORMAL;\r
+ }\r
\r
- public int code_index;\r
- }\r
+ /**\r
+ * 矩形が見付かるたびに呼び出されます。\r
+ * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。\r
+ */\r
+ public void onSquareDetect(INyARSquareContourDetector i_sender,int[] i_coordx,int[] i_coordy,int i_coor_num,int[] i_vertex_index) throws NyARException\r
+ {\r
+ if (this._match_patt==null) {\r
+ return;\r
+ }\r
+ //輪郭座標から頂点リストに変換\r
+ NyARIntPoint2d[] vertex=this.__tmp_vertex;\r
+ vertex[0].x=i_coordx[i_vertex_index[0]];\r
+ vertex[0].y=i_coordy[i_vertex_index[0]];\r
+ vertex[1].x=i_coordx[i_vertex_index[1]];\r
+ vertex[1].y=i_coordy[i_vertex_index[1]];\r
+ vertex[2].x=i_coordx[i_vertex_index[2]];\r
+ vertex[2].y=i_coordy[i_vertex_index[2]];\r
+ vertex[3].x=i_coordx[i_vertex_index[3]];\r
+ vertex[3].y=i_coordy[i_vertex_index[3]];\r
+ \r
+ //画像を取得\r
+ if (!this._inst_patt.pickFromRaster(this._ref_raster,vertex)){\r
+ return;//取得失敗\r
+ }\r
+ //取得パターンをカラー差分データに変換して評価する。\r
+ this._deviation_data.setRaster(this._inst_patt);\r
+\r
+ \r
+ //code_index,dir,c1にデータを得る。\r
+ final NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
+ int lcode_index = 0;\r
+ int dir = 0;\r
+ double c1 = 0;\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
+ lcode_index = i;\r
+ c1 = c2;\r
+ dir = mr.direction;\r
+ }\r
+ }\r
+ \r
+ //認識処理\r
+ if (this.code_index == -1) { // マーカ未認識\r
+ //現在は未認識\r
+ if (c1 < this.cf_threshold_new) {\r
+ return;\r
+ }\r
+ if (this.confidence > c1) {\r
+ // 一致度が低い。\r
+ return;\r
+ }\r
+ //認識しているマーカIDを保存\r
+ this.code_index=lcode_index;\r
+ }else{\r
+ //現在はマーカ認識中 \r
+ // 現在のマーカを認識したか?\r
+ if (lcode_index != this.code_index) {\r
+ // 認識中のマーカではないので無視\r
+ return;\r
+ }\r
+ //認識中の閾値より大きいか?\r
+ if (c1 < this.cf_threshold_exist) {\r
+ return;\r
+ }\r
+ //現在の候補よりも一致度は大きいか?\r
+ if (this.confidence>c1) {\r
+ return;\r
+ }\r
+ }\r
+ //新しく認識、または継続認識中に更新があったときだけ、Square情報を更新する。\r
+ //ココから先はこの条件でしか実行されない。\r
+ \r
+ //一致率の高い矩形があれば、方位を考慮して頂点情報を作成\r
+ this.confidence=c1;\r
+ NyARSquare sq=this.square;\r
+ //directionを考慮して、squareを更新する。\r
+ for(int i=0;i<4;i++){\r
+ int idx=(i+4 - dir) % 4;\r
+ sq.imvertex[i].x=vertex[idx].x;\r
+ sq.imvertex[i].y=vertex[idx].y;\r
+ this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coordx,i_coordy,i_coor_num,sq.line[i]);\r
+ }\r
+ for (int i = 0; i < 4; i++) {\r
+ //直線同士の交点計算\r
+ if(!NyARLinear.crossPos(sq.line[i],sq.line[(i + 3) % 4],sq.sqvertex[i])){\r
+ throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK\r
+ }\r
+ }\r
+ }\r
+ } \r
/**オーナーが自由に使えるタグ変数です。\r
*/\r
public Object tag;\r
\r
private int _lost_delay = 5;\r
\r
- private INyARSquareDetector _square_detect;\r
+ private INyARSquareContourDetector _square_detect;\r
\r
protected INyARTransMat _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 INyARColorPatt _patt = null;\r
-\r
- private double _cf_threshold_new = 0.30;\r
- private double _cf_threshold_exist = 0.15;\r
- \r
private int _threshold = 110;\r
// [AR]検出結果の保存用\r
private NyARBinRaster _bin_raster;\r
\r
protected int _current_arcode_index = -1;\r
\r
- private NyARMatchPattDeviationColorData _deviation_data;\r
private NyARRasterThresholdAnalyzer_SlidePTile _threshold_detect;\r
\r
protected SingleARMarkerProcesser()\r
\r
NyARIntSize scr_size = i_param.getScreenSize();\r
// 解析オブジェクトを作る\r
- this._square_detect = new NyARSquareDetector_Rle(i_param.getDistortionFactor(), scr_size);\r
+ this._square_detect = new NyARSquareContourDetector_Rle(i_param.getDistortionFactor(), scr_size);\r
this._transmat = new NyARTransMat(i_param);\r
this._tobin_filter=new NyARRasterFilter_ARToolkitThreshold(110,i_raster_type);\r
\r
this._bin_raster = new NyARBinRaster(scr_size.w, scr_size.h);\r
this._threshold_detect=new NyARRasterThresholdAnalyzer_SlidePTile(15,i_raster_type,4);\r
this._initialized=true;\r
+ //コールバックハンドラ\r
+ this._detectmarker_cb=new DetectSquareCB(i_param);\r
+ \r
return;\r
}\r
\r
reset(true);\r
}\r
//検出するマーカセット、情報、検出器を作り直す。(1ピクセル4ポイントサンプリング,マーカのパターン領域は50%)\r
- this._patt = new NyARColorPatt_Perspective_O2(i_code_resolution, i_code_resolution,4,25);\r
- this._deviation_data=new NyARMatchPattDeviationColorData(i_code_resolution, i_code_resolution);\r
+ this._detectmarker_cb.setNyARCodeTable(i_ref_code_table,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
this._current_arcode_index = -1;\r
return;\r
}\r
-\r
+ private DetectSquareCB _detectmarker_cb;\r
public void detectMarker(INyARRgbRaster i_raster) throws NyARException\r
{\r
// サイズチェック\r
assert(this._bin_raster.getSize().isEqualSize(i_raster.getSize().w, i_raster.getSize().h));\r
\r
- // コードテーブルが無ければここで終わり\r
- if (this._match_patt== null) {\r
- return;\r
- }\r
-\r
- // ラスタを(1/4の画像の)2値イメージに変換する.\r
+ //BINイメージへの変換\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.imvertex)) {\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, (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
- final boolean is_id_found=updateStatus(this._square_list.getItem(square_index), code_index, cf, dir);\r
- //閾値フィードバック(detectExistMarkerにもあるよ)\r
- if(!is_id_found){\r
- //マーカがなければ、探索+DualPTailで基準輝度検索\r
- int th=this._threshold_detect.analyzeRaster(i_raster);\r
- this._threshold=(this._threshold+th)/2;\r
- }\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,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
+ this._detectmarker_cb.init(i_raster);\r
+ this._square_detect.detectMarkerCB(this._bin_raster,this._detectmarker_cb);\r
+ \r
// 認識状態を更新\r
- final boolean is_id_found=updateStatus(this._square_list.getItem(square_index), code_index, cf, dir);\r
+ final boolean is_id_found=updateStatus(this._detectmarker_cb.square,this._detectmarker_cb.code_index);\r
//閾値フィードバック(detectExistMarkerにもあるよ)\r
if(!is_id_found){\r
//マーカがなければ、探索+DualPTailで基準輝度検索\r
this._threshold=(this._threshold+th)/2;\r
}\r
\r
+ \r
+ return;\r
}\r
\r
private NyARTransMatResult __NyARSquare_result = new NyARTransMatResult();\r
/** オブジェクトのステータスを更新し、必要に応じてハンドル関数を駆動します。\r
* 戻り値は、「実際にマーカを発見する事ができたか」です。クラスの状態とは異なります。\r
*/\r
- private boolean updateStatus(NyARSquare i_square, int i_code_index, double i_cf, int i_dir) throws NyARException\r
+ private boolean updateStatus(NyARSquare i_square, int i_code_index) throws NyARException\r
{\r
NyARTransMatResult result = this.__NyARSquare_result;\r
if (this._current_arcode_index < 0) {// 未認識中\r
// OnEnter\r
this.onEnterHandler(i_code_index);\r
// 変換行列を作成\r
- this._transmat.transMat(i_square, i_dir, this._marker_width, result);\r
+ this._transmat.transMat(i_square, this._marker_width, result);\r
// OnUpdate\r
this.onUpdateHandler(i_square, result);\r
this._lost_delay_count = 0;\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
+ this._transmat.transMat(i_square, this._marker_width, result);\r
// OnUpdate\r
this.onUpdateHandler(i_square, result);\r
this._lost_delay_count = 0;\r
public abstract class SingleNyIdMarkerProcesser\r
{\r
/**\r
+ * detectMarkerのコールバック関数\r
+ */\r
+ private class DetectSquareCB implements INyARSquareContourDetector.DetectMarkerCallback\r
+ {\r
+ //公開プロパティ\r
+ public final NyARSquare square=new NyARSquare();\r
+ public INyIdMarkerData marker_data;\r
+ public int threshold;\r
+\r
+ \r
+ //参照\r
+ private INyARRgbRaster _ref_raster;\r
+ //所有インスタンス\r
+ private INyIdMarkerData _current_data;\r
+ private final NyIdMarkerPickup _id_pickup = new NyIdMarkerPickup();\r
+ private Coord2Linear _coordline;\r
+ private INyIdMarkerDataEncoder _encoder;\r
+\r
+ \r
+ private INyIdMarkerData _data_temp;\r
+ private INyIdMarkerData _prev_data;\r
+ \r
+ public DetectSquareCB(NyARParam i_param,INyIdMarkerDataEncoder i_encoder)\r
+ {\r
+ this._coordline=new Coord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());\r
+ this._data_temp=i_encoder.createDataInstance();\r
+ this._current_data=i_encoder.createDataInstance();\r
+ this._encoder=i_encoder;\r
+ return;\r
+ }\r
+ private NyARIntPoint2d[] __tmp_vertex=NyARIntPoint2d.createArray(4);\r
+ /**\r
+ * Initialize call back handler.\r
+ */\r
+ public void init(INyARRgbRaster i_raster,INyIdMarkerData i_prev_data)\r
+ {\r
+ this.marker_data=null;\r
+ this._prev_data=i_prev_data;\r
+ this._ref_raster=i_raster;\r
+ }\r
+ private final NyIdMarkerParam _marker_param=new NyIdMarkerParam();\r
+ private final NyIdMarkerPattern _marker_data=new NyIdMarkerPattern();\r
+\r
+ /**\r
+ * 矩形が見付かるたびに呼び出されます。\r
+ * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。\r
+ */\r
+ public void onSquareDetect(INyARSquareContourDetector i_sender,int[] i_coordx,int[] i_coordy,int i_coor_num,int[] i_vertex_index) throws NyARException\r
+ {\r
+ //既に発見済なら終了\r
+ if(this.marker_data!=null){\r
+ return;\r
+ }\r
+ //輪郭座標から頂点リストに変換\r
+ NyARIntPoint2d[] vertex=this.__tmp_vertex;\r
+ vertex[0].x=i_coordx[i_vertex_index[0]];\r
+ vertex[0].y=i_coordy[i_vertex_index[0]];\r
+ vertex[1].x=i_coordx[i_vertex_index[1]];\r
+ vertex[1].y=i_coordy[i_vertex_index[1]];\r
+ vertex[2].x=i_coordx[i_vertex_index[2]];\r
+ vertex[2].y=i_coordy[i_vertex_index[2]];\r
+ vertex[3].x=i_coordx[i_vertex_index[3]];\r
+ vertex[3].y=i_coordy[i_vertex_index[3]];\r
+ \r
+ NyIdMarkerParam param=this._marker_param;\r
+ NyIdMarkerPattern patt_data =this._marker_data; \r
+ // 評価基準になるパターンをイメージから切り出す\r
+ if (!this._id_pickup.pickFromRaster(this._ref_raster,vertex, patt_data, param)){\r
+ return;\r
+ }\r
+ //エンコード\r
+ if(!this._encoder.encode(patt_data,this._data_temp)){\r
+ return;\r
+ }\r
+\r
+ //継続認識要求されている?\r
+ if (this._prev_data==null){\r
+ //継続認識要求なし\r
+ this._current_data.copyFrom(this._data_temp);\r
+ }else{\r
+ //継続認識要求あり\r
+ if(!this._prev_data.isEqual((this._data_temp))){\r
+ return;//認識請求のあったIDと違う。\r
+ }\r
+ }\r
+ //新しく認識、または継続認識中に更新があったときだけ、Square情報を更新する。\r
+ //ココから先はこの条件でしか実行されない。\r
+ NyARSquare sq=this.square;\r
+ //directionを考慮して、squareを更新する。\r
+ for(int i=0;i<4;i++){\r
+ int idx=(i+4 - param.direction) % 4;\r
+ sq.imvertex[i].x=vertex[idx].x;\r
+ sq.imvertex[i].y=vertex[idx].y;\r
+ this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coordx,i_coordy,i_coor_num,sq.line[i]);\r
+ }\r
+ for (int i = 0; i < 4; i++) {\r
+ //直線同士の交点計算\r
+ if(!NyARLinear.crossPos(sq.line[i],sq.line[(i + 3) % 4],sq.sqvertex[i])){\r
+ throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK\r
+ }\r
+ }\r
+ this.threshold=param.threshold;\r
+ this.marker_data=this._current_data;//みつかった。\r
+ }\r
+ } \r
+ /**\r
* オーナーが自由に使えるタグ変数です。\r
*/\r
public Object tag;\r
private int _lost_delay_count = 0;\r
private int _lost_delay = 5;\r
\r
- private NyARSquareDetector_Rle _square_detect;\r
+ private NyARSquareContourDetector_Rle _square_detect;\r
protected INyARTransMat _transmat;\r
private double _marker_width=100;\r
-\r
- private NyARSquareStack _square_list = new NyARSquareStack(100);\r
- private INyIdMarkerDataEncoder _encoder;\r
private boolean _is_active;\r
- private INyIdMarkerData _data_temp;\r
- private INyIdMarkerData _data_current;\r
-\r
private int _current_threshold=110;\r
// [AR]検出結果の保存用\r
private NyARBinRaster _bin_raster;\r
-\r
private NyARRasterFilter_ARToolkitThreshold _tobin_filter;\r
-\r
- private NyIdMarkerPickup _id_pickup = new NyIdMarkerPickup();\r
+ private DetectSquareCB _callback;\r
+ private INyIdMarkerData _data_current;\r
\r
\r
protected SingleNyIdMarkerProcesser()\r
\r
NyARIntSize scr_size = i_param.getScreenSize();\r
// 解析オブジェクトを作る\r
- this._square_detect = new NyARSquareDetector_Rle(i_param.getDistortionFactor(), scr_size);\r
+ this._square_detect = new NyARSquareContourDetector_Rle(i_param.getDistortionFactor(), scr_size);\r
this._transmat = new NyARTransMat(i_param);\r
- this._encoder=i_encoder;\r
+ this._callback=new DetectSquareCB(i_param,i_encoder);\r
\r
// 2値画像バッファを作る\r
this._bin_raster = new NyARBinRaster(scr_size.w, scr_size.h);\r
//ワーク用のデータオブジェクトを2個作る\r
- this._is_active=false;\r
- this._data_temp=i_encoder.createDataInstance();\r
this._data_current=i_encoder.createDataInstance();\r
this._tobin_filter =new NyARRasterFilter_ARToolkitThreshold(110,i_raster_format);\r
this._threshold_detect=new NyARRasterThresholdAnalyzer_SlidePTile(15,i_raster_format,4);\r
this._initialized=true;\r
+ this._is_active=false;\r
return;\r
\r
}\r
\r
public void reset(boolean i_is_force)\r
{\r
- if (this._data_current!=null && i_is_force == false) {\r
+ if (i_is_force == false && this._is_active){\r
// 強制書き換えでなければイベントコール\r
this.onLeaveHandler();\r
}\r
- // カレントマーカをリセット\r
- this._data_current = null;\r
+ //マーカ無効\r
+ this._is_active=false;\r
return;\r
}\r
\r
this._tobin_filter.setThreshold(this._current_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._is_active) {\r
- // マーカ未認識→新規認識\r
- detectNewMarker(i_raster, square_stack);\r
- } else {\r
- // マーカ認識依頼→継続認識\r
- detectExistMarker(i_raster, square_stack);\r
- }\r
- return;\r
- }\r
-\r
- \r
- private final NyIdMarkerPattern _marker_data=new NyIdMarkerPattern();\r
- private final NyIdMarkerParam _marker_param=new NyIdMarkerParam();\r
- private NyARRasterThresholdAnalyzer_SlidePTile _threshold_detect;\r
- \r
- /**新規マーカ検索 現在認識中のマーカがないものとして、最も認識しやすいマーカを1個認識します。\r
- */\r
- private void detectNewMarker(INyARRgbRaster i_raster, NyARSquareStack i_stack) throws NyARException\r
- {\r
- NyIdMarkerParam param=this._marker_param;\r
- NyIdMarkerPattern patt_data =this._marker_data;\r
- int number_of_square = i_stack.getLength();\r
- NyARSquare current_square=null;\r
- INyIdMarkerData marker_id=null;\r
- for (int i = 0; i < number_of_square; i++) {\r
- // 評価基準になるパターンをイメージから切り出す\r
- current_square=i_stack.getItem(i);\r
- if (!this._id_pickup.pickFromRaster(i_raster,current_square, patt_data, param)) {\r
- continue;\r
- }\r
- //エンコード\r
- if(!this._encoder.encode(patt_data,this._data_temp)){\r
- continue;\r
- }\r
- //認識率が一番高いもの(占有面積が一番大きいもの)を選択する(省略)\r
- //id認識が成功したら終了\r
- marker_id=this._data_temp;\r
- break;\r
- }\r
- \r
- // 認識状態を更新\r
- final boolean is_id_found=updateStatus(current_square,marker_id, param);\r
-\r
- //閾値フィードバック(detectExistMarkerにもあるよ)\r
- if(is_id_found){\r
- //マーカがあれば、マーカの周辺閾値を反映\r
- this._current_threshold=(this._current_threshold+param.threshold)/2;\r
- }else{\r
- //マーカがなければ、探索+DualPTailで基準輝度検索\r
- int th=this._threshold_detect.analyzeRaster(i_raster);\r
- this._current_threshold=(this._current_threshold+th)/2;\r
- }\r
- return;\r
- }\r
+ // スクエアコードを探す(第二引数に指定したマーカ、もしくは新しいマーカを探す。)\r
+ this._callback.init(i_raster,this._is_active?this._data_current:null);\r
+ this._square_detect.detectMarkerCB(this._bin_raster, this._callback);\r
\r
- /**マーカの継続認識 現在認識中のマーカを優先して認識します。 \r
- * (注)この機能はたぶん今後いろいろ発展するからNewと混ぜないこと。\r
- */\r
- private void detectExistMarker(INyARRgbRaster i_raster, NyARSquareStack i_stack) throws NyARException\r
- {\r
- NyIdMarkerParam param=this._marker_param;\r
- NyIdMarkerPattern patt_data =this._marker_data;\r
- int number_of_square = i_stack.getLength();\r
- NyARSquare current_square=null;\r
- INyIdMarkerData marker_id=null;\r
- for (int i = 0; i < number_of_square; i++){\r
- //idマーカを認識\r
- current_square=i_stack.getItem(i);\r
- if (!this._id_pickup.pickFromRaster(i_raster, current_square, patt_data, param)) {\r
- continue;\r
- }\r
- if(!this._encoder.encode(patt_data,this._data_temp)){\r
- continue;\r
- }\r
- //現在認識中のidか確認\r
- if(!this._data_current.isEqual((this._data_temp))){\r
- continue;\r
- }\r
- //現在認識中のものであれば、終了\r
- marker_id=this._data_temp;\r
- break;\r
- }\r
- // 認識状態を更新\r
- final boolean is_id_found=updateStatus(current_square,marker_id,param);\r
+ // 認識状態を更新(マーカを発見したなら、current_dataを渡すかんじ)\r
+ final boolean is_id_found=updateStatus(this._callback.square,this._callback.marker_data);\r
\r
//閾値フィードバック(detectExistMarkerにもあるよ)\r
if(is_id_found){\r
//マーカがあれば、マーカの周辺閾値を反映\r
- this._current_threshold=(this._current_threshold+param.threshold)/2;\r
+ this._current_threshold=(this._current_threshold+this._callback.threshold)/2;\r
}else{\r
//マーカがなければ、探索+DualPTailで基準輝度検索\r
int th=this._threshold_detect.analyzeRaster(i_raster);\r
this._current_threshold=(this._current_threshold+th)/2;\r
- }\r
+ } \r
return;\r
}\r
\r
+ \r
+ private NyARRasterThresholdAnalyzer_SlidePTile _threshold_detect;\r
private NyARTransMatResult __NyARSquare_result = new NyARTransMatResult();\r
\r
/**オブジェクトのステータスを更新し、必要に応じてハンドル関数を駆動します。\r
*/\r
- private boolean updateStatus(NyARSquare i_square, INyIdMarkerData i_marker_data,NyIdMarkerParam i_param) throws NyARException\r
+ private boolean updateStatus(NyARSquare i_square, INyIdMarkerData i_marker_data) throws NyARException\r
{\r
boolean is_id_found=false;\r
NyARTransMatResult result = this.__NyARSquare_result;\r
// OnEnter\r
this.onEnterHandler(this._data_current);\r
// 変換行列を作成\r
- this._transmat.transMat(i_square,i_param.direction, this._marker_width, result);\r
+ this._transmat.transMat(i_square, this._marker_width, result);\r
// OnUpdate\r
this.onUpdateHandler(i_square, result);\r
this._lost_delay_count = 0;\r
}\r
} else if(this._data_current.isEqual(i_marker_data)) {\r
//同じidの再認識\r
- this._transmat.transMat(i_square, i_param.direction, this._marker_width, result);\r
+ this._transmat.transMat(i_square, this._marker_width, result);\r
// OnUpdate\r
this.onUpdateHandler(i_square, result);\r
this._lost_delay_count = 0;\r