/** * 2回目以降の履歴を使ったデータチェック。 * 条件は、 * 1.一番長い辺と短い辺の比は、0.1~10の範囲か? * 2.位置倍長い辺、短い辺が短すぎないか? * 3.移動距離が極端に大きなものは無いか?(他の物の3倍動いてたらおかしい) * * @param i_sample_area */ private bool checkDeilyRectCondition(NyARRectTargetStatus i_prev_st) { NyARDoublePoint2d[] this_vx = this.vertex; //一番長い辺と短い辺の比を確認(10倍の比があったらなんか変) int max = int.MinValue; int min = int.MaxValue; for (int i = 0; i < 4; i++) { int t = (int)this_vx[i].sqDist(this_vx[(i + 1) % 4]); if (t > max) { max = t; } if (t < min) { min = t; } } //比率係数の確認 if (max < (5 * 5) || min < (5 * 5)) { return(false); } //10倍スケールの2乗 if ((10 * 10) * min / max < (3 * 3)) { return(false); } //移動距離平均より大きく剥離した点が無いか確認 return(this._ref_my_pool.checkLargeDiff(this_vx, i_prev_st.vertex)); }
/** * 予想位置を基準に四角形をトレースして、一定の基準をクリアするかを評価します。 * @param i_reader * @param i_edge_size * @param i_prevsq * @return * @throws NyARException */ private bool traceSquareLine(INyARVectorReader i_reader, int i_edge_size, NyARRectTargetStatus i_prevsq, NyARLinear[] o_line) { NyARDoublePoint2d p1, p2; VecLinearCoordinates vecpos = this._ref_my_pool._vecpos; //NyARIntRect i_rect p1 = i_prevsq.estimate_vertex[0]; int dist_limit = i_edge_size * i_edge_size; //強度敷居値(セルサイズ-1) // int min_th=i_edge_size*2+1; // min_th=(min_th*min_th); for (int i = 0; i < 4; i++) { p2 = i_prevsq.estimate_vertex[(i + 1) % 4]; //クリップ付きで予想位置周辺の直線のトレース i_reader.traceLineWithClip(p1, p2, i_edge_size, vecpos); //クラスタリングして、傾きの近いベクトルを探す。(限界は10度) this._ref_my_pool._vecpos_op.margeResembleCoords(vecpos); //基本的には1番でかいベクトルだよね。だって、直線状に取るんだもの。 int vid = vecpos.getMaxCoordIndex(); //データ品質規制(強度が多少強くないと。) // if(vecpos.items[vid].sq_dist<(min_th)){ // return false; // } //@todo:パラメタ調整 //角度規制(元の線分との角度を確認) if (vecpos.items[vid].getAbsVecCos(i_prevsq.vertex[i], i_prevsq.vertex[(i + 1) % 4]) < NyARMath.COS_DEG_5) { //System.out.println("CODE1"); return(false); } //@todo:パラメタ調整 //予想点からさほど外れていない点であるか。(検出点の移動距離を計算する。) double dist; dist = vecpos.items[vid].sqDistBySegmentLineEdge(i_prevsq.vertex[i], i_prevsq.vertex[i]); if (dist < dist_limit) { o_line[i].setVectorWithNormalize(vecpos.items[vid]); } else { //System.out.println("CODE2:"+dist+","+dist_limit); return(false); } //頂点ポインタの移動 p1 = p2; } return(true); }
/** * 輪郭からの単独検出 * @param i_raster * @param i_prev_status * @return * @throws NyARException */ public bool setValueByLineLog(INyARVectorReader i_vec_reader, NyARRectTargetStatus i_prev_status) { //検出範囲からカーネルサイズの2乗値を計算。検出領域の二乗距離の1/(40*40) (元距離の1/40) int d = ((int)i_prev_status.estimate_rect.getDiagonalSqDist() / (NyARMath.SQ_40)); //二乗移動速度からカーネルサイズを計算。 int v_ave_limit = i_prev_status.estimate_sum_sq_vertex_velocity_ave; // if (v_ave_limit > d) { //移動カーネルサイズより、検出範囲カーネルのほうが大きかったらエラー(動きすぎ) return(false); } d = (int)Math.Sqrt(d); //最低でも2だよね。 if (d < 2) { d = 2; } //最大カーネルサイズ(5)を超える場合は5にする。 if (d > 5) { d = 5; } //ライントレースの試行 NyARLinear[] sh_l = this._ref_my_pool._line; if (!traceSquareLine(i_vec_reader, d, i_prev_status, sh_l)) { return(false); } else { } //4点抽出 for (int i = 3; i >= 0; i--) { if (!sh_l[i].crossPos(sh_l[(i + 3) % 4], this.vertex[i])) { //四角が作れない。 return(false); } } //頂点並び順の調整 rotateVertexL(this.vertex, checkVertexShiftValue(i_prev_status.vertex, this.vertex)); //差分パラメータのセット setEstimateParam(i_prev_status); return(true); }
/** * 前回のステータスと予想パラメータを計算してセットします。 * @param i_prev_param */ private void setEstimateParam(NyARRectTargetStatus i_prev_param) { NyARDoublePoint2d[] vc_ptr = this.vertex; NyARDoublePoint2d[] ve_ptr = this.estimate_vertex; int sum_of_vertex_sq_dist = 0; if (i_prev_param != null) { //差分パラメータをセット NyARDoublePoint2d[] vp = i_prev_param.vertex; //頂点速度の計測 for (int i = 3; i >= 0; i--) { int x = (int)((vc_ptr[i].x - vp[i].x)); int y = (int)((vc_ptr[i].y - vp[i].y)); //予想位置 ve_ptr[i].x = (int)vc_ptr[i].x + x; ve_ptr[i].y = (int)vc_ptr[i].y + y; sum_of_vertex_sq_dist += x * x + y * y; } } else { //頂点速度のリセット for (int i = 3; i >= 0; i--) { ve_ptr[i].x = (int)vc_ptr[i].x; ve_ptr[i].y = (int)vc_ptr[i].y; } } //頂点予測と範囲予測 this.estimate_sum_sq_vertex_velocity_ave = sum_of_vertex_sq_dist / 4; this.estimate_rect.setAreaRect(ve_ptr, 4); // this.estimate_rect.clip(i_left, i_top, i_right, i_bottom); return; }
/** * 状況に応じて矩形選択手法を切り替えます。 * @param i_vec_reader * サンプリングデータの基本画像にリンクしたVectorReader * @param i_source * サンプリングデータ * @param i_prev_status * 前回の状態を格納したオブジェクト * @return * @throws NyARException */ public bool setValueByAutoSelect(INyARVectorReader i_vec_reader, LowResolutionLabelingSamplerOut.Item i_source, NyARRectTargetStatus i_prev_status) { int current_detect_type = DT_SQDAILY; //移動速度による手段の切り替え int sq_v_ave_limit = i_prev_status.estimate_sum_sq_vertex_velocity_ave / 4; //速度が小さい時か、前回LineLogが成功したときはDT_LIDAILY if (((sq_v_ave_limit < 10) && (i_prev_status.detect_type == DT_SQDAILY)) || (i_prev_status.detect_type == DT_LIDAILY)) { current_detect_type = DT_LIDAILY; } //前回の動作ログによる手段の切り替え switch (current_detect_type) { case DT_LIDAILY: //LineLog-> if (setValueByLineLog(i_vec_reader, i_prev_status)) { //うまくいった。 this.detect_type = DT_LIDAILY; return(true); } if (i_source != null) { if (setValueWithDeilyCheck(i_vec_reader, i_source, i_prev_status)) { //うまくいった this.detect_type = DT_SQDAILY; return(true); } } break; case DT_SQDAILY: if (i_source != null) { if (setValueWithDeilyCheck(i_vec_reader, i_source, i_prev_status)) { this.detect_type = DT_SQDAILY; return(true); } } break; default: break; } //前回の動作ログを書き換え i_prev_status.detect_type = DT_FAILED; return(false); }
/** * 値をセットします。この関数は、処理の成功失敗に関わらず、内容変更を行います。 * @param i_sampler_in * @param i_source * @param i_prev_status * @return * @throws NyARException */ public bool setValueWithDeilyCheck(INyARVectorReader i_vec_reader, LowResolutionLabelingSamplerOut.Item i_source, NyARRectTargetStatus i_prev_status) { VecLinearCoordinates vecpos = this._ref_my_pool._vecpos; //輪郭線を取る if (!i_vec_reader.traceConture(i_source.lebeling_th, i_source.entry_pos, vecpos)) { return(false); } //3,4象限方向のベクトルは1,2象限のベクトルに変換する。 vecpos.limitQuadrantTo12(); //ベクトルのマージ this._ref_my_pool._vecpos_op.margeResembleCoords(vecpos); if (vecpos.length < 4) { return(false); } //キーベクトルを取得 vecpos.getKeyCoord(this._ref_my_pool._indexbuf); //点に変換 NyARDoublePoint2d[] this_vx = this.vertex; if (!this._ref_my_pool._line_detect.line2SquareVertex(this._ref_my_pool._indexbuf, this_vx)) { return(false); } //頂点並び順の調整 rotateVertexL(this.vertex, checkVertexShiftValue(i_prev_status.vertex, this.vertex)); //パラメタチェック if (!checkDeilyRectCondition(i_prev_status)) { return(false); } //次回の予測 setEstimateParam(i_prev_status); return(true); }