/**
         * double arGetTransMat( ARMarkerInfo *marker_info,double center[2], double width, double conv[3][4] )
         *
         * @param i_square
         * 計算対象のNyARSquareオブジェクト
         * @param i_width
         * @return
         * @throws NyARException
         */
        public void transMat(NyARSquare i_square, NyARRectOffset i_offset, NyARTransMatResult o_result_conv)
        {
            NyARDoublePoint3d trans = this.__transMat_trans;

            //平行移動量計算機に、2D座標系をセット
            NyARDoublePoint2d[] vertex_2d;
            if (this._ref_dist_factor != null)
            {
                //歪み復元必要
                vertex_2d = this.__transMat_vertex_2d;
                this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d, 4);
            }
            else
            {
                //歪み復元は不要
                vertex_2d = i_square.sqvertex;
            }
            this._transsolver.set2dVertex(vertex_2d, 4);
            //回転行列を計算
            this._rotmatrix.initRotBySquare(i_square.line, i_square.sqvertex);

            //回転後の3D座標系から、平行移動量を計算
            NyARDoublePoint3d[] vertex_3d = this.__transMat_vertex_3d;
            this._rotmatrix.getPoint3dBatch(i_offset.vertex, vertex_3d, 4);
            this._transsolver.solveTransportVector(vertex_3d, trans);

            //計算結果の最適化(平行移動量と回転行列の最適化)
            double err = this.optimize(this._rotmatrix, trans, this._transsolver, i_offset.vertex, vertex_2d);

            // マトリクスの保存
            o_result_conv.setValue(this._rotmatrix, trans, err);
            return;
        }
        /**オブジェクトのステータスを更新し、必要に応じてハンドル関数を駆動します。
         */
        private bool updateStatus(NyARSquare i_square, INyIdMarkerData i_marker_data)
        {
            bool is_id_found          = false;
            NyARTransMatResult result = this.__NyARSquare_result;

            if (!this._is_active)
            {     // 未認識中
                if (i_marker_data == null)
                { // 未認識から未認識の遷移
                    // なにもしないよーん。
                    this._is_active = false;
                }
                else
                {// 未認識から認識の遷移
                    this._data_current.copyFrom(i_marker_data);
                    // イベント生成
                    // OnEnter
                    this.onEnterHandler(this._data_current);
                    // 変換行列を作成
                    this._transmat.transMat(i_square, this._offset, result);
                    // OnUpdate
                    this.onUpdateHandler(i_square, result);
                    this._lost_delay_count = 0;
                    this._is_active        = true;
                    is_id_found            = true;
                }
            }
            else
            {// 認識中
                if (i_marker_data == null)
                {
                    // 認識から未認識の遷移
                    this._lost_delay_count++;
                    if (this._lost_delay < this._lost_delay_count)
                    {
                        // OnLeave
                        this.onLeaveHandler();
                        this._is_active = false;
                    }
                }
                else if (this._data_current.isEqual(i_marker_data))
                {
                    //同じidの再認識
                    this._transmat.transMatContinue(i_square, this._offset, result);
                    // OnUpdate
                    this.onUpdateHandler(i_square, result);
                    this._lost_delay_count = 0;
                    is_id_found            = true;
                }
                else
                {// 異なるコードの認識→今はサポートしない。
                    throw new NyARException();
                }
            }
            return(is_id_found);
        }
예제 #3
0
        /**	オブジェクトのステータスを更新し、必要に応じてハンドル関数を駆動します。
         *  戻り値は、「実際にマーカを発見する事ができたか」です。クラスの状態とは異なります。
         */
        private bool updateStatus(NyARSquare i_square, int i_code_index)
        {
            NyARTransMatResult result = this.__NyARSquare_result;

            if (this._current_arcode_index < 0)
            {     // 未認識中
                if (i_code_index < 0)
                { // 未認識から未認識の遷移
                    // なにもしないよーん。
                    return(false);
                }
                else
                {// 未認識から認識の遷移
                    this._current_arcode_index = i_code_index;
                    // イベント生成
                    // OnEnter
                    this.onEnterHandler(i_code_index);
                    // 変換行列を作成
                    this._transmat.transMat(i_square, this._offset, result);
                    // OnUpdate
                    this.onUpdateHandler(i_square, result);
                    this._lost_delay_count = 0;
                    return(true);
                }
            }
            else
            {     // 認識中
                if (i_code_index < 0)
                { // 認識から未認識の遷移
                    this._lost_delay_count++;
                    if (this._lost_delay < this._lost_delay_count)
                    {
                        // OnLeave
                        this._current_arcode_index = -1;
                        this.onLeaveHandler();
                    }
                    return(false);
                }
                else if (i_code_index == this._current_arcode_index)
                {// 同じARCodeの再認識
                    // イベント生成
                    // 変換行列を作成
                    this._transmat.transMatContinue(i_square, this._offset, result);
                    // OnUpdate
                    this.onUpdateHandler(i_square, result);
                    this._lost_delay_count = 0;
                    return(true);
                }
                else
                {// 異なるコードの認識→今はサポートしない。
                    throw new NyARException();
                }
            }
        }
        /*
         * (non-Javadoc)
         * @see jp.nyatla.nyartoolkit.core.transmat.INyARTransMat#transMatContinue(jp.nyatla.nyartoolkit.core.NyARSquare, int, double, jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult)
         */
        public void transMatContinue(NyARSquare i_square, NyARRectOffset i_offset, NyARTransMatResult o_result_conv)
        {
            NyARDoublePoint3d trans = this.__transMat_trans;

            // io_result_convが初期値なら、transMatで計算する。
            if (!o_result_conv.has_value)
            {
                this.transMat(i_square, i_offset, o_result_conv);
                return;
            }

            //平行移動量計算機に、2D座標系をセット
            NyARDoublePoint2d[] vertex_2d = this.__transMat_vertex_2d;
            NyARDoublePoint3d[] vertex_3d = this.__transMat_vertex_3d;
            this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d, 4);
            this._transsolver.set2dVertex(vertex_2d, 4);

            //回転行列を計算
            this._rotmatrix.initRotByPrevResult(o_result_conv);

            //回転後の3D座標系から、平行移動量を計算
            this._rotmatrix.getPoint3dBatch(i_offset.vertex, vertex_3d, 4);
            this._transsolver.solveTransportVector(vertex_3d, trans);

            //計算結果の最適化(平行移動量と回転行列の最適化)
            double err = this.optimize(this._rotmatrix, trans, this._transsolver, i_offset.vertex, vertex_2d);

            // マトリクスの保存
            this.updateMatrixValue(this._rotmatrix, trans, o_result_conv);

            // エラー値が許容範囲でなければTransMatをやり直し
            if (err > AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR)
            {
                // rotationを矩形情報で初期化
                this._rotmatrix.initRotBySquare(i_square.line, i_square.sqvertex);
                //回転行列の平行移動量の計算
                this._rotmatrix.getPoint3dBatch(i_offset.vertex, vertex_3d, 4);
                this._transsolver.solveTransportVector(vertex_3d, trans);
                //計算結果の最適化(this._rotmatrix,trans)
                double err2 = this.optimize(this._rotmatrix, trans, this._transsolver, i_offset.vertex, vertex_2d);
                //エラー値が低かったら値を差換え
                if (err2 < err)
                {
                    // 良い値が取れたら、差換え
                    this.updateMatrixValue(this._rotmatrix, trans, o_result_conv);
                }
                err = err2;
            }
            //エラー値保存
            o_result_conv.error = err;
            return;
        }
 /**
  * 検出したマーカーの変換行列を計算して、o_resultへ値を返します。
  * 直前に実行したdetectMarkerLiteが成功していないと使えません。
  *
  * @param o_result
  * 変換行列を受け取るオブジェクトを指定します。
  * @throws NyARException
  */
 public void getTransmationMatrix(NyARTransMatResult o_result)
 {
     // 一番一致したマーカーの位置とかその辺を計算
     if (this._is_continue)
     {
         this._transmat.transMatContinue(this._detect_cb.square, this._offset, o_result);
     }
     else
     {
         this._transmat.transMat(this._detect_cb.square, this._offset, o_result);
     }
     return;
 }
