2016-12-09 18 views
2

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

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

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

Вот уменьшенные фото всей платы:

Marker board

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

Lower-left marker

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

enter image description here

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

Моя функция, которая вызывает 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. 
} 

ответ

2

Исследование из optional detectorParameters argument в 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. 
} 

успеха!

Edges correctly identified