LemonJumps
LemonJumps

Reputation: 49

how come some aruco markers don't get detected on my marker sheet unless I cover a part of it?

I've created a sheet that contains 3 sizes of 6x6 markers, these are all unique and don't overlap. (the idea is to have multiple sizes so that I can move a camera up close and still have at least one small marker in view, as well as have big ones that can be seen from a distance)

I am using default openCV configuration that comes from DetectorParameters() function.

And the problem is that not all markers get detected, as you can see below. enter image description here

Now, the interesting thing is, when I cover the bottom left marker, all of a sudden, the rest of the bottom ones appear. (behold the finger of detection) enter image description here

Covering the rest of the bottom ones makes the top ones appear.

(I'm also aware that r and b are switched, this has no effect on my problem, it happens with Black and white image too)

My question is, can I do something to detect all of them, either settings wise or perhaps generating the sheet differently? I'd prefer If I was able to detect all of them at once so that I can memorize the pattern and don't have to share files between devices.

Also the opencv website makes mention of hamming distance between markers, and it feels like it's related, however I didn't find any explanation of what that actually means.

Here is my code:

in GDextension c++ file:

cv::aruco::Dictionary dict;
cv::aruco::DetectorParameters params;
cv::aruco::ArucoDetector detector;

void aruco_generateDictionary(DictionaryTypes d)
{
    dict = cv::aruco::getPredefinedDictionary(d);
    
    params = cv::aruco::DetectorParameters();
    detector = cv::aruco::ArucoDetector(dict, params);
}

int aruco_detectMarkers(Ref<Image> imgRef)
{
    // ERR_PRINT("test");
    if (!imgRef.is_valid())
    {
        ERR_PRINT("invalid reference");
        return -1;
    }

    detector.detectMarkers(Opencv::g2cvImage(imgRef, imgData), markerCorners, markerIDs);

    return markerIDs.size();
}

and in godot:

func _ready():
    camera.set(CamWrapper.SCAN_PROP_FRAME_WIDTH, 1920)
    camera.set(CamWrapper.SCAN_PROP_FRAME_HEIGHT, 1080)
    
    camera.open(0, CamWrapper.CAP_DSHOW)
    detector.setMaxFeatures(6000)
    scanner.aruco_generateDictionary(Scannur.DICT_6X6_1000)

func _process(delta):
    var img = camera.getImage()
    
    img.convert(Image.FORMAT_L8)
    
    texture = ImageTexture.create_from_image(img)
    
    scanner.aruco_detectMarkers(img)
    
    for m in %PanelContainer2.get_children():
        %PanelContainer2.remove_child(m)
    
    for i in range(scanner.getMarkerCount()):
        #for j in range(4):
        var v = scanner.getCorner(i,0)
        var m = Label.new()
        m.text = " " + str(scanner.getMarker(i))
        m.add_theme_color_override("font_color", Color(1,0,0))
        m.position = v
        m.top_level = true
        %PanelContainer2.add_child(m)

Upvotes: 0

Views: 235

Answers (1)

LemonJumps
LemonJumps

Reputation: 49

As it turns out, the error was never in the detection, and it detected all of them.

The actual problem was godot it self, and how it orders elements, as some of the marker numbers would be displayed under the Image/camera texture.

Me hiding one of the markers caused the other ones to pop out, I'll have to see about better visualisation.

However If anyone stumbles upon this question and perhaps has similar issues or wants to learn about the detection works, or wants to implement their own:

This tutorial describes how aruco detection works in steps: https://docs.opencv.org/4.x/d5/dae/tutorial_aruco_detection.html

And in the square example in opencv repository you will find an example of how the squares them selves are detected: https://github.com/opencv/opencv/blob/4.x/samples/python/squares.py there are similar ones for other languages too in the directory samples.

Upvotes: 0

Related Questions