aruco:: detectMarkers не находит истинных краев маркеров


Я использую маркеры ArUco для коррекции перспективы и вычисления размеров изображения. На этом изображении я знаю точное расстояние между внешними краями маркеров и использую его для вычисления размеров черных прямоугольников.

Моя проблема заключается в том, что aruco::detectMarkers не всегда идентифицирует истинные края маркеров (как показано на детальном изображении). Когда я корректирую перспективу на основе углов маркеров, это вызывает искажение, которое влияет на вычисления размеров объектов в пространстве. изображение.

Есть ли способ повысить точность обнаружения краев aruco::detectMarkers?

Вот уменьшенная фотография всей доски:

Маркерная доска

Вот деталь нижнего левого маркера, показывающая неточность обнаружения края:

Нижний левый маркер

Вот деталь верхнего правого маркера, показывающая точное обнаружение края того же идентификатора маркера:

Введите описание изображения здесь

Это трудно увидеть в этом уменьшенном изображении. но верхний левый маркер точен, а нижний правый маркер неточен.

Моя функция, которая вызывает detectMarkers:

bool findMarkers(const Mat image, Point2d outerMarkerCoordinates[], Point2d innerMarkerCoordinates[], Size2d *boardSize) {
    Ptr<aruco::Dictionary> theDictionary = aruco::getPredefinedDictionary(aruco::DICT_4X4_1000);
    vector<vector<Point2f> > markers;
    vector<int> ids;

    aruco::detectMarkers(image, theDictionary, markers, ids);

    aruco::drawDetectedMarkers(image, markers, ids);

    return true; //There's actually more code here that makes sure there are four markers.
}
1 4

1 ответ:

Проверка необязательногоdetectorParameters аргумента к detectMarkers показала параметр под названием doCornerRefinement. Его описание - "делать субпиксельное уточнение или нет". Поскольку ошибка, которую я вижу, больше пикселя, я не думал, что это применимо к моей ситуации. Я все равно попробовал и экспериментировал со значением cornerRefinementWinSize и обнаружил, что это действительно решает мою проблему. Теперь я думаю, что "пиксель" в смысле ArUco-это размер одного из квадратов внутри маркера, а не изображения пиксель.

Модифицированный вызов detectMarkers:

bool findMarkers(const Mat image, Point2d outerMarkerCoordinates[], Point2d innerMarkerCoordinates[], Size2d *boardSize) {
    Ptr<aruco::Dictionary> theDictionary = aruco::getPredefinedDictionary(aruco::DICT_4X4_1000);
    vector<vector<Point2f> > markers;
    vector<int> ids;
    Ptr<aruco::DetectorParameters> detectorParameters = new aruco::DetectorParameters;

    detectorParameters->doCornerRefinement = true;
    detectorParameters->cornerRefinementWinSize = 11;       

    aruco::detectMarkers(image, theDictionary, markers, ids, detectorParameters);

    aruco::drawDetectedMarkers(image, markers, ids);

    return true; //There's actually more code here that makes sure there are four markers.
}

Успех!

Края правильно определил