aruco::detectMarkers 没有找到标记的真正边缘

SSt*_*eve 5 opencv aruco

我正在使用 ArUco 标记来校正透视图并计算图像中的大小。在此图像中,我知道标记外边缘之间的确切距离,并使用它来计算黑色矩形的大小。

我的问题是aruco::detectMarkers并不总是识别标记的真实边缘(如细节图像中所示)。当我根据标记的角校正透视时,会导致失真,从而影响图像中对象的大小计算。

有没有办法提高 的边缘检测精度aruco::detectMarkers

这是整个电路板的缩小照片:

记号板

这是左下角标记的详细信息,显示了边缘检测的不准确性:

左下标记

以下是右上角标记的详细信息,显示了对同一标记 ID 的准确边缘检测:

在此处输入图片说明

在这个缩小的图像中很难看到,但左上角的标记准确,右下角的标记不准确。

我的函数调用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.
}
Run Code Online (Sandbox Code Playgroud)

SSt*_*eve 5

检查可选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.
}
Run Code Online (Sandbox Code Playgroud)

成功!

正确识别边缘

  • 请注意,在最新版本的 OpenCV 中,`doCornerRefinement` 消失了,取而代之的是默认为 `CORNER_REFINE_NONE` 的 `cornerRefinementMethod`。我猜`-&gt;cornerRefinementMethod = aruco::CORNER_REFINE_SUBPIX` 是导致与旧的`-&gt;doCornerRefinement = true` 相同行为的值,如本答案所示。 (2认同)