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 static final double VERTEX_FACTOR = 1.0;// 線検出のファクタ \r
private final double[] _xpos;\r
private final double[] _ypos; \r
- private final int[] __detectMarker_mkvertex = new int[5];\r
- private final NyARVertexCounter __getSquareVertex_wv1 = new NyARVertexCounter();\r
- private final NyARVertexCounter __getSquareVertex_wv2 = new NyARVertexCounter();\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
this._dist_factor = new NyARObserv2IdealMap(i_distfactor_ref,i_size);\r
\r
\r
- // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\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
{\r
\r
final int[] mkvertex = this.__detectMarker_mkvertex;\r
- int vertex_1=getFarPoint(i_xcoord,i_ycoord,i_coord_num,0);\r
// 頂点情報を取得\r
- if (!getSquareVertex(i_xcoord, i_ycoord, vertex_1, i_coord_num-1, i_label_area, mkvertex)) {\r
+ if (!this._coord2vertex.getVertexIndexes(i_xcoord, i_ycoord, i_coord_num, i_label_area, mkvertex)) {\r
// 頂点の取得が出来なかったので破棄\r
return false;\r
}\r
final double[] mean=this.__getSquareLine_mean;\r
final double[] ev=this.__getSquareLine_ev;\r
\r
- double w1; \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(i_mkvertex[i + 1]>=i_mkvertex[i]){\r
+ if(ver2>=i_mkvertex[i]){\r
//頂点[i]から頂点[i+1]までの輪郭が、1区間にあるとき\r
- w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;\r
+ w1 = (double) (ver2 - ver1 + 1) * 0.05 + 0.5;\r
//探索区間の決定\r
- st = (int) (i_mkvertex[i]+w1);\r
- ed = (int) (i_mkvertex[i+1] - w1);\r
+ st = (int) (ver1+w1);\r
+ ed = (int) (ver2 - 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
+ w1 = (double) (ver2+i_cood_num-ver1+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
+ 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
final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;\r
final NyARIntPoint2d[] l_imvertex = o_square.imvertex;\r
for (int i = 0; i < 4; i++) {\r
- final NyARLinear l_line_i = l_line[i];\r
- final NyARLinear l_line_2 = l_line[(i + 3) % 4];\r
- w1 = l_line_2.dy * l_line_i.dx - l_line_i.dy * l_line_2.dx;\r
- if (w1 == 0.0) {\r
+ //直線同士の交点計算\r
+ if(!NyARLinear.crossPos(l_line[i],l_line[(i + 3) % 4],l_sqvertex[i])){\r
return false;\r
}\r
- l_sqvertex[i].x = (l_line_2.dx * l_line_i.c - l_line_i.dx * l_line_2.c) / w1;\r
- l_sqvertex[i].y = (l_line_i.dy * l_line_2.c - l_line_2.dy * l_line_i.c) / w1;\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
- \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
- 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_coord_num, i_vertex1_index, v1, thresh)) {\r
- return false;\r
- }\r
- if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v1,prev_vertex_index, thresh)) {\r
- return false;\r
- }\r
-\r
- int v2;\r
- if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {// if(wvnum1 == 1 && wvnum2== 1) {\r
- o_vertex[1] = wv1.vertex[0];\r
- o_vertex[2] = v1;\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
- 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,i_coord_num, v2, v1, thresh)) {\r
- return false;\r
- }\r
- if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {\r
- o_vertex[1] = wv1.vertex[0];\r
- o_vertex[2] = wv2.vertex[0];\r
- o_vertex[3] = v1;\r
- } else {\r
- return false;\r
- }\r
- } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) {\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,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[1] = v1;\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] = prev_vertex_index;\r
- return true;\r
- }\r
-\r
- /**\r
- * i_pointの輪郭座標から、最も遠方にある輪郭座標のインデクスを探します。\r
- * @param i_xcoord\r
- * @param i_ycoord\r
- * @param i_coord_num\r
- * @return\r
- */\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[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 = 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
- if (w > d) {\r
- d = w;\r
- ret = i;\r
- }\r
- } \r
- return ret;\r
- } \r
}
\ No newline at end of file