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

Aruco custom dictionary #3133

Closed
ekkelenkamp opened this issue Dec 16, 2021 · 4 comments
Closed

Aruco custom dictionary #3133

ekkelenkamp opened this issue Dec 16, 2021 · 4 comments

Comments

@ekkelenkamp
Copy link

System information (version)
  • OpenCV => 4.4.3
  • Operating System / Platform => Windows 64 Bit, Java binding
  • Compiler => Visual Studio 2019
Detailed description

I'm trying to create an Aruco custom dictionary using the java binding. When drawing the image, it doesn't match the configured marker. I cannot find any examples on how to do this in java.

I configured a marker like:
011
111
011

But I get as result:

011
110
010

Steps to reproduce

Here a simple test case:

  
    @Test
    public void testGithub() {
        byte[][] marker = {{0,1,1},{1,1,1},{0,1,1}};
        Dictionary dictionary = Dictionary.create(1, 3);
        dictionary.set_maxCorrectionBits(0);
        Mat markerBits = new Mat(3, 3, CV_8UC1);
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                markerBits.put(i, j, marker[i][j]);
            }
        }
        Mat markerCompressed = Dictionary.getByteListFromBits(markerBits);
        dictionary.get_bytesList().push_back(markerCompressed);
        Mat markerMat = new Mat(3, 3, CV_8UC1);
        Aruco.drawMarker(dictionary, 0, 9, markerMat);
        Imgcodecs.imwrite("c:/temp/marker0.jpg", markerMat);
    }

Resulting marker is attached.

marker0

@ekkelenkamp
Copy link
Author

What i noted is that the dictionary.get_bytesList() is already filled with a random marker directly after the Dictionary has been created. This results in adding a new marker not being updated.
This differs from the c++ implementation. I use similar code from ios and there it works just fine. For example:

   unsigned char data[3][3] = { {0,1,0},{0,1,1},{1,1,0} };
    cv::Mat markerBits = cv::Mat(3, 3, CV_8UC1, data);
    cv::Mat markerCompressed = cv::aruco::Dictionary::getByteListFromBits(markerBits);
    dictionary->bytesList.push_back(markerCompressed);

So I probably can change the values in the already configured dictonary entries, but it looks like a bug to me in the java binding.

@ekkelenkamp
Copy link
Author

I can confirm that overwriting the values of the existing dictionary is working. Here the testcase that fixes this issue.

    @Test
    public void testGithub() {
        char[][] marker = {{0,1,1},{1,1,1},{0,1,1}};
        Dictionary dictionary = Dictionary.create(1, 3);
        dictionary.set_maxCorrectionBits(0);
        Mat markerBits = new Mat(3, 3, CV_8UC1);
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                markerBits.put(j, i, marker[j][i]);
            }
        }
        Mat markerCompressed = Dictionary.getByteListFromBits(markerBits);
        Mat dictionaryMat = dictionary.get_bytesList();
        int markerId = 0;
        for (int i = 0; i < 2; i++) {
            double[] markerValues = markerCompressed.get(0, i);
            byte[] b = new byte[4];
            for (int m = 0; m < markerValues.length; m++) {
                b[m] = (byte) markerValues[m];
            }
            dictionaryMat.put(markerId, i, b);
        }
        Mat markerMat = new Mat(3, 3, CV_8UC1);
        Aruco.drawMarker(dictionary, 0, 9, markerMat);
        Imgcodecs.imwrite("/tmp/aruco/marker0.jpg", markerMat);
    }

Now the generated marker is as expected.

marker0

@AleksandrPanov
Copy link
Contributor

related: #3200

@AleksandrPanov
Copy link
Contributor

@ekkelenkamp Dictionary.create() call generateCustomDictionary() inside.
use set_bytesList() to change bytesList:

        byte[][] marker = {{0,1,1},{1,1,1},{0,1,1}};
        Dictionary dictionary = Dictionary.create(1, 3);
        dictionary.set_maxCorrectionBits(0);
        Mat markerBits = new Mat(3, 3, CvType.CV_8UC1);
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                markerBits.put(i, j, marker[i][j]);
            }
        }
        Mat markerCompressed = Dictionary.getByteListFromBits(markerBits);
        dictionary.set_bytesList(markerCompressed);

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

No branches or pull requests

3 participants