/// <summary> /// Initialize a new SquareDetectionListener. /// </summary> /// <param name="patternMatchers">The pattern matchers with the marker data.</param> /// <param name="cameraParameters">The camera calibration data.</param> /// <param name="colorPattern">The used color pattern.</param> /// <param name="patternMatchDeviationData">The pattern match deviation data.</param> public SquareDetectionListener(List <PatternMatcher> patternMatchers, NyARParam cameraParameters, INyARColorPatt colorPattern, NyARMatchPattDeviationColorData patternMatchDeviationData) { this.patternMatchers = patternMatchers; this.colorPattern = colorPattern; this.patternMatchDeviationData = patternMatchDeviationData; this.coordinationMapper = new Coord2Linear(cameraParameters.getScreenSize(), cameraParameters.getDistortionFactor()); this.matrixCalculator = new NyARTransMat(cameraParameters); this.points = NyARIntPoint2d.createArray(4); this.evaluationResult = new NyARMatchPattResult(); Reset(); }
/** * 内部関数です。 * この関数は、thisの二次元矩形情報プロパティを更新します。 * @param i_coord * @param i_vertex_index * @ */ protected internal void updateSquareInfo(NyARIntCoordinates i_coord, int[] i_vertex_index) { NyARMatchPattResult mr = this.__detectMarkerLite_mr; //輪郭座標から頂点リストに変換 NyARIntPoint2d[] vertex = this.__ref_vertex; //C言語ならポインタ扱いで実装 vertex[0] = i_coord.items[i_vertex_index[0]]; vertex[1] = i_coord.items[i_vertex_index[1]]; vertex[2] = i_coord.items[i_vertex_index[2]]; vertex[3] = i_coord.items[i_vertex_index[3]]; //画像を取得 if (!this._inst_patt.pickFromRaster(this._last_input_raster, vertex)) { return; } //取得パターンをカラー差分データに変換して評価する。 this._deviation_data.setRaster(this._inst_patt); if (!this._match_patt.evaluate(this._deviation_data, mr)) { return; } //現在の一致率より低ければ終了 if (this._confidence > mr.confidence) { return; } //一致率の高い矩形があれば、方位を考慮して頂点情報を作成 NyARSquare sq = this._square; this._confidence = mr.confidence; //directionを考慮して、squareを更新する。 for (int i = 0; i < 4; i++) { int idx = (i + 4 - mr.direction) % 4; this._coordline.coord2Line(i_vertex_index[idx], i_vertex_index[(idx + 1) % 4], i_coord, sq.line[i]); } //ちょっと、ひっくり返してみようか。 for (int i = 0; i < 4; i++) { //直線同士の交点計算 if (!sq.line[i].crossPos(sq.line[(i + 3) % 4], sq.sqvertex[i])) { throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK } } }
/** * 矩形が見付かるたびに呼び出されます。 * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。 */ public void onSquareDetect(NyARSquareContourDetector i_sender, int[] i_coordx, int[] i_coordy, int i_coor_num, int[] i_vertex_index) { NyARMatchPattResult mr = this.__detectMarkerLite_mr; //輪郭座標から頂点リストに変換 NyARIntPoint2d[] vertex = this.__tmp_vertex; vertex[0].x = i_coordx[i_vertex_index[0]]; vertex[0].y = i_coordy[i_vertex_index[0]]; vertex[1].x = i_coordx[i_vertex_index[1]]; vertex[1].y = i_coordy[i_vertex_index[1]]; vertex[2].x = i_coordx[i_vertex_index[2]]; vertex[2].y = i_coordy[i_vertex_index[2]]; vertex[3].x = i_coordx[i_vertex_index[3]]; vertex[3].y = i_coordy[i_vertex_index[3]]; //画像を取得 if (!this._inst_patt.pickFromRaster(this._ref_raster, vertex)) { return; } //取得パターンをカラー差分データに変換して評価する。 this._deviation_data.setRaster(this._inst_patt); if (!this._match_patt.evaluate(this._deviation_data, mr)) { return; } //現在の一致率より低ければ終了 if (this.confidence > mr.confidence) { return; } //一致率の高い矩形があれば、方位を考慮して頂点情報を作成 NyARSquare sq = this.square; this.confidence = mr.confidence; //directionを考慮して、squareを更新する。 for (int i = 0; i < 4; i++) { int idx = (i + 4 - mr.direction) % 4; this._coordline.coord2Line(i_vertex_index[idx], i_vertex_index[(idx + 1) % 4], i_coordx, i_coordy, i_coor_num, sq.line[i]); } for (int i = 0; i < 4; i++) { //直線同士の交点計算 if (!NyARLinear.crossPos(sq.line[i], sq.line[(i + 3) % 4], sq.sqvertex[i])) { throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK } } }
/** * RealityTargetに最も一致するパターンをテーブルから検索して、メタデータを返します。 * @param i_target * Realityが検出したターゲット。 * Unknownターゲットを指定すること。 * @param i_rtsorce * i_targetを検出したRealitySourceインスタンス。 * @param o_result * 返却値を格納するインスタンスを設定します。 * 返却値がtrueの場合のみ、内容が更新されています。 * @return * 特定に成功すると、trueを返します。 * @throws NyARException */ public bool getBestMatchTarget(NyARRealityTarget i_target, NyARRealitySource i_rtsorce, GetBestMatchTargetResult o_result) { //パターン抽出 NyARMatchPattResult tmp_patt_result = this.__tmp_patt_result; INyARPerspectiveCopy r = i_rtsorce.refPerspectiveRasterReader(); r.copyPatt(i_target.refTargetVertex(), this._edge_x, this._edge_y, this._sample_per_pix, this._tmp_raster); //比較パターン生成 this._deviation_data.setRaster(this._tmp_raster); int ret = -1; int dir = -1; double cf = Double.MinValue; for (int i = this._table.getLength() - 1; i >= 0; i--) { this._match_patt.setARCode(this._table.getItem(i).code); this._match_patt.evaluate(this._deviation_data, tmp_patt_result); if (cf < tmp_patt_result.confidence) { ret = i; cf = tmp_patt_result.confidence; dir = tmp_patt_result.direction; } } if (ret < 0) { return(false); } //戻り値を設定 MarkerTable.SerialTableRow row = this._table.getItem(ret); o_result.artk_direction = dir; o_result.confidence = cf; o_result.idtag = row.idtag; o_result.marker_height = row.marker_height; o_result.marker_width = row.marker_width; o_result.name = row.name; return(true); }
/** * 矩形が見付かるたびに呼び出されます。 * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。 */ public void detectMarkerCallback(NyARIntCoordinates i_coord, int[] i_vertex_index) { NyARMatchPattResult mr = this.__detectMarkerLite_mr; //輪郭座標から頂点リストに変換 NyARIntPoint2d[] vertex = this.__ref_vertex; vertex[0] = i_coord.items[i_vertex_index[0]]; vertex[1] = i_coord.items[i_vertex_index[1]]; vertex[2] = i_coord.items[i_vertex_index[2]]; vertex[3] = i_coord.items[i_vertex_index[3]]; //画像を取得 if (!this._inst_patt.pickFromRaster(this._ref_raster, vertex)) { return; } //取得パターンをカラー差分データに変換して評価する。 this._deviation_data.setRaster(this._inst_patt); //最も一致するパターンを割り当てる。 int square_index, direction; double confidence; this._match_patt[0].evaluate(this._deviation_data, mr); square_index = 0; direction = mr.direction; confidence = mr.confidence; //2番目以降 for (int i = 1; i < this._match_patt.Length; i++) { this._match_patt[i].evaluate(this._deviation_data, mr); if (confidence > mr.confidence) { continue; } // もっと一致するマーカーがあったぽい square_index = i; direction = mr.direction; confidence = mr.confidence; } //最も一致したマーカ情報を、この矩形の情報として記録する。 NyARDetectMarkerResult result = this.result_stack.prePush(); result.arcode_id = square_index; result.confidence = confidence; NyARSquare sq = result.square; //directionを考慮して、squareを更新する。 for (int i = 0; i < 4; i++) { int idx = (i + 4 - direction) % 4; this._coordline.coord2Line(i_vertex_index[idx], i_vertex_index[(idx + 1) % 4], i_coord, sq.line[i]); } for (int i = 0; i < 4; i++) { //直線同士の交点計算 if (!sq.line[i].crossPos(sq.line[(i + 3) % 4], sq.sqvertex[i])) { throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK } } }
/** * 矩形が見付かるたびに呼び出されます。 * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。 */ public void detectMarkerCallback(NyARIntCoordinates i_coord, int[] i_vertex_index) { if (this._match_patt == null) { return; } //輪郭座標から頂点リストに変換 NyARIntPoint2d[] vertex = this.__ref_vertex; vertex[0] = i_coord.items[i_vertex_index[0]]; vertex[1] = i_coord.items[i_vertex_index[1]]; vertex[2] = i_coord.items[i_vertex_index[2]]; vertex[3] = i_coord.items[i_vertex_index[3]]; //画像を取得 if (!this._inst_patt.pickFromRaster(this._ref_raster, vertex)) { return; } //取得失敗 //取得パターンをカラー差分データに変換して評価する。 this._deviation_data.setRaster(this._inst_patt); //code_index,dir,c1にデータを得る。 NyARMatchPattResult mr = this.__detectMarkerLite_mr; int lcode_index = 0; int dir = 0; double c1 = 0; for (int i = 0; i < this._match_patt.Length; i++) { this._match_patt[i].evaluate(this._deviation_data, mr); double c2 = mr.confidence; if (c1 < c2) { lcode_index = i; c1 = c2; dir = mr.direction; } } //認識処理 if (this._target_id == -1) // マーカ未認識 { if (c1 < this.cf_threshold_new) { return; } // 現在は未認識 if (this.confidence > c1) { return; } // 一致度が低い。 //認識しているマーカIDを保存 this.code_index = lcode_index; } else { //現在はマーカ認識中 // 現在のマーカを認識したか? if (lcode_index != this._target_id) { // 認識中のマーカではないので無視 return; } //認識中の閾値より大きいか? if (c1 < this.cf_threshold_exist) { return; } //現在の候補よりも一致度は大きいか? if (this.confidence > c1) { return; } this.code_index = this._target_id; } //新しく認識、または継続認識中に更新があったときだけ、Square情報を更新する。 //ココから先はこの条件でしか実行されない。 //一致率の高い矩形があれば、方位を考慮して頂点情報を作成 this.confidence = c1; NyARSquare sq = this.square; //directionを考慮して、squareを更新する。 for (int i = 0; i < 4; i++) { int idx = (i + 4 - dir) % 4; this._coordline.coord2Line(i_vertex_index[idx], i_vertex_index[(idx + 1) % 4], i_coord, sq.line[i]); } for (int i = 0; i < 4; i++) { //直線同士の交点計算 if (!sq.line[i].crossPos(sq.line[(i + 3) % 4], sq.sqvertex[i])) { throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK } } }