// 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
int number_of_coord = (this._width + this._height) * 2;\r
\r
- // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\r
+ // 輪郭バッファ\r
this._max_coord = number_of_coord;\r
- this._xcoord = new int[number_of_coord * 2];\r
- this._ycoord = new int[number_of_coord * 2];\r
+ this._xcoord = new int[number_of_coord];\r
+ this._ycoord = new int[number_of_coord];\r
return;\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
+ int[] xcoord = this._xcoord;\r
+ int[] ycoord = this._ycoord;\r
final int coord_max = this._max_coord;\r
\r
\r
\r
for (int i=0; i < label_num; i++) {\r
final RleLabelFragmentInfoStack.RleLabelFragmentInfo label_pt=labels[i];\r
- final int label_area = label_pt.area;\r
+ int label_area = label_pt.area;\r
\r
// クリップ領域が画面の枠に接していれば除外\r
if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){\r
// 重なっているようだ。\r
continue;\r
}\r
- \r
+\r
// 輪郭を取得\r
- final int coord_num = _cpickup.getContour(i_raster,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);\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
- final int vertex1 = SquareContourDetector.normalizeCoord(xcoord, ycoord, coord_num);\r
+ \r
+ NyARSquare square_ptr = o_square_stack.prePush();\r
\r
//ここから先が輪郭分析\r
- NyARSquare square_ptr = o_square_stack.prePush();\r
- if(!this._sqconvertor.coordToSquare(xcoord,ycoord,vertex1,coord_num,label_area,square_ptr)){\r
+ if(!this._sqconvertor.coordToSquare(xcoord,ycoord,coord_num,label_area,square_ptr)){\r
o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
continue; \r
}\r
+ \r
+ \r
// 検出済の矩形の属したラベルを重なりチェックに追加する。\r
overlap.push(label_pt);\r
}\r
\r
private int[] y_coord;\r
\r
- public boolean getVertex(int[] i_x_coord, int[] i_y_coord, int st, int ed, double i_thresh)\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);\r
+ return get_vertex(st, ed,i_coord_len);\r
}\r
\r
/**\r
* @param thresh\r
* @return\r
*/\r
- private boolean get_vertex(int st, int ed)\r
+ private boolean get_vertex(int st, int ed,int i_coord_len)\r
{\r
//メモ:座標値は65536を超えなければint32で扱って大丈夫なので変更。\r
//dmaxは4乗なのでやるとしてもint64じゃないとマズイ\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
- 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
+ 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)) {\r
+ if (!get_vertex(st, v1,i_coord_len)) {\r
return false;\r
}\r
if (number_of_vertex > 5) {\r
vertex[number_of_vertex] = v1;// vertex[(*vnum)] = v1;\r
number_of_vertex++;// (*vnum)++;\r
\r
- if (!get_vertex(v1, ed)) {\r
+ if (!get_vertex(v1, ed,i_coord_len)) {\r
return false;\r
}\r
}\r
return;\r
}\r
\r
- public boolean coordToSquare(int[] i_xcoord,int[] i_ycoord,int i_st_index,int i_coord_num,int i_label_area,NyARSquare o_square) throws NyARException\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
+ int vertex_1=getFarPoint(i_xcoord,i_ycoord,i_coord_num,0);\r
// 頂点情報を取得\r
- if (!getSquareVertex(i_xcoord, i_ycoord, i_st_index, i_coord_num, i_label_area, mkvertex)) {\r
+ if (!getSquareVertex(i_xcoord, i_ycoord, vertex_1, i_coord_num-1, i_label_area, mkvertex)) {\r
// 頂点の取得が出来なかったので破棄\r
return false;\r
}\r
// マーカーを検出\r
- if (!getSquareLine(mkvertex, i_xcoord, i_ycoord, o_square)){\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, NyARSquare o_square) throws NyARException\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
- \r
- for (int i = 0; i < 4; i++) {\r
- final double w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;\r
- final int st = (int) (i_mkvertex[i] + w1);\r
- final int ed = (int) (i_mkvertex[i + 1] - w1);\r
- final int n = ed - st + 1;\r
+ double w1; \r
+ for (int i = 0; i < 4; i++){\r
+ int n,st,ed;\r
+ //探索区間の決定\r
+ if(i_mkvertex[i + 1]>=i_mkvertex[i]){\r
+ //頂点[i]から頂点[i+1]までの輪郭が、1区間にあるとき\r
+ w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;\r
+ //探索区間の決定\r
+ st = (int) (i_mkvertex[i]+w1);\r
+ ed = (int) (i_mkvertex[i+1] - w1);\r
+ }else{\r
+ //頂点[i]から頂点[i+1]までの輪郭が、2区間に分かれているとき\r
+ w1 = (double) (i_mkvertex[i + 1]+i_cood_num-i_mkvertex[i]+1)%i_cood_num * 0.05 + 0.5;\r
+ //探索区間の決定\r
+ st = (int) (i_mkvertex[i]+w1)%i_cood_num;\r
+ ed = (int) (i_mkvertex[i+1]+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._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st, n,this._xpos,this._ypos);\r
- \r
//主成分分析する。\r
this._pca.pca(this._xpos,this._ypos,n,evec, ev,mean);\r
final NyARLinear l_line_i = l_line[i];\r
for (int i = 0; i < 4; i++) {\r
final NyARLinear l_line_i = l_line[i];\r
final NyARLinear l_line_2 = l_line[(i + 3) % 4];\r
- final double w1 = l_line_2.dy * l_line_i.dx - l_line_i.dy * l_line_2.dx;\r
+ w1 = l_line_2.dy * l_line_i.dx - l_line_i.dy * l_line_2.dx;\r
if (w1 == 0.0) {\r
return false;\r
}\r
}\r
return true;\r
} \r
+ \r
+\r
private boolean getSquareVertex(int[] i_x_coord, int[] i_y_coord, int i_vertex1_index, int i_coord_num, int i_area, int[] o_vertex)\r
{\r
final NyARVertexCounter wv1 = this.__getSquareVertex_wv1;\r
final NyARVertexCounter wv2 = this.__getSquareVertex_wv2;\r
- final int end_of_coord = i_vertex1_index + i_coord_num - 1;\r
- final int sx = i_x_coord[i_vertex1_index];// sx = marker_info2->x_coord[0];\r
- final int sy = i_y_coord[i_vertex1_index];// sy = marker_info2->y_coord[0];\r
- int dmax = 0;\r
- int v1 = i_vertex1_index;\r
- for (int i = 1 + i_vertex1_index; i < end_of_coord; i++) {// for(i=1;i<marker_info2->coord_num-1;i++)\r
- // {\r
- final int d = (i_x_coord[i] - sx) * (i_x_coord[i] - sx) + (i_y_coord[i] - sy) * (i_y_coord[i] - sy);\r
- if (d > dmax) {\r
- dmax = d;\r
- v1 = i;\r
- }\r
- }\r
+ int prev_vertex_index=(i_vertex1_index+i_coord_num)%i_coord_num;\r
+ int v1=getFarPoint(i_x_coord,i_y_coord,i_coord_num,i_vertex1_index);\r
final double thresh = (i_area / 0.75) * 0.01 * VERTEX_FACTOR;\r
\r
o_vertex[0] = i_vertex1_index;\r
\r
- if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v1, thresh)) { // if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,0,v1,thresh,wv1,&wvnum1)<\r
- // 0 ) {\r
+ if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, i_vertex1_index, v1, thresh)) {\r
return false;\r
}\r
- if (!wv2.getVertex(i_x_coord, i_y_coord, v1, end_of_coord, thresh)) {// if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,v1,marker_info2->coord_num-1,thresh,wv2,&wvnum2)\r
- // < 0) {\r
+ if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v1,prev_vertex_index, thresh)) {\r
return false;\r
}\r
\r
o_vertex[3] = wv2.vertex[0];\r
} else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {// }else if( wvnum1 > 1 && wvnum2== 0) {\r
//頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。\r
- v2 = (v1-i_vertex1_index)/2+i_vertex1_index;\r
- if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v2, thresh)) {\r
+ if(v1>=i_vertex1_index){\r
+ v2 = (v1-i_vertex1_index)/2+i_vertex1_index;\r
+ }else{\r
+ v2 = ((v1+i_coord_num-i_vertex1_index)/2+i_vertex1_index)%i_coord_num;\r
+ }\r
+ if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, i_vertex1_index, v2, thresh)) {\r
return false;\r
}\r
- if (!wv2.getVertex(i_x_coord, i_y_coord, v2, v1, thresh)) {\r
+ if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v2, v1, thresh)) {\r
return false;\r
}\r
if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {\r
return false;\r
}\r
} else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) {\r
- //v2 = (v1-i_vertex1_index+ end_of_coord-i_vertex1_index) / 2+i_vertex1_index;\r
- v2 = (v1+ end_of_coord)/2;\r
-\r
- if (!wv1.getVertex(i_x_coord, i_y_coord, v1, v2, thresh)) {\r
+ //v2 = (v1+ end_of_coord)/2;\r
+ if(v1<=prev_vertex_index){\r
+ v2 = (v1+prev_vertex_index)/2;\r
+ }else{\r
+ v2 = ((v1+i_coord_num+prev_vertex_index)/2)%i_coord_num;\r
+ \r
+ }\r
+ if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, v1, v2, thresh)) {\r
return false;\r
}\r
- if (!wv2.getVertex(i_x_coord, i_y_coord, v2, end_of_coord, thresh)) {\r
+ if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v2, prev_vertex_index, thresh)) {\r
return false;\r
}\r
if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {\r
o_vertex[2] = wv1.vertex[0];\r
o_vertex[3] = wv2.vertex[0];\r
} else {\r
+ \r
return false;\r
}\r
} else {\r
return false;\r
}\r
- o_vertex[4] = end_of_coord;\r
+ o_vertex[4] = prev_vertex_index;\r
return true;\r
}\r
- \r
+\r
/**\r
- * 輪郭線の矩形検出開始ポイントを特定して、座標を並べ替えます。\r
- * 輪郭線の先頭から、対角線が最長になる点を1点検索し、それより前の区間をバッファの後方に接続します。\r
- * 戻り値は対角線が最長になった点です。関数終了後、返却値+i_coord_numの要素が有効になります。\r
+ * i_pointの輪郭座標から、最も遠方にある輪郭座標のインデクスを探します。\r
* @param i_xcoord\r
* @param i_ycoord\r
* @param i_coord_num\r
* @return\r
*/\r
- public static int normalizeCoord(int[] i_coord_x, int[] i_coord_y,int i_coord_num)\r
+ private static int getFarPoint(int[] i_coord_x, int[] i_coord_y,int i_coord_num,int i_point)\r
{\r
//\r
- final int sx = i_coord_x[0];\r
- final int sy = i_coord_y[0];\r
+ final int sx = i_coord_x[i_point];\r
+ final int sy = i_coord_y[i_point];\r
int d = 0;\r
int w, x, y;\r
int ret = 0;\r
- for (int i = 1; i < i_coord_num; i++) {\r
+ for (int i = i_point+1; i < i_coord_num; i++) {\r
+ x = i_coord_x[i] - sx;\r
+ y = i_coord_y[i] - sy;\r
+ w = x * x + y * y;\r
+ if (w > d) {\r
+ d = w;\r
+ ret = i;\r
+ }\r
+ }\r
+ for (int i = 0; i < i_point; i++) {\r
x = i_coord_x[i] - sx;\r
y = i_coord_y[i] - sy;\r
w = x * x + y * y;\r
d = w;\r
ret = i;\r
}\r
- // ここでうまく終了条件入れられないかな。\r
} \r
- // vertex1を境界にして、後方に配列を連結\r
- System.arraycopy(i_coord_x, 1, i_coord_x, i_coord_num, ret);\r
- System.arraycopy(i_coord_y, 1, i_coord_y, i_coord_num, ret);\r
return ret;\r
} \r
- \r
}
\ No newline at end of file