예제 #6
0
        public void Test_arDetectMarkerLite()
        {
            Assembly assembly = Assembly.GetExecutingAssembly();

            //AR用カメラパラメタファイルをロード
            NyARParam ap = new NyARParam();

            ap.loadARParam(assembly.GetManifestResourceStream(RES_CAMERA));
            ap.changeScreenSize(320, 240);

            //AR用のパターンコードを読み出し
            NyARCode code = new NyARCode(16, 16);
            Stream   sr1  = assembly.GetManifestResourceStream(RES_PATT);

            code.loadARPatt(new StreamReader(sr1));

            //試験イメージの読み出し(320x240 BGRAのRAWデータ)
            StreamReader sr = new StreamReader(assembly.GetManifestResourceStream(RES_DATA));
            BinaryReader bs = new BinaryReader(sr.BaseStream);

            byte[]             raw = bs.ReadBytes(320 * 240 * 4);
            NyARRgbRaster_BGRA ra  = new NyARRgbRaster_BGRA(320, 240, false);

            ra.wrapBuffer(raw);
            //		Blank_Raster ra=new Blank_Raster(320, 240);

            //1パターンのみを追跡するクラスを作成
//            NyARSingleDetectMarker_Quad ar = new NyARSingleDetectMarker_Quad(ap, code, 80.0);
            NyARSingleDetectMarker ar         = new NyARSingleDetectMarker(ap, code, 80.0, ra.getBufferType());
            NyARTransMatResult     result_mat = new NyARTransMatResult();

            ar.setContinueMode(false);
            ar.detectMarkerLite(ra, 100);
            ar.getTransmationMatrix(result_mat);

            //マーカーを検出
            for (int i3 = 0; i3 < 10; i3++)
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();
                for (int i = 0; i < 10; i++)
                {
                    //変換行列を取得
                    ar.detectMarkerLite(ra, 100);
                    ar.getTransmationMatrix(result_mat);
                }
                sw.Stop();
                Debug.WriteLine(sw.ElapsedMilliseconds + "[ms]");
            }
            return;
        }
예제 #7
0
        /**
         * i_indexのマーカーに対する変換行列を計算し、結果値をo_resultへ格納します。 直前に実行したdetectMarkerLiteが成功していないと使えません。
         *
         * @param i_index
         * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
         * @param o_result
         * 結果値を受け取るオブジェクトを指定してください。
         * @throws NyARException
         */
        public void getTransmationMatrix(int i_index, NyARTransMatResult o_result)
        {
            NyARDetectMarkerResult result = this._square_detect.result_stack.getItem(i_index);

            // 一番一致したマーカーの位置とかその辺を計算
            if (_is_continue)
            {
                _transmat.transMatContinue(result.square, this._offset[result.arcode_id], o_result, o_result);
            }
            else
            {
                _transmat.transMat(result.square, this._offset[result.arcode_id], o_result);
            }
            return;
        }
예제 #8
0
 public void toD3dMatrix(NyARTransMatResult i_ny_result, ref Matrix o_result)
 {
     //ARのMatrixをDirectXのMatrixに変換
     o_result.M11 = (float)i_ny_result.m00;
     o_result.M12 = (float)i_ny_result.m10;
     o_result.M13 = (float)i_ny_result.m20;
     o_result.M14 = 0;
     o_result.M21 = (float)i_ny_result.m01;
     o_result.M22 = (float)i_ny_result.m11;
     o_result.M23 = (float)i_ny_result.m21;
     o_result.M24 = 0;
     o_result.M31 = (float)i_ny_result.m02;
     o_result.M32 = (float)i_ny_result.m12;
     o_result.M33 = (float)i_ny_result.m22;
     o_result.M34 = 0;
     o_result.M41 = (float)i_ny_result.m03;
     o_result.M42 = (float)i_ny_result.m13;
     o_result.M43 = (float)i_ny_result.m23;
     o_result.M44 = 1;
     return;
 }
        /**
         * double arGetTransMat( ARMarkerInfo *marker_info,double center[2], double width, double conv[3][4] )
         * 
         * @param i_square
         * 計算対象のNyARSquareオブジェクト
         * @param i_width
         * @return
         * @throws NyARException
         */
        public void transMat(NyARSquare i_square, NyARRectOffset i_offset, NyARTransMatResult o_result_conv)
        {
            NyARDoublePoint3d trans = this.__transMat_trans;

            //平行移動量計算機に、2D座標系をセット
            NyARDoublePoint2d[] vertex_2d = this.__transMat_vertex_2d;
            NyARDoublePoint3d[] vertex_3d = this.__transMat_vertex_3d;
            this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d, 4);
            this._transsolver.set2dVertex(vertex_2d, 4);

            //回転行列を計算
            this._rotmatrix.initRotBySquare(i_square.line, i_square.sqvertex);

            //回転後の3D座標系から、平行移動量を計算
            this._rotmatrix.getPoint3dBatch(i_offset.vertex, vertex_3d, 4);
            this._transsolver.solveTransportVector(vertex_3d, trans);

            //計算結果の最適化(平行移動量と回転行列の最適化)
            o_result_conv.error = this.optimize(this._rotmatrix, trans, this._transsolver, i_offset.vertex, vertex_2d);

            // マトリクスの保存
            this.updateMatrixValue(this._rotmatrix, trans, o_result_conv);
            return;
        }
        /// <summary>
        /// Listener method called when something was detected.
        /// </summary>
        /// <param name="callingDetector">The detector that called the method.</param>
        /// <param name="coordsX">The four x coordinates of the detected marker square.</param>
        /// <param name="coordsY">The four y coordinates of the detected marker square.</param>
        /// <param name="coordCount">The number of coordinates.</param>
        /// <param name="coordIndices">The indices of the coordiantes in the coords array.</param>
        public void onSquareDetect(NyARSquareContourDetector callingDetector, int[] coordsX, int[] coordsY, int coordCount, int[] coordIndices)
        {
            // Init variables
            points[0].x = coordsX[coordIndices[0]];
            points[0].y = coordsY[coordIndices[0]];
            points[1].x = coordsX[coordIndices[1]];
            points[1].y = coordsY[coordIndices[1]];
            points[2].x = coordsX[coordIndices[2]];
            points[2].y = coordsY[coordIndices[2]];
            points[3].x = coordsX[coordIndices[3]];
            points[3].y = coordsY[coordIndices[3]];

            // Evaluate and find best match
            if (this.colorPattern.pickFromRaster(this.Buffer, points))
            {
                // Find best matching marker
                this.patternMatchDeviationData.setRaster(this.colorPattern);
                Marker foundMarker    = null;
                int    foundDirection = NyARMatchPattResult.DIRECTION_UNKNOWN;
                double bestConfidence = 0;

                foreach (var patMat in patternMatchers)
                {
                    // Evaluate
                    patMat.evaluate(this.patternMatchDeviationData, evaluationResult);

                    // Best match?
                    if (evaluationResult.confidence > bestConfidence)
                    {
                        foundMarker    = patMat.Marker;
                        foundDirection = evaluationResult.direction;
                        bestConfidence = evaluationResult.confidence;
                    }
                }

                // Calculate found marker square
                var square = new NyARSquare();
                var len    = coordIndices.Length;
                for (int i = 0; i < len; i++)
                {
                    int idx = (i + len - foundDirection) % len;
                    this.coordinationMapper.coord2Line(coordIndices[idx], coordIndices[(idx + 1) % len], coordsX, coordsY, coordCount, square.line[i]);
                }
                // Calculate normal
                for (int i = 0; i < len; i++)
                {
                    NyARLinear.crossPos(square.line[i], square.line[(i + 3) % len], square.sqvertex[i]);
                }

                // Calculate matrix using continued mode
                if (foundMarker != null)
                {
                    var nymat = new NyARTransMatResult();
                    matrixCalculator.transMatContinue(square, foundMarker.RectOffset, nymat);

                    // Create and add result to collection
                    var v            = square.sqvertex;
                    var resultSquare = new Square(v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, v[3].x, v[3].y);
                    Results.Add(new DetectionResult(foundMarker, bestConfidence, nymat.ToMatrix3D(), resultSquare));
                }
            }
        }
