/** * このターゲットについて、非同期に認識依頼を出します。このプログラムはサンプルなので、別スレッドでIDマーカ判定をして、 * 三秒後に適当なサイズとDirectionを返却するだけです。 * @param i_target * @return * @throws NyARException */ public void requestAsyncMarkerDetect(NyARReality i_reality, NyARRealitySource i_source, NyARRealityTarget i_target) { //ターゲットから画像データなどを取得するときは、スレッドからではなく、ここで同期して取得してコピーしてからスレッドに引き渡します。 //100x100の領域を切りだして、Rasterを作る。 NyARRgbRaster raster = new NyARRgbRaster(100, 100, NyARBufferType.INT1D_X8R8G8B8_32); i_reality.GetRgbPatt2d(i_source, i_target.refTargetVertex(), 1, raster); //コピーしたラスタとターゲットのIDをスレッドへ引き渡す。 Thread t = new Thread(new AsyncThread(this, i_target.getSerialId(), raster).Run); t.Start(); return; }
/** * i_targetの大きさを推定して、{@link UnknownRectInfo}に結果を保存します。この関数は{@link UnknownRectInfo}の状態を変化させるだけです。 * @param i_target * 大きさを推定するターゲット。 * @param io_result * 入出力パラメータ。前段までの推定結果と現在の推定値をマージして返します。 * はじめてターゲットの推定をするときは、リセットした{@link UnknownRectInfo}を入力してください。 * @return * 認識状況を返します。 * @throws NyARException */ public void detectCardDirection(NyARRealityTarget i_target, UnknownRectInfo io_result) { //成功点数が20点を超えたら推定完了。 if (io_result._success_point > 20) { io_result.last_status = ESTIMATE_COMPLETE; return; } //10回失敗したら推定失敗 if (io_result._failed > 10) { io_result.last_status = FAILED_ESTIMATE; return; } NyARDoublePoint2d[] pos = i_target.refTargetVertex(); //正面から一回認識させてほしい。 for (int i = 0; i < 4; i++) { //正面判定。辺のなす角が90、または-90度の10度以内であること。 if (getAbsSin(pos[0 + i], pos[(1 + i) % 4], pos[(2 + i) % 4]) < 0.984) { io_result.last_status = MORE_FRONT_CENTER; return; } } //線の長さを4本計算 double d1 = Math.Sqrt(pos[0].sqDist(pos[1])); double d2 = Math.Sqrt(pos[1].sqDist(pos[2])); double d3 = Math.Sqrt(pos[2].sqDist(pos[3])); double d4 = Math.Sqrt(pos[3].sqDist(pos[0])); //現在の比率を計算 double t, t2, t3; t = d1 + d3 * 0.5; t2 = d2 + d4 * 0.5; t3 = t / t2; t3 = t3 < 1 ? 1 / t3 : t3; if (io_result._target_serial == NyARRealityTarget.INVALID_REALITY_TARGET_ID) { //サイクルをリセット io_result._target_serial = i_target.getSerialId(); io_result.rate = t3; io_result._success_point = 0; io_result._failed = 0; io_result.artk_direction = t < t2 ? 1 : 0; } else { if (io_result._target_serial != i_target.getSerialId()) { //ターゲットが一致しない。 io_result.last_status = FAILED_TARGET_MISSMATCH; return; } if (t3 / io_result.rate > 0.98 && t3 / io_result.rate < 1.02) { io_result.rate = (io_result.rate + t3) * 0.5; io_result._success_point++; } else { io_result._failed++; } } //推定中 io_result.last_status = ESTIMATE_NOW; return; }