Ejemplo n.º 1
0
 /**
  * RealityTargetに一致するID値を特定します。
  * 複数のパターンにヒットしたときは、一番初めにヒットした項目を返します。
  * @param i_target
  * Realityが検出したターゲット。
  * Unknownターゲットを指定すること。
  * @param i_rtsorce
  * i_targetを検出したRealitySourceインスタンス。
  * @param o_result
  * 返却値を格納するインスタンスを設定します。
  * 返却値がtrueの場合のみ、内容が更新されています。
  * @return
  * 特定に成功すると、trueを返します。
  * @throws NyARException
  */
 public bool identifyId(NyARRealityTarget i_target, NyARRealitySource i_rtsorce, IdentifyIdResult o_result)
 {
     //NyARDoublePoint2d[] i_vertex,NyARRgbRaster i_raster,SelectResult o_result
     return(this.identifyId(
                ((NyARRectTargetStatus)(i_target._ref_tracktarget._ref_status)).vertex,
                i_rtsorce.refRgbSource(),
                o_result));
 }
        //メインループ処理
        public void MainLoop()
        {
            //RealitySourceにデータが処理する。
            if (!this._reality_source.isReady())
            {
                return;
            }

            // 背景を書く
            try{
                lock (this){
                    // 背景サーフェイスを直接描画
                    Surface   dest_surface  = this._device.GetBackBuffer(0, 0, BackBufferType.Mono);
                    Rectangle src_dest_rect = new Rectangle(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
                    this._device.StretchRectangle((Surface)this._surface, src_dest_rect, dest_surface, src_dest_rect, TextureFilter.None);

                    // 3Dオブジェクトの描画はここから
                    this._device.BeginScene();
                    this._device.Clear(ClearFlags.ZBuffer, Color.DarkBlue, 1.0f, 0);

                    //ターゲットリストを走査して、画面に内容を反映
                    NyARRealityTargetList tl = this._reality.refTargetList();
                    for (int i = tl.getLength() - 1; i >= 0; i--)
                    {
                        NyARRealityTarget t = tl.getItem(i);
                        switch (t.getTargetType())
                        {
                        case NyARRealityTarget.RT_KNOWN:
                            //立方体を20mm上(マーカーの上)にずらしておく
                            Matrix mat = new Matrix();
                            this._reality.getD3dModelViewMatrix(t.refTransformMatrix(), ref mat);
                            Matrix transform_mat2 = Matrix.Translation(0, 0, 20.0f);
                            transform_mat2 = transform_mat2 * mat;
                            this._device.SetTransform(TransformType.World, transform_mat2);
                            this._cube.draw(this._device);
                            break;

                        case NyARRealityTarget.RT_UNKNOWN:
                            //
                            break;
                        }
                    }
                    // 描画はここまで
                    this._device.EndScene();

                    // 実際のディスプレイに描画
                    this._device.Present();
                }
                Thread.Sleep(1);            // タスク実行権限を一旦渡す
            }catch (Exception e) {
                System.Console.WriteLine(e.StackTrace);
            }

            return;
        }
Ejemplo n.º 3
0
        /* 非同期イベントハンドラ
         * CaptureDeviceからのイベントをハンドリングして、バッファとテクスチャを更新する。
         */
        public void onSample(WmCapture i_sender, INySample i_sample)
        {
            int w = SCREEN_WIDTH;
            int h = SCREEN_HEIGHT;
            int s = w * h;

            Thread.Sleep(0);
            lock (this)
            {
                //カメラ映像をARのバッファにコピー
                this._reality_source.setWMCaptureSample(i_sample.GetData(), i_sender.vertical_flip);
                this._reality.progress(this._reality_source);

                //テクスチャ内容を更新
                this._back_ground.CopyFromRaster((DsRGB565Raster)this._reality_source.refRgbSource());

                //UnknownTargetを1個取得して、遷移を試す。
                NyARRealityTarget t = this._reality.selectSingleUnknownTarget();
                if (t == null)
                {
                    return;
                }
                //ターゲットに一致するデータを検索
                ARTKMarkerTable.GetBestMatchTargetResult r = new ARTKMarkerTable.GetBestMatchTargetResult();
                if (this._mklib.getBestMatchTarget(t, this._reality_source, r))
                {
                    if (r.confidence < 0.5)
                    {   //一致率が低すぎる。
                        return;
                    }
                    //既に認識しているターゲットの内側のものでないか確認する?(この処理をすれば、二重認識は無くなる。)

                    //一致度を確認して、80%以上ならKnownターゲットへ遷移
                    if (!this._reality.changeTargetToKnown(t, r.artk_direction, r.marker_width))
                    {
                        //遷移の成功チェック
                        return;//失敗
                    }
                    //遷移に成功したので、tagにResult情報をコピーしておく。(後で表示に使う)
                    t.tag = r;
                }
                else
                {
                    //一致しないので、このターゲットは捨てる。
                    this._reality.changeTargetToDead(t, 10);
                }
            }

            return;
        }
        /* 非同期イベントハンドラ
         * CaptureDeviceからのイベントをハンドリングして、バッファとテクスチャを更新する。
         */
        public void OnBuffer(CaptureDevice i_sender, double i_sample_time, IntPtr i_buffer, int i_buffer_len)
        {
            int w = i_sender.video_width;
            int h = i_sender.video_height;
            int s = w * (i_sender.video_bit_count / 8);

            lock (this)
            {
                //カメラ映像をARのバッファにコピー
                this._reality_source.setDShowImage(i_buffer, i_buffer_len, i_sender.video_vertical_flip);
                this._reality.progress(this._reality_source);
                //テクスチャ内容を更新
                this._surface.setRaster(this._reality_source.refRgbSource());

                //UnknownTargetを1個取得して、遷移を試す。
                NyARRealityTarget t = this._reality.selectSingleUnknownTarget();
                if (t == null)
                {
                    return;
                }
                //ターゲットに一致するデータを検索
                ARTKMarkerTable.GetBestMatchTargetResult r = new ARTKMarkerTable.GetBestMatchTargetResult();
                if (this._mklib.getBestMatchTarget(t, this._reality_source, r))
                {
                    if (r.confidence < 0.6)
                    {                           //一致率が低すぎる。
                        return;
                    }
                    //既に認識しているターゲットの内側のものでないか確認する?(この処理をすれば、二重認識は無くなる。)

                    //一致度を確認して、80%以上ならKnownターゲットへ遷移
                    if (!this._reality.changeTargetToKnown(t, r.artk_direction, r.marker_width))
                    {
                        //遷移の成功チェック
                        return;                        //失敗
                    }
                    //遷移に成功したので、tagにResult情報をコピーしておく。(後で表示に使う)
                    t.tag = r;
                }
                else
                {
                    //一致しないので、このターゲットは捨てる。
                    this._reality.changeTargetToDead(t, 15);
                }
            }
            return;
        }
        //メインループ処理
        public void MainLoop()
        {
            //ARの計算
            lock (this)
            {
                // 背景サーフェイスを直接描画
                Surface   dest_surface  = this._device.GetBackBuffer(0, 0, BackBufferType.Mono);
                Rectangle src_dest_rect = new Rectangle(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
                this._device.StretchRectangle((Surface)this._surface, src_dest_rect, dest_surface, src_dest_rect, TextureFilter.None);

                // 3Dオブジェクトの描画はここから
                this._device.BeginScene();
                this._device.Clear(ClearFlags.ZBuffer, Color.DarkBlue, 1.0f, 0);


                //ターゲットリストを走査して、画面に内容を反映
                NyARRealityTargetList tl = this._reality.refTargetList();
                for (int i = tl.getLength() - 1; i >= 0; i--)
                {
                    NyARRealityTarget t = tl.getItem(i);
                    switch (t.getTargetType())
                    {
                    case NyARRealityTarget.RT_KNOWN:
                        //立方体を20mm上(マーカーの上)にずらしておく
                        Matrix mat = new Matrix();
                        this._reality.getD3dModelViewMatrix(t.refTransformMatrix(), ref mat);
                        Matrix transform_mat2 = Matrix.Translation(0, 0, 20.0f);
                        transform_mat2 = transform_mat2 * mat;
                        this._device.SetTransform(TransformType.World, transform_mat2);
                        this._cube.draw(this._device);
                        break;

                    case NyARRealityTarget.RT_UNKNOWN:
                        //NyARDoublePoint2d[] p = t.refTargetVertex();
                        //NyARGLDrawUtil.beginScreenCoordinateSystem(this._gl, SCREEN_X, SCREEN_Y, true);
                        //NyARGLDrawUtil.endScreenCoordinateSystem(this._gl);
                        break;
                    }
                }
                // 描画はここまで
                this._device.EndScene();

                // 実際のディスプレイに描画
                this._device.Present();
            }
            return;
        }
Ejemplo n.º 6
0
        //メインループ処理
        public void MainLoop()
        {
            //ARの計算
            lock (this)
            {
                Device dev = this._d3dmgr.d3d_device;
                // 背景サーフェイスを直接描画

                // 3Dオブジェクトの描画はここから
                dev.Clear(ClearFlags.ZBuffer, Color.DarkBlue, 1.0f, 0);
                dev.BeginScene();
                this._back_ground.drawBackGround(this._d3dmgr.d3d_device);


                //ターゲットリストを走査して、画面に内容を反映
                NyARRealityTargetList tl = this._reality.refTargetList();
                for (int i = tl.getLength() - 1; i >= 0; i--)
                {
                    NyARRealityTarget t = tl.getItem(i);
                    switch (t.getTargetType())
                    {
                    case NyARRealityTarget.RT_KNOWN:
                        //立方体を20mm上(マーカーの上)にずらしておく
                        Matrix mat = new Matrix();
                        this._reality.getD3dModelViewMatrix(t.refTransformMatrix(), ref mat);
                        Matrix transform_mat2 = Matrix.Translation(0, 0, 20.0f);
                        transform_mat2 = transform_mat2 * mat;
                        dev.SetTransform(TransformType.World, transform_mat2);
                        this._d3dcube.draw(dev);
                        break;

                    case NyARRealityTarget.RT_UNKNOWN:
                        //NyARDoublePoint2d[] p = t.refTargetVertex();
                        //NyARGLDrawUtil.beginScreenCoordinateSystem(this._gl, SCREEN_X, SCREEN_Y, true);
                        //NyARGLDrawUtil.endScreenCoordinateSystem(this._gl);
                        break;
                    }
                }
                // 描画はここまで
                dev.EndScene();

                // 実際のディスプレイに描画
                dev.Present();
            }
            return;
        }
        /* 非同期イベントハンドラ
         * CaptureDeviceからのイベントをハンドリングして、バッファとテクスチャを更新する。
         */
        public void OnBuffer(CaptureDevice i_sender, double i_sample_time, IntPtr i_buffer, int i_buffer_len)
        {
            try {
                lock (this)
                {
                    this._reality_source.setDShowImage(i_buffer, i_buffer_len, i_sender.video_vertical_flip);
                    this._reality.progress(this._reality_source);
                    //テクスチャ内容を更新
                    this._surface.setRaster(this._reality_source.refRgbSource());

                    //UnknownTargetを1個取得して、遷移を試す。
                    NyARRealityTarget t = this._reality.selectSingleUnknownTarget();
                    if (t == null)
                    {
                        return;
                    }
                    //ターゲットに一致するデータを検索
                    RawbitSerialIdTable.IdentifyIdResult r = new RawbitSerialIdTable.IdentifyIdResult();
                    if (this._mklib.identifyId(t, this._reality_source, r))
                    {
                        //テーブルにターゲットが見つかったので遷移する。
                        if (!this._reality.changeTargetToKnown(t, r.artk_direction, r.marker_width))
                        {
                            //遷移の成功チェック
                            return;                        //失敗
                        }
                        //遷移に成功したので、tagにユーザ定義情報を書きこむ。
                        long l = new long();
                        l     = r.id;
                        t.tag = l;
                    }
                    else
                    {
                        //一致しないので、このターゲットは捨てる。(15フレーム無視)
                        this._reality.changeTargetToDead(t, 15);
                    }
                }
            } catch (Exception e) {
                System.Console.WriteLine(e.StackTrace);
            }
            return;
        }
Ejemplo n.º 8
0
        public void Test()
        {
            try {
                NyARParam param = NyARParam.createFromARParamFile(new StreamReader(PARAM_FILE));
                param.changeScreenSize(320, 240);
                NyARReality       reality    = new NyARReality(param.getScreenSize(), 10, 1000, param.getPerspectiveProjectionMatrix(), null, 10, 10);
                NyARRealitySource reality_in = new NyARRealitySource_Reference(320, 240, null, 2, 100, NyARBufferType.BYTE1D_B8G8R8X8_32);

                //試験イメージの読み出し(320x240 BGRAのRAWデータ)
                StreamReader sr  = new StreamReader(DATA_FILE);
                BinaryReader bs  = new BinaryReader(sr.BaseStream);
                byte[]       raw = bs.ReadBytes(320 * 240 * 4);
                Array.Copy(raw, (byte[])reality_in.refRgbSource().getBuffer(), raw.Length);


                Stopwatch sw = new Stopwatch();
                sw.Start();
                for (int i = 0; i < 1000; i++)
                {
                    reality.progress(reality_in);
                }
                sw.Stop();
                Console.WriteLine(sw.ElapsedMilliseconds + "[ms]");
                Console.WriteLine(reality.getNumberOfKnown());
                Console.WriteLine(reality.getNumberOfUnknown());
                Console.WriteLine(reality.getNumberOfDead());
                NyARRealityTarget[] rt = new NyARRealityTarget[10];
                reality.selectUnKnownTargets(rt);
                reality.changeTargetToKnown(rt[0], 2, 80);
                Console.WriteLine(rt[0]._transform_matrix.m00 + "," + rt[0]._transform_matrix.m01 + "," + rt[0]._transform_matrix.m02 + "," + rt[0]._transform_matrix.m03);
                Console.WriteLine(rt[0]._transform_matrix.m10 + "," + rt[0]._transform_matrix.m11 + "," + rt[0]._transform_matrix.m12 + "," + rt[0]._transform_matrix.m13);
                Console.WriteLine(rt[0]._transform_matrix.m20 + "," + rt[0]._transform_matrix.m21 + "," + rt[0]._transform_matrix.m22 + "," + rt[0]._transform_matrix.m23);
                Console.WriteLine(rt[0]._transform_matrix.m30 + "," + rt[0]._transform_matrix.m31 + "," + rt[0]._transform_matrix.m32 + "," + rt[0]._transform_matrix.m33);
            } catch (Exception e) {
                Console.WriteLine(e.StackTrace);
            }
            return;
        }
Ejemplo n.º 9
0
        /**
         * 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;
            NyARPerspectiveRasterReader r = i_rtsorce.refPerspectiveRasterReader();

            r.read4Point(i_rtsorce.refRgbSource(), 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);
        }
Ejemplo n.º 10
0
        /**
         * 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;
        }
Ejemplo n.º 11
0
        /**
         * このターゲットについて、非同期に認識依頼を出します。このプログラムはサンプルなので、別スレッドで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;
        }