Beispiel #1
0
        /// <summary>
        /// Gets the marker identifier.
        /// </summary>
        /// <returns>The marker identifier.</returns>
        /// <param name="markerImage">Marker image.</param>
        /// <param name="nRotations">N rotations.</param>
        public static int getMarkerId(Mat markerImage, MatOfInt nRotations, byte[,] markerDesign)
        {
            Mat grey = markerImage;

            // Threshold image
            Imgproc.threshold(grey, grey, 125, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);


            //Markers  are divided in 7x7 regions, of which the inner 5x5 belongs to marker info
            //the external border should be entirely black

            int size = markerDesign.GetLength(0);

            int cellSize = markerImage.rows() / (size + 2);

            for (int y = 0; y < (size + 2); y++)
            {
                int inc = size + 1;

                if (y == 0 || y == (size + 1))
                {
                    inc = 1; //for first and last row, check the whole border
                }
                for (int x = 0; x < (size + 2); x += inc)
                {
                    int cellX = x * cellSize;
                    int cellY = y * cellSize;
                    Mat cell  = new Mat(grey, new OpenCVForUnity.CoreModule.Rect(cellX, cellY, cellSize, cellSize));


                    int nZ = Core.countNonZero(cell);

                    cell.Dispose();

                    if (nZ > (cellSize * cellSize) / 2)
                    {
                        return(-1);//can not be a marker because the border element is not black!
                    }
                }
            }

            Mat bitMatrix = Mat.zeros(size, size, CvType.CV_8UC1);

            //get information(for each inner square, determine if it is  black or white)
            for (int y = 0; y < size; y++)
            {
                for (int x = 0; x < size; x++)
                {
                    int cellX = (x + 1) * cellSize;
                    int cellY = (y + 1) * cellSize;
                    Mat cell  = new Mat(grey, new OpenCVForUnity.CoreModule.Rect(cellX, cellY, cellSize, cellSize));

                    int nZ = Core.countNonZero(cell);

                    if (nZ > (cellSize * cellSize) / 2)
                    {
                        bitMatrix.put(y, x, new byte[] { 1 });
                    }

                    cell.Dispose();
                }
            }

            //check all possible rotations
            Mat[] rotations = new Mat[4];
            for (int i = 0; i < rotations.Length; i++)
            {
                rotations[i] = new Mat();
            }
            int[] distances = new int[4];


            rotations[0] = bitMatrix;
            distances[0] = hammDistMarker(rotations[0], markerDesign);


            int first  = distances[0];
            int second = 0;

            for (int i = 1; i < 4; i++)
            {
                //get the hamming distance to the nearest possible word
                rotations[i] = rotate(rotations[i - 1]);
                distances[i] = hammDistMarker(rotations[i], markerDesign);

                if (distances[i] < first)
                {
                    first  = distances[i];
                    second = i;
                }
            }

            nRotations.fromArray(second);
            if (first == 0)
            {
                int id = mat2id(rotations[second]);


                bitMatrix.Dispose();
                for (int i = 0; i < rotations.Length; i++)
                {
                    rotations[i].Dispose();
                }

                return(id);
            }

            return(-1);
        }
Beispiel #2
0
		/// <summary>
		/// Gets the marker identifier.
		/// </summary>
		/// <returns>The marker identifier.</returns>
		/// <param name="markerImage">Marker image.</param>
		/// <param name="nRotations">N rotations.</param>
		public static int getMarkerId (Mat markerImage, MatOfInt nRotations, byte[,] markerDesign)
		{

		
				Mat grey = markerImage;
		
				// Threshold image
				Imgproc.threshold (grey, grey, 125, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);

		
				//Markers  are divided in 7x7 regions, of which the inner 5x5 belongs to marker info
				//the external border should be entirely black

				int size = markerDesign.GetLength(0);
		
				int cellSize = markerImage.rows () / (size + 2);
		
				for (int y=0; y<(size+2); y++) {
						int inc = size + 1;
			
						if (y == 0 || y == (size + 1))
								inc = 1; //for first and last row, check the whole border
			
						for (int x=0; x<(size+2); x+=inc) {
								int cellX = x * cellSize;
								int cellY = y * cellSize;
								Mat cell = new Mat (grey, new OpenCVForUnity.Rect (cellX, cellY, cellSize, cellSize));

				
								int nZ = Core.countNonZero (cell);

								cell.Dispose ();
				
								if (nZ > (cellSize * cellSize) / 2) {
										return -1;//can not be a marker because the border element is not black!
								}
						}
				}

				Mat bitMatrix = Mat.zeros (size, size, CvType.CV_8UC1);
		
				//get information(for each inner square, determine if it is  black or white)  
				for (int y=0; y<size; y++) {
						for (int x=0; x<size; x++) {
								int cellX = (x + 1) * cellSize;
								int cellY = (y + 1) * cellSize;
								Mat cell = new Mat (grey, new OpenCVForUnity.Rect (cellX, cellY, cellSize, cellSize));
				
								int nZ = Core.countNonZero (cell);

								if (nZ > (cellSize * cellSize) / 2)
										bitMatrix.put (y, x, new byte[]{1});
								//bitMatrix.at<uchar> (y, x) = 1;

								cell.Dispose ();
						}
				}

//		Debug.Log ("bitMatrix " + bitMatrix.dump());
		
				//check all possible rotations
				Mat[] rotations = new Mat[4];
				for (int i = 0; i < rotations.Length; i++) {
						rotations [i] = new Mat ();
				}
				int[] distances = new int[4];
				
		
				rotations [0] = bitMatrix;  
				distances [0] = hammDistMarker (rotations [0], markerDesign);



				int first = distances [0];
				int second = 0;
		
				for (int i=1; i<4; i++) {
						//get the hamming distance to the nearest possible word
						rotations [i] = rotate (rotations [i - 1]);
						distances [i] = hammDistMarker (rotations [i], markerDesign);
			
						if (distances [i] < first) {
								first = distances [i];
								second = i;
						}
				}

//		Debug.Log ("first " + first);

				nRotations.fromArray (second);
				if (first == 0) {
						int id = mat2id (rotations [second]);


						bitMatrix.Dispose ();
						for (int i = 0; i < rotations.Length; i++) {
								rotations [i].Dispose ();
						}

						return id;
				}
		
				return -1;
		}