Search code examples
javaopencvaruco

Aruco , Charuco detection with java and opencv


here is my minimal code :

package charucotest;




import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.CvType;
import org.opencv.core.Scalar;

import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.QRCodeDetector;


import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import org.opencv.core.MatOfByte;
import org.opencv.core.Size;



import org.opencv.videoio.VideoCapture;
import java.util.concurrent.*;

import org.opencv.aruco.Aruco;
import org.opencv.aruco.ArucoDetector;
import org.opencv.aruco.DetectorParameters;
import org.opencv.aruco.Dictionary;

import java.util.ArrayList;
import java.util.List;

public class App {


    public static JFrame frame;

    public static String currentpath;


    public static void main(String[] args) {
        currentpath = System.getProperty("user.dir");
        System.out.println("current path is:" + currentpath);
        System.load(currentpath+"/lib/libopencv_java460.so");
        Dictionary dictionary= Aruco.getPredefinedDictionary(Aruco.DICT_4X4_50);
        DetectorParameters parameters= DetectorParameters.create();
        //parameters.set_cornerRefinementMethod(Aruco.CORNER_REFINE_NONE);
        //parameters.set_cornerRefinementMethod();
        ArucoDetector detector= new ArucoDetector(dictionary,parameters);
    
        System.out.println("Welcome to OpenCV " + Core.VERSION);
        List<Mat> corners = new ArrayList<Mat>();
        //List<Mat> rejectedImgPoints = new ArrayList<Mat>();
        Mat ids = new Mat();
        // [12,12]
        Mat img2 = Imgcodecs.imread(currentpath+"/assets/card.jpg");
        detector.detectMarkers(img2, corners, ids);
        System.out.println("OpenCV Mat: " + ids.dump());
        System.out.println("OpenCV size idds  " + ids.size());
        System.out.println("OpenCV Mat Corner: " + String.valueOf(corners.size()));


    } 

}

The opencv lib is loaded, if i had two lines i can decode qrcode so it's working.

But when i try to read my asset card :

enter image description here

It found nothing,

i've verfied the aruco codes seems te be good the 4x4 50 : https://chev.me/arucogen/

So i have no idea why it didn't found the arcuo code.

the test project is here :

https://github.com/bussiere/charucotest/blob/master/app/src/main/java/charucotest/App.java edit : Event with this board :

enter image description here

Or by changing the detection dictionary to 6x6 and with this board (the qrcode detection work fine)

enter image description here


Solution

  • ArUco markers shouldn't be placed directly at the edge of the image. And the markers need a complete and wide black border.

    • If you add some white space around the whole image then the first two markers are detected (id 0 and 1).
    • If you add some black color to the broken frame of the second row of markers then all markers are detected (id 0, 1, 2 and 3).

    Please check this modified input image:

    enter image description here

    Update

    When I run your code above with this image I get the following ouput:

    current path is: <my working dir>
    Welcome to OpenCV 4.6.0
    OpenCV Mat: [2;
     3;
     1;
     0]
    OpenCV size idds  1x4
    OpenCV Mat Corner: 4