Etantonio
Etantonio

Reputation: 359

Tune of aruco detection parameters on marker identification

I've two photo really similar this one is recognized correctly as marker 209 of a 5x5_250 dictionary

marker 209 recognized by Aruco

while this other really similar it is not recognized, it is the marker 207 of the same 5x5_250 dictionary:

marker 207 NOT recognized by Aruco

and also the marker 207 is instead recognized in this other photo:

marker 207 recognized

I've tried changing something in the detector parameters

params->adaptiveThreshWinSizeMin = 4;
params->adaptiveThreshWinSizeMax = 26;
params->adaptiveThreshWinSizeStep = 2;
params->minMarkerPerimeterRate = 0.01;
params->maxMarkerPerimeterRate = 4;
params->polygonalApproxAccuracyRate = 0.1;
params->perspectiveRemovePixelPerCell = 10;

but it seems nothing change so I turn back to the default values, so my question is:

  1. it is necessary a white border surrounding the marker?
  2. why the marker 207 is not recognized in the second photo? Thanks

Upvotes: 3

Views: 5238

Answers (1)

John
John

Reputation: 555

The white border around the ArUco marker is necessary because the first step of ArUco marker detection is the detection of corners. For reference, see page 4 of the documentation of the ArUco library.

Unfortunately, cutting off the so-called "quiet region" around markers is a common problem. In the future, it might help to print the markers with additional corners like so:

ArUco marker with corners

To generate the corners, run this snippet and drag & drop an image where it says to do so. Then right click and "Save Image As...".

var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var theImage = null;

function redraw(){
    if (!theImage){
        context.font = "30px Arial";
        context.fillStyle = "black";
        context.fillText("Drag & Drop image here.", 10, 40);
        return;
    }
    
    var width = theImage.width;
    var height = theImage.height;
    
    var nTiles = 8;
    var padding = 3;
    var cornerLength = 4;
    var dx = width / nTiles;
    var dy = height / nTiles;
    
    canvas.width = 2 * padding * dx + width;
    canvas.height = 2 * padding * dy + height;
    
    // clear background
    context.fillStyle = "#ffffff";
    context.fillRect(0, 0, canvas.width, canvas.height);
    
    // draw corners
    context.fillStyle = "#000000";
    context.fillRect(0, 0, dx, dy * cornerLength);
    context.fillRect(0, 0, cornerLength * dx, dy);
    context.fillRect(canvas.width - dx, canvas.height - dy * cornerLength, dx, dy * cornerLength);
    context.fillRect(canvas.width - cornerLength * dx, canvas.height - dy, cornerLength * dx, dy);
    context.fillRect(canvas.width - dx, 0, dx, dy * cornerLength);
    context.fillRect(canvas.width - cornerLength * dx, 0, dx * cornerLength, dy);
    context.fillRect(0, canvas.height - dy * cornerLength, dx, dy * cornerLength);
    context.fillRect(0, canvas.height - dy, cornerLength * dx, dy);
    
    // draw image
    context.drawImage(theImage, padding * dx, padding * dy);
}

redraw();

function handleFile(file){
    var reader = new FileReader();
    reader.onload = function(){
        var image = new Image();
        image.src = this.result;
        image.onload = function(){
            theImage = image;
            redraw();
        }
    }
    reader.readAsDataURL(file);
}

canvas.addEventListener("dragover", function(e){
    e.preventDefault()
    e.stopPropagation()
})

canvas.addEventListener("drop", function(e){
    var files = e.dataTransfer.files;
    for (var i = 0; i < files.length; i++){
        handleFile(files[i]);
    }
    e.preventDefault()
    e.stopPropagation()
})
<canvas id="myCanvas" width="512" height="512"></canvas>

Upvotes: 6

Related Questions