예제 #11
0
        //Método executado a cada frame de vídeo
        public void OnBuffer(CaptureDevice i_sender, double i_sample_time, IntPtr i_buffer, int i_buffer_len)
        {
            try
            {
                i++;
                int                w             = i_sender.video_width;
                int                h             = i_sender.video_height;
                int                s             = w * (i_sender.video_bit_count / 8);
                Matrix             trans_matrix  = new Matrix();
                NyARTransMatResult nyar_transmat = this.__OnBuffer_nyar_transmat;

                Bitmap b = new Bitmap(w, h, s, PixelFormat.Format32bppRgb, i_buffer);

                // If the image is upsidedown
                b.RotateFlip(RotateFlipType.RotateNoneFlipY);
                this.pbxNyAR.Image = b;

                //Calculation of the AR - Seta o frame do vídeo no objeto Raster
                Core.raster.setBuffer(i_buffer, i_sender.video_vertical_flip);

                //Instância dos objetos de detecção
                detectedMarkersListLetters = new ArrayList();
                detectedMarkersListImages  = new ArrayList();
                NyARTransMatResult transMatrix;
                NyARDoublePoint3d  point3D;



                //Aqui vem a lógica do Bingo
                //1 - Detectar o marcador da cartela
                //2 - Verificar a relação de letras sorteadas e a palavra da cartela
                //3 - Se a palavra tiver todas as letras sorteadas, plotar o desenho específico
                //  - Senão, informa de algum jeito o total das letras, e qual falta, sei lá.

                //Verficar a palavra relacionada à cartela
                string originalWord = string.Empty;

                //Adiciona as letras sorteadas no ArrayList para comparação
                raffledLetters = new ArrayList();
                foreach (char item in gmNyAR.RaffleLetters)
                {
                    raffledLetters.Add(item);
                }



                if (intRefresh == 0)
                {
                    //Detecção das LETRAS
                    int totalMarkersLetter           = this.markerDetectorLetters.detectMarkerLite(Core.raster, 100);
                    int markerLetterId               = 0;
                    NyARTransMatResult transMatKanji = new NyARTransMatResult();

                    //Caso encontrar marcadores
                    if (totalMarkersLetter > 0)
                    {
                        for (int counter = 0; counter < totalMarkersLetter; counter++)
                        {
                            markerLetterId = this.markerDetectorLetters.getARCodeIndex(counter);

                            if (this.markerDetectorLetters.getConfidence(counter) > 0.60)
                            {
                                if (markerLetterId == 0)
                                {
                                    this.markerDetectorLetters.getTransmationMatrix(markerLetterId, transMatKanji);
                                }
                                else
                                {
                                    //Recupera o ângulo XYZ do marcador e salva na lista.
                                    transMatrix = new NyARTransMatResult();
                                    point3D     = new NyARDoublePoint3d();
                                    this.markerDetectorLetters.getTransmationMatrix(counter, transMatrix);
                                    transMatrix.getZXYAngle(point3D);

                                    detectedMarker          = new DetectedMarker();
                                    detectedMarker.markerID = markerLetterId;
                                    detectedMarker.point3D  = point3D;
                                    detectedMarkersListLetters.Add(detectedMarker);
                                }
                            }
                        }
                    }

                    //Detecção dos marcadores específicos
                    int totalMarkerImages = this.markerDetectorImages.detectMarkerLite(Core.raster, 100);
                    int markerImageId     = 0;

                    if (totalMarkerImages > 0)
                    {
                        for (int counter = 0; counter < totalMarkerImages; counter++)
                        {
                            markerImageId = this.markerDetectorImages.getARCodeIndex(counter);

                            if (this.markerDetectorImages.getConfidence(counter) > 0.50)
                            {
                                //Recupera o ângulo XYZ do marcador e salva na lista.
                                transMatrix = new NyARTransMatResult();
                                point3D     = new NyARDoublePoint3d();
                                this.markerDetectorImages.getTransmationMatrix(counter, transMatrix);
                                transMatrix.getZXYAngle(point3D);

                                detectedMarker          = new DetectedMarker();
                                detectedMarker.markerID = markerImageId;
                                detectedMarker.point3D  = point3D;
                                detectedMarkersListImages.Add(detectedMarker);
                            }
                        }
                    }



                    if ((detectedMarkersListLetters.Count + detectedMarkersListImages.Count) > 0)
                    {
                        if ((detectedMarkersListLetters.Count + detectedMarkersListImages.Count) > 1)
                        {
                            lbNyAR.Text = "Há letras que não foram preenchidas na cartela";
                            //Fazer algo para avisar que nem todas as letras foram preenchidas.
                        }
                        else
                        {
                            if (detectedMarkersListImages.Count > 0)
                            {
                                //switch das palavras correspondentes ao marcador encontrado.
                                switch (markerImageId)
                                {
                                case 0: originalWord = "BOLA";
                                    break;

                                case 1: originalWord = "ESPADA";
                                    break;

                                case 2: originalWord = "CARRO";
                                    break;

                                case 3: originalWord = "BRIGADEIRO";
                                    break;

                                case 4: originalWord = "GARFO";
                                    break;

                                case 5: originalWord = "CANETA";
                                    break;

                                case 6: originalWord = "PEIXE";
                                    break;
                                }

                                int total = checkTotalLetters(raffledLetters, originalWord);

                                //Se todas as letras da palavra tiverem sido sorteadas, plota a imagem
                                if (total == originalWord.Length)
                                {
                                    lbNyAR.Text = "BINGO! Palavra: " + originalWord;
                                    intRefresh++;
                                    intDetected = markerImageId;
                                }
                                else
                                {
                                    lbNyAR.Text = "Algumas letras ainda não foram sorteadas";
                                    //Verificar o que vai fazer... pode ser uma mensagem na tela.
                                }
                            }
                        }
                    }
                }
                else
                {
                    bool detected;
                    switch (intDetected)
                    {
                    case 0: detected = this.ballMarkerDetector.detectMarkerLite(Core.raster);
                        if (detected)
                        {
                            NyARTransMatResult result = new NyARTransMatResult();
                            if (this.ballMarkerDetector.getConfidence() > 0.50)
                            {
                                this.ballMarkerDetector.getTransmationMatrix(result);
                                //DrawWord("bola", result);
                            }
                        }
                        break;

                    case 1: detected = this.swordMarkerDetector.detectMarkerLite(Core.raster);
                        if (detected)
                        {
                            NyARTransMatResult result = new NyARTransMatResult();
                            if (this.swordMarkerDetector.getConfidence() > 0.50)
                            {
                                this.swordMarkerDetector.getTransmationMatrix(result);
                                //DrawWord("espada", result);
                            }
                        }
                        break;

                    case 3: detected = this.carMarkerDetector.detectMarkerLite(Core.raster);
                        if (detected)
                        {
                            NyARTransMatResult result = new NyARTransMatResult();
                            if (this.carMarkerDetector.getConfidence() > 0.50)
                            {
                                this.carMarkerDetector.getTransmationMatrix(result);
                                //DrawWord("carro", result);
                            }
                        }
                        break;

                    case 4: detected = this.forkMarkerDetector.detectMarkerLite(Core.raster);
                        if (detected)
                        {
                            NyARTransMatResult result = new NyARTransMatResult();
                            if (this.forkMarkerDetector.getConfidence() > 0.50)
                            {
                                this.forkMarkerDetector.getTransmationMatrix(result);
                                DrawWord("garfo", result);
                            }
                        }
                        break;

                    case 5: detected = this.penMarkerDetector.detectMarkerLite(Core.raster);
                        if (detected)
                        {
                            NyARTransMatResult result = new NyARTransMatResult();
                            if (this.penMarkerDetector.getConfidence() > 0.50)
                            {
                                this.penMarkerDetector.getTransmationMatrix(result);
                                //DrawWord("caneta", result);
                            }
                        }
                        break;

                    case 6: detected = this.fishMarkerDetector.detectMarkerLite(Core.raster);
                        if (detected)
                        {
                            NyARTransMatResult result = new NyARTransMatResult();
                            if (this.fishMarkerDetector.getConfidence() > 0.50)
                            {
                                this.fishMarkerDetector.getTransmationMatrix(result);
                                DrawWord("peixe", result);
                            }
                        }
                        break;
                    }


                    //Refresh do detector
                    intRefresh++;
                    if (intRefresh > 20)
                    {
                        intRefresh  = 0;
                        intDetected = -1;
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("Ocorreu um erro na verficação dos marcadores. Favor, reinicie a aplicação. Se o erro persistir, contate os desenvolvedores.", "Erro!");
                Environment.Exit(0);
            }
        }
예제 #12
0
        void CaptureListener.OnBuffer(CaptureDevice i_sender, double i_sample_time, IntPtr i_buffer, int i_buffer_len)
        {
            // calculate size of the frame bitmap
            int w = i_sender.video_width;
            int h = i_sender.video_height;
            int s = w * (i_sender.video_bit_count / 8); // stride


            AForge.Imaging.Filters.FiltersSequence seq = new AForge.Imaging.Filters.FiltersSequence();
            seq.Add(new AForge.Imaging.Filters.Grayscale(0.2125, 0.7154, 0.0721));
            seq.Add(new AForge.Imaging.Filters.Threshold(127));
            seq.Add(new AForge.Imaging.Filters.GrayscaleToRGB());
            AForge.Imaging.UnmanagedImage srcImg    = new AForge.Imaging.UnmanagedImage(i_buffer, w, h, s, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
            AForge.Imaging.UnmanagedImage outputImg = seq.Apply(srcImg);
            byte[] destArr = new byte[outputImg.Stride * outputImg.Height];
            System.Runtime.InteropServices.Marshal.Copy(outputImg.ImageData, destArr, 0, outputImg.Stride * outputImg.Height);
            this.m_raster.wrapBuffer(destArr);

            try
            {
                int        detectedMkrs = this.m_ar.detectMarkerLite(this.m_raster, m_threshold);
                NyARSquare square       = null;
                if (detectedMkrs > 0)
                {
                    NyARTransMatResult  transMat = new NyARTransMatResult();
                    NyARDoublePoint2d[] points   = m_ar.getCorners(0); // RichF added this method
                    square          = new NyARSquare();
                    square.sqvertex = points;
                }


                Dispatcher.BeginInvoke(new Action(delegate()
                {
                    TransformedBitmap b = new TransformedBitmap();
                    b.BeginInit();
                    b.Source = BitmapSource.Create(w, h, dpiX, dpiY, PixelFormats.Bgr32, BitmapPalettes.WebPalette, i_buffer, i_buffer_len, s);
                    b.SetValue(TransformedBitmap.TransformProperty, new ScaleTransform(-1, -1));
                    b.EndInit();
                    image1.SetValue(Image.SourceProperty, b);

                    if (square != null)
                    {
                        recognizedTag.Points = new PointCollection(new Point[] {
                            new Point(cameraResX - square.sqvertex[0].x, cameraResY - square.sqvertex[0].y),
                            new Point(cameraResX - square.sqvertex[1].x, cameraResY - square.sqvertex[1].y),
                            new Point(cameraResX - square.sqvertex[2].x, cameraResY - square.sqvertex[2].y),
                            new Point(cameraResX - square.sqvertex[3].x, cameraResY - square.sqvertex[3].y)
                        });

                        recognizedTag.Visibility = System.Windows.Visibility.Visible;
                    }
                    else
                    {
                        recognizedTag.Visibility = System.Windows.Visibility.Hidden;
                    }
                }), null);
            }
            catch
            {
            }
        }
예제 #13
0
        //Método executado a cada frame de vídeo
        public void OnBuffer(CaptureDevice i_sender, double i_sample_time, IntPtr i_buffer, int i_buffer_len)
        {
            try
            {
                i++;
                int                w             = i_sender.video_width;
                int                h             = i_sender.video_height;
                int                s             = w * (i_sender.video_bit_count / 8);
                Matrix             trans_matrix  = new Matrix();
                NyARTransMatResult nyar_transmat = this.__OnBuffer_nyar_transmat;

                Bitmap b = new Bitmap(w, h, s, PixelFormat.Format32bppRgb, i_buffer);

                // If the image is upsidedown
                b.RotateFlip(RotateFlipType.RotateNoneFlipY);
                this.pbxNyAR.Image = b;

                //Calculation of the AR - Seta o frame do vídeo no objeto Raster
                Core.raster.setBuffer(i_buffer, i_sender.video_vertical_flip);

                //Instância dos objetos de detecção
                detectedMarkersList = new ArrayList();
                NyARTransMatResult transMatrix;
                NyARDoublePoint3d  point3D;


                if (this.blnKanji == false)   //Controle Kanji. FALSE: Palavra não formada // TRUE: Palavra formada, pronto para plotar
                {
                    //Detecção
                    int    totalMarkers   = this.markerDetector.detectMarkerLite(Core.raster, 100);
                    int    markerId       = 0;
                    string palavraFormada = null;

                    NyARTransMatResult transMatKanji = new NyARTransMatResult();

                    //Caso encontrar marcadores
                    if (totalMarkers > 0)
                    {
                        for (int counter = 0; counter < totalMarkers; counter++)
                        {
                            markerId = this.markerDetector.getARCodeIndex(counter);

                            if (this.markerDetector.getConfidence(counter) > 0.60)
                            {
                                if (markerId == 0)
                                {
                                    this.markerDetector.getTransmationMatrix(markerId, transMatKanji);
                                }
                                else
                                {
                                    //Recupera o ângulo XYZ do marcador e salva na lista.
                                    transMatrix = new NyARTransMatResult();
                                    point3D     = new NyARDoublePoint3d();
                                    this.markerDetector.getTransmationMatrix(counter, transMatrix);
                                    transMatrix.getZXYAngle(point3D);


                                    detectedMarker          = new DetectedMarker();
                                    detectedMarker.markerID = markerId;
                                    detectedMarker.point3D  = point3D;
                                    detectedMarkersList.Add(detectedMarker);
                                }
                            }
                        }
                    }


                    //Realiza os cálculos da RA caso encontrar algum marcador válido
                    if (detectedMarkersList.Count > 0)
                    {
                        //Ordena a lista de acordo com a posição
                        detectedMarkersList.Sort(new OrdenacaoPorX());

                        //Monta a palavra de acordo com os marcadores detectados
                        foreach (DetectedMarker item in detectedMarkersList)
                        {
                            palavraFormada += this.arrayLetters[item.markerID - 1];
                        }

                        if (detectedMarkersList.Count == 3)
                        {
                            totalMarkers = totalMarkers + 0;
                        }



                        //Teste - Verifica o número de letras correspondentes
                        string originalWord = gmNyAR.SelectedObject;
                        int    total        = verificaTotalPalavraFormada(detectedMarkersList, originalWord);
                        if (total == originalWord.Length)
                        {
                            this.blnKanji     = true;
                            this.kanjiCounter = 0; //Refresh do contador
                            lbNyAR.Text       = "Palavra correta!";
                        }
                        else
                        {
                            if (intRefresh == 0)
                            {
                                if (total == 1)
                                {
                                    lbNyAR.Text = "Você acertou " + total + " letra! ";
                                }
                                else
                                {
                                    lbNyAR.Text = "Você acertou " + total + " letras! ";
                                }
                            }
                        }

                        // Realiza a gravação da pontuação
                        int points = (total / originalWord.Length) * 100;

                        if (points > int.Parse(gmNyAR.Points))
                        {
                            gmNyAR.Points = points.ToString();
                        }

                        //Refresh da label que indica a quantidade de letras corretas.
                        intRefresh++;
                        if (intRefresh > 20)
                        {
                            intRefresh = 0;
                        }
                    }
                }
                else
                {
                    //Desenho do objeto 3D no marcador Kanji.
                    bool kanji = this.kanjiDetector.detectMarkerLite(Core.raster);
                    if (kanji)
                    {
                        NyARTransMatResult result = new NyARTransMatResult();
                        if (this.kanjiDetector.getConfidence() > 0.50)
                        {
                            this.kanjiDetector.getTransmationMatrix(result);
                            DrawWord(gmNyAR.SelectedObject, result);
                        }
                    }
                    this.kanjiCounter++;
                    if (this.kanjiCounter > 50)
                    {
                        this.blnKanji = false;
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("Ocorreu um erro na verficação dos marcadores. Favor, reinicie a aplicação. Se o erro persistir, contate os desenvolvedores.", "Erro!");
                Environment.Exit(0);
            }
        }
        /**
         * この関数は、理想座標系の四角系を元に、位置姿勢変換行列を求めます。
         * 計算に過去の履歴を使う点が、{@link #transMat}と異なります。
         * @see INyARTransMat#transMatContinue
         */
        public bool transMatContinue(NyARSquare i_square, NyARRectOffset i_offset, NyARTransMatResult i_prev_result, NyARTransMatResult o_result)
        {
            NyARDoublePoint3d trans = this.__transMat_trans;

            // i_prev_resultが初期値なら、transMatで計算する。
            if (!i_prev_result.has_value)
            {
                this.transMat(i_square, i_offset, o_result);
                return true;
            }

            //平行移動量計算機に、2D座標系をセット
            NyARDoublePoint2d[] vertex_2d;
            if (this._ref_dist_factor != null)
            {
                //歪み復元必要
                vertex_2d = this.__transMat_vertex_2d;
                this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d, 4);
            }
            else
            {
                //歪み復元は不要
                vertex_2d = i_square.sqvertex;
            }
            this._transsolver.set2dVertex(vertex_2d, 4);

            NyARDoublePoint3d[] vertex_3d = this.__transMat_vertex_3d;
            //回転行列を計算
            this._rotmatrix.initRotByPrevResult(i_prev_result);

            //回転後の3D座標系から、平行移動量を計算
            this._rotmatrix.getPoint3dBatch(i_offset.vertex, vertex_3d, 4);
            this._transsolver.solveTransportVector(vertex_3d, trans);

            //計算結果の最適化(平行移動量と回転行列の最適化)
            double err = this.optimize(this._rotmatrix, trans, this._transsolver, i_offset.vertex, vertex_2d);

            // マトリクスの保存
            o_result.setValue(this._rotmatrix, trans, err);

            // エラー値が許容範囲でなければTransMatをやり直し
            if (err > AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR)
            {
                // rotationを矩形情報で初期化
                this._rotmatrix.initRotBySquare(i_square.line, i_square.sqvertex);
                //回転行列の平行移動量の計算
                this._rotmatrix.getPoint3dBatch(i_offset.vertex, vertex_3d, 4);
                this._transsolver.solveTransportVector(vertex_3d, trans);
                //計算結果の最適化(this._rotmatrix,trans)
                double err2 = this.optimize(this._rotmatrix, trans, this._transsolver, i_offset.vertex, vertex_2d);
                //エラー値が低かったら値を差換え
                if (err2 < err)
                {
                    // 良い値が取れたら、差換え
                    o_result.setValue(this._rotmatrix, trans, err2);
                }
                err = err2;
            }
            //エラー値保存
            return true;
        }
        /**
         * この関数は、理想座標系の四角系を元に、位置姿勢変換行列を求めます。
         * ARToolKitのarGetTransMatに該当します。
         * @see INyARTransMat#transMatContinue
         */
        public bool transMat(NyARSquare i_square, NyARRectOffset i_offset, NyARTransMatResult o_result_conv)
        {
            NyARDoublePoint3d trans = this.__transMat_trans;

            //平行移動量計算機に、2D座標系をセット
            NyARDoublePoint2d[] vertex_2d;
            if (this._ref_dist_factor != null)
            {
                //歪み復元必要
                vertex_2d = this.__transMat_vertex_2d;
                this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d, 4);
            }
            else
            {
                //歪み復元は不要
                vertex_2d = i_square.sqvertex;
            }
            this._transsolver.set2dVertex(vertex_2d, 4);
            //回転行列を計算
            this._rotmatrix.initRotBySquare(i_square.line, i_square.sqvertex);

            //回転後の3D座標系から、平行移動量を計算
            NyARDoublePoint3d[] vertex_3d = this.__transMat_vertex_3d;
            this._rotmatrix.getPoint3dBatch(i_offset.vertex, vertex_3d, 4);
            this._transsolver.solveTransportVector(vertex_3d, trans);

            //計算結果の最適化(平行移動量と回転行列の最適化)
            double err = this.optimize(this._rotmatrix, trans, this._transsolver, i_offset.vertex, vertex_2d);

            // マトリクスの保存
            o_result_conv.setValue(this._rotmatrix, trans, err);
            return true;
        }
 protected abstract void onUpdateHandler(NyARSquare i_square, NyARTransMatResult result);
예제 #17
0
 /**
  * @deprecated
  * {@link #getTransmat}
  */
 public void getTransmationMatrix(NyARTransMatResult o_result)
 {
     this.getTransmat(o_result);
     return;
 }
        /**
         * パラメータで変換行列を更新します。
         *
         * @param i_rot
         * @param i_off
         * @param i_trans
         */
        public void updateMatrixValue(NyARRotMatrix i_rot, NyARDoublePoint3d i_trans, NyARTransMatResult o_result)
        {
            o_result.m00 = i_rot.m00;
            o_result.m01 = i_rot.m01;
            o_result.m02 = i_rot.m02;
            o_result.m03 = i_trans.x;

            o_result.m10 = i_rot.m10;
            o_result.m11 = i_rot.m11;
            o_result.m12 = i_rot.m12;
            o_result.m13 = i_trans.y;

            o_result.m20 = i_rot.m20;
            o_result.m21 = i_rot.m21;
            o_result.m22 = i_rot.m22;
            o_result.m23 = i_trans.z;

            o_result.has_value = true;
            return;
        }
        /**
         * This function retrieves bitmap from the area defined by RECT(i_l,i_t,i_r,i_b) above transform matrix i_base_mat.
         * ----
         * この関数は、basementで示される平面のAで定義される領域から、ビットマップを読み出します。
         * 例えば、8cmマーカでRECT(i_l,i_t,i_r,i_b)に-40,0,0,-40.0を指定すると、マーカの左下部分の画像を抽出します。
         *
         * マーカから離れた場所になるほど、また、マーカの鉛直方向から外れるほど誤差が大きくなります。
         * @param i_src_imege
         * 詠み出し元の画像を指定します。
         * @param i_l
         * 基準点からの左上の相対座標(x)を指定します。
         * @param i_t
         * 基準点からの左上の相対座標(y)を指定します。
         * @param i_r
         * 基準点からの右下の相対座標(x)を指定します。
         * @param i_b
         * 基準点からの右下の相対座標(y)を指定します。
         * @param i_base_mat
         * @return 画像の取得の成否を返す。
         */
        public bool pickupImage2d(INyARRgbRaster i_src_imege, double i_l, double i_t, double i_r, double i_b, NyARTransMatResult i_base_mat)
        {
            double cp00, cp01, cp02, cp11, cp12;

            cp00 = this._ref_perspective.m00;
            cp01 = this._ref_perspective.m01;
            cp02 = this._ref_perspective.m02;
            cp11 = this._ref_perspective.m11;
            cp12 = this._ref_perspective.m12;
            //マーカと同一平面上にある矩形の4個の頂点を座標変換して、射影変換して画面上の
            //頂点を計算する。
            //[hX,hY,h]=[P][RT][x,y,z]

            //出力先
            NyARIntPoint2d[] poinsts = this._work_points;

            double yt0, yt1, yt2;
            double x3, y3, z3;

            double m00 = i_base_mat.m00;
            double m10 = i_base_mat.m10;
            double m20 = i_base_mat.m20;

            //yとtの要素を先に計算
            yt0 = i_base_mat.m01 * i_t + i_base_mat.m03;
            yt1 = i_base_mat.m11 * i_t + i_base_mat.m13;
            yt2 = i_base_mat.m21 * i_t + i_base_mat.m23;
            // l,t
            x3           = m00 * i_l + yt0;
            y3           = m10 * i_l + yt1;
            z3           = m20 * i_l + yt2;
            poinsts[0].x = (int)((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);
            poinsts[0].y = (int)((y3 * cp11 + z3 * cp12) / z3);
            // r,t
            x3           = m00 * i_r + yt0;
            y3           = m10 * i_r + yt1;
            z3           = m20 * i_r + yt2;
            poinsts[1].x = (int)((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);
            poinsts[1].y = (int)((y3 * cp11 + z3 * cp12) / z3);

            //yとtの要素を先に計算
            yt0 = i_base_mat.m01 * i_b + i_base_mat.m03;
            yt1 = i_base_mat.m11 * i_b + i_base_mat.m13;
            yt2 = i_base_mat.m21 * i_b + i_base_mat.m23;

            // r,b
            x3           = m00 * i_r + yt0;
            y3           = m10 * i_r + yt1;
            z3           = m20 * i_r + yt2;
            poinsts[2].x = (int)((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);
            poinsts[2].y = (int)((y3 * cp11 + z3 * cp12) / z3);
            // l,b
            x3           = m00 * i_l + yt0;
            y3           = m10 * i_l + yt1;
            z3           = m20 * i_l + yt2;
            poinsts[3].x = (int)((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);
            poinsts[3].y = (int)((y3 * cp11 + z3 * cp12) / z3);
            return(this.pickFromRaster(i_src_imege, poinsts));
        }
예제 #20
0
        void DrawWord(string word, NyARTransMatResult result)
        {
            NyARD3dUtil.toD3dCameraView(result, 1f, ref this._trans_mat);
            this._surface.CopyFromXRGB32(Core.raster);

            lock (pbxNyAR)
            {
                //Ajustando a escala para cada desenho
                switch (word)
                {
                case "bola":
                    scaling = scaleArray[0];
                    break;

                case "gato":
                    scaling = scaleArray[1];
                    break;

                case "peixe":
                    scaling = scaleArray[2];
                    break;

                case "garfo":
                    scaling = scaleArray[3];
                    break;

                case "leao":
                    scaling = scaleArray[4];
                    break;

                case "caneta":
                    scaling = scaleArray[5];
                    break;

                case "panela":
                    scaling = scaleArray[6];
                    break;

                case "radio":
                    scaling = scaleArray[7];
                    break;

                case "tesoura":
                    scaling = scaleArray[8];
                    break;

                case "faca":
                    scaling = scaleArray[9];
                    break;

                case "espada":
                    scaling = scaleArray[10];
                    break;

                case "mesa":
                    scaling = scaleArray[11];
                    break;
                }

                // Background directly to the surface drawing
                Surface   dest_surface  = this._device.GetBackBuffer(0, 0, BackBufferType.Mono);
                Rectangle src_dest_rect = new Rectangle(0, 0, 543, 348);
                this._device.StretchRectangle(this._surface.d3d_surface, src_dest_rect, dest_surface, src_dest_rect, TextureFilter.None);

                // Drawing 3D objects from here
                this._device.BeginScene();
                this._device.Clear(ClearFlags.ZBuffer, Color.DarkBlue, 1.0f, 0);

                //MATRIZ QUE DEFINE O POSICIONAMENTO DO OBJETO 3D
                //On 20mm cube (top marker) to be shifted
                Matrix transform_mat2 = Matrix.Scaling(scaling, scaling, scaling);
                transform_mat2 *= Matrix.RotationX((float)Math.PI * 1 / 2);

                //Multiply the transformation matrix
                transform_mat2 *= this._trans_mat;
                // Coordinate transformation matrix was calculated
                this._device.SetTransform(TransformType.World, transform_mat2);

                // Rendering (drawing)
                //this._cube.draw(this._device);

                //switch (word)
                //{
                //    case "sapo":
                //        DrawMesh(listSpacemesh[0], listSpacemeshmaterials[0], listSpacemeshtextures[0]);
                //        break;
                //    case "bola":
                //        DrawMesh(listSpacemesh[1], listSpacemeshmaterials[1], listSpacemeshtextures[1]);
                //        break;
                //}

                //Plota a imagem
                switch (word)
                {
                case "bola":
                    DrawMesh(listSpacemesh[0], listSpacemeshmaterials[0], listSpacemeshtextures[0]);
                    break;

                case "gato":
                    DrawMesh(listSpacemesh[1], listSpacemeshmaterials[1], listSpacemeshtextures[1]);
                    break;

                case "peixe":
                    DrawMesh(listSpacemesh[2], listSpacemeshmaterials[2], listSpacemeshtextures[2]);
                    break;

                case "garfo":
                    DrawMesh(listSpacemesh[3], listSpacemeshmaterials[3], listSpacemeshtextures[3]);
                    break;

                case "leao":
                    DrawMesh(listSpacemesh[4], listSpacemeshmaterials[4], listSpacemeshtextures[4]);
                    break;

                case "caneta":
                    DrawMesh(listSpacemesh[5], listSpacemeshmaterials[5], listSpacemeshtextures[5]);
                    break;

                case "panela":
                    DrawMesh(listSpacemesh[6], listSpacemeshmaterials[6], listSpacemeshtextures[6]);
                    break;

                case "radio":
                    DrawMesh(listSpacemesh[7], listSpacemeshmaterials[7], listSpacemeshtextures[7]);
                    break;

                case "tesoura":
                    DrawMesh(listSpacemesh[8], listSpacemeshmaterials[8], listSpacemeshtextures[8]);
                    break;

                case "faca":
                    DrawMesh(listSpacemesh[9], listSpacemeshmaterials[9], listSpacemeshtextures[9]);
                    break;

                case "espada":
                    DrawMesh(listSpacemesh[10], listSpacemeshmaterials[10], listSpacemeshtextures[10]);
                    break;

                case "mesa":
                    DrawMesh(listSpacemesh[11], listSpacemeshmaterials[11], listSpacemeshtextures[11]);
                    break;
                }
                //DrawMesh(spacemesh, spacemeshmaterials, spacemeshtextures);
                //DrawMesh(listSpacemesh[2], listSpacemeshmaterials[2], listSpacemeshtextures[2]);

                // Drawing up here
                this._device.EndScene();

                // Drawing on the actual display
                this._device.Present();
            }
        }
        /**
         * パラメータで変換行列を更新します。
         * 
         * @param i_rot
         * @param i_off
         * @param i_trans
         */
        public void updateMatrixValue(NyARRotMatrix i_rot, NyARDoublePoint3d i_trans, NyARTransMatResult o_result)
        {
            o_result.m00 = i_rot.m00;
            o_result.m01 = i_rot.m01;
            o_result.m02 = i_rot.m02;
            o_result.m03 = i_trans.x;

            o_result.m10 = i_rot.m10;
            o_result.m11 = i_rot.m11;
            o_result.m12 = i_rot.m12;
            o_result.m13 = i_trans.y;

            o_result.m20 = i_rot.m20;
            o_result.m21 = i_rot.m21;
            o_result.m22 = i_rot.m22;
            o_result.m23 = i_trans.z;

            o_result.has_value = true;
            return;
        }