给定一些ArUco标记可见的图像,检测过程必须返回检测到的标记列表。 每个检测标记包括:
- 图像中四个角的位置(按原始顺序)。
- 标记的id。
标记检测过程包括两个主要步骤:
- 检测候选标记。在该步骤中,分析图像以找到作为标记的候选的正方形形状。 它首先进行自适应阈值处理以对标记进行分割,然后从阈值图像中提取轮廓,并丢弃那些非凸起或不接近正方形的轮廓。 还应用了一些额外的过滤(去除太小或太大的轮廓,去除彼此太近的轮廓等)。
- 在候选检测之后,有必要通过分析它们的内部编码来确定它们是否实际上是标记。 此步骤首先提取每个标记的标记位。 为此,首先,应用透视变换以获得其规范形式的标记。 然后,使用Otsu对规范图像进行阈值处理以分离白色和黑色位。 根据标记大小和边界大小将图像分成不同的单元格,并计算每个单元格上的黑色或白色像素的数量,以确定它是白色还是黑色位。 最后,分析比特以确定标记是否属于特定字典,并且在必要时采用纠错技术。
在aruco模块中,检测在detectMarkers()
函数中执行。 此功能在模块中是最重要的,因为所有其余功能都基于detectMarkers()
返回的先前检测到的标记。
cv::Mat inputImage;
...
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f>> markerCorners, rejectedCandidates;
cv::Ptr<cv::aruco::DetectorParameters> parameters;
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::detectMarkers(inputImage, dictionary, markerCorners, markerIds, parameters, rejectedCandidates);
detectMarkers
的参数是:
- 第一个参数是将要检测标记的图像。
- 第二个参数是字典对象,在这种情况下是一个预定义的字典(
DICT_6X6_250
)。 - 检测到的标记存储在
markerCorners
和markerIds
结构中:markerCorners
是检测到的标记的角点列表。 对于每个标记,其四个角以其原始顺序返回(从左上角开始顺时针)。 因此,第一个角是左上角,然后是右上角,右下角和左下角。markerIds
是markerIds
中每个检测到的标记的id列表。 请注意,返回的markerCorners
和markerIds
向量具有相同的大小。
- 第四个参数是
DetectionParameters
类型的对象。 此对象包括可在检测过程中自定义的所有参数。 这些参数将在下一节中详细说明。 - 最终参数
rejectedCandidates
是一个返回的标记候选列表,即已找到的那些方格,但它们不提供有效的编码。 每个候选者也由其四个角定义,其格式与markerCorners
参数相同。 此参数可以省略,仅用于调试目的和“refind”策略(请参阅refineDetectedMarkers()
)。
在detectMarkers()
检查您的标记是否已被正确检测之后,aruco模块提供了一个在输入图像中绘制检测到的标记的功能,这个功能是drawDetectedMarkers()
。 例如:
cv::Mat outputImage
cv::aruco::drawDetectedMarkers(image, markerCorners, markerIds);
image
是输入/输出图像,其中将绘制标记(它通常与检测到标记的图像相同)。markerCorners
和markerIds
是detectMarkers()
函数提供的相同格式的检测到的标记的结构。
测试示例: