Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect markers with N bits resolution #56

Open
GuillaumeHauss opened this issue Jun 12, 2018 · 1 comment
Open

Detect markers with N bits resolution #56

GuillaumeHauss opened this issue Jun 12, 2018 · 1 comment

Comments

@GuillaumeHauss
Copy link

Hi all,

As mentioned in my previous issue, I'm looking to adapt the Aruco Detector to make it able to detect and identify markers with N-bits resolution, N in [4; 7].
So far, the bit resolution is hardcoded in the function detect in the file arucofidmarkers.cpp, as shown in the following snippet of code

int FiducidalMarkers::analyzeMarkerImage(Mat &grey,int &nRotations)
  {

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

    int swidth=grey.rows/7;
    for (int y=0;y<7;y++)
    {
      int inc=6;
      if (y==0 || y==6) inc=1;//for first and last row, check the whole border
      for (int x=0;x<7;x+=inc)
      {
        int Xstart=(x)*(swidth);
        int Ystart=(y)*(swidth);
        Mat square=grey(Rect(Xstart,Ystart,swidth,swidth));
        int nZ=countNonZero(square);
        if (nZ> (swidth*swidth) /2) {
          // 		cout<<"neb"<<endl;
          return -1;//can not be a marker because the border element is not black!
        }
      }
    }

    //now,
    vector<int> markerInfo(5);
    Mat _bits=Mat::zeros(5,5,CV_8UC1);
    //get information(for each inner square, determine if it is  black or white)

    for (int y=0;y<5;y++)
    {

      for (int x=0;x<5;x++)
      {
        int Xstart=(x+1)*(swidth);
        int Ystart=(y+1)*(swidth);
        Mat square=grey(Rect(Xstart,Ystart,swidth,swidth));
        int nZ=countNonZero(square);
        if (nZ> (swidth*swidth) /2)  _bits.at<uchar>( y,x)=1;
      }
    }
    // 		printMat<uchar>( _bits,"or mat");

    //checkl all possible rotations
    Mat _bitsFlip;
    Mat Rotations[4];
    Rotations[0]=_bits;
    int dists[4];
    dists[0]=hammDistMarker( Rotations[0]) ;
    pair<int,int> minDist( dists[0],0);
    for (int i=1;i<4;i++)
    {
      //rotate
      Rotations[i]=rotate(Rotations[i-1]);
      //get the hamming distance to the nearest possible word
      dists[i]=hammDistMarker( Rotations[i]) ;
      if (dists[i]<minDist.first)
      {
        minDist.first=  dists[i];
        minDist.second=i;
      }
    }
    // 		        printMat<uchar>( Rotations [ minDist.second]);
    // 		 	cout<<"MinDist="<<minDist.first<<" "<<minDist.second<<endl;

    nRotations=minDist.second;
    if (minDist.first!=0)	 //FUTURE WORK: correct if any error
      return -1;
    else {//Get id of the marker
      int MatID=0;
      cv::Mat bits=Rotations [ minDist.second];
      for (int y=0;y<5;y++)
      {
        MatID<<=1;
        if ( bits.at<uchar>(y,1)) MatID|=1;
        MatID<<=1;
        if ( bits.at<uchar>(y,3)) MatID|=1;
      }
      return MatID;
    }
  }

My initial guess was to change every 7 in N, every 6 in N-1 and every 5 in N-2, after adding N as a parameter of the function.
But this wasn't working. Does anyone has a better approach in mind?

I'll keep digging and keep you posted if I find a workaround :)

Thank you very much for your help

@GuillaumeHauss
Copy link
Author

Well, it seems that this function is handling the major magic step to get the ID of the marker

int FiducidalMarkers::hammDistMarker(Mat  bits)

in the same arucodifmarker.cpp file.
Now, there is some kind of mask set in the function, that has explicitly 5 columns, used in the computation of the Hammind distance. After some digging in the opencv library, I found this file which houses the function

int normHamming(const uchar* a, int n, int cellSize)

It also uses some predefined tables, but I cannot understand their origin.
Do someone has a thought on that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant