/// <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();
        }
Пример #2
0
        /**
         * 内部関数です。
         * この関数は、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
                    }
                }
            }
Пример #4
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;
            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
                    }
                }
            }
Пример #6
0
            /**
             * 矩形が見付かるたびに呼び出されます。
             * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。
             */
            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
                    }
                }
            }