赞
踩
这个函数写在aruco.cpp里。
detectMarkers()
_detectCandidates()
_detectInitialCandidates() //预处理,利用目标的凸性检测出四边形集合
_detectCandidates() //检测正方形候选框
_reorderCandidatesCorners() //确保候选角的顺序为顺时针方向
_filterTooCloseCandidates() //检查那些离得太近的候选框,保留那些潜在的候选框
_extractBits() //提取角点(输入侯选角)
_findMarkerContours() // L.131 ,轮廓检测
detectMarkers() // L.1120
创建多个并行检测管道:
threshold()
和findMarkerContours()
分别进行二值化操作
及轮廓检测
,在_detectInitialCandidates()被调用。二值化操作调用opencv:adaptiveThreshold()函数
在得到二值化窗口之后,利用findContours(contoursImg, contours, RETR_LIST, CHAIN_APPROX_NONE);查找这个二值化图的所有轮廓,每个轮廓存在contours里面。下面对每一个轮廓进行如下的一个过程:
_identifyCandidates()
_identifyOneCandidate() //L.567,确认候选框是否是有效
class IdentifyCandidatesParallell
correctCornerPosition() // L.695,将角的位置转换为正确的旋转位置
_extractBits() //给定一幅输入图像和候选角,提取候选角的位,包括边界位
getPerspectiveTransform()
_getBorderErrors()
_identifyOneCandidate() //L.567,确认候选框是否是有效,此处返回一个typ:
typ:
0 if the candidate is not valid,
1 if the candidate is a black candidate (default candidate)
2 if the candidate is a white candidate
调用_extractBits():
getPerspectiveTransform
和warpPerspective
进行透视变换,透视变换的目标为方形,其边长为perspectiveRemovePixelPerCell * 码标的比特边长meanStdDev
计算区域的均值和方差,如果方差小于minOtsuStdDev,说明是全黑或全白,如果均值大于127,则认为是全白,否则全黑threshold(resultImg, resultImg, 125, 255, THRESH_BINARY | THRESH_OTSU)
,二值化阈值使用大津法,二值化方式THRESH_BINARY 与上述THRESH_BINARY_INV作用相反countNonZero
统计比特块的非0个数,如果非0个数超过图像一般,则认为这个块是白色,否则是黑色,最后将这个码标用一个8*8的bits矩阵存储调用_getBorderErrors():
int _getBorderErrors(const Mat &bits, int markerSize, int borderSize)
统计边界黑色的个数,如果错误块个数大于编码块总数*maxErroneousBitsInBorderRate,则认为边界错误,导致编码错误dictionary->identify:
dictionary->identify(onlyBits, idx, rotation, params->errorCorrectionRate)
进行解码,解码失败就说明这个不是目标,解码成功,并返回一个值,来确定哪个角点是左上第一个角点。
IdentifyCandidatesParallell类,对每一个candidate进行一次_identifyOneCandidate()操作
前面步骤检测出的角点都是像素级的,用于后续位姿估计时候可能会有误差,因此检测出角点之后,需要对其进行细化,得到亚像素角点,细化方法有两种,分别为:角点细化(CORNER_REFINE_SUBPIX)和拟合直线细化(CORNER_REFINE_CONTOUR)。细化方法的选择,指定参数cornerRefinementMethod即可,算法默认是不细化的。
opencv自带函数cv::cornerSubPix()
可将像素级角点细化为亚像素,其中涉及到三个参数,cornerRefinementWinSize细化窗口大小,cornerRefinementMaxIterations细化最大迭代数,cornerRefinementMinAccuracy细化误差。
对4边形的每个边进行拟合,然后利用拟合直线的交点作为最终细化的角点。
如果相机有畸变,利用undistortPoints
对四边形像素点进行校正。
提取两个角点之间的像素集,也就是4边形的每个边
对每个边进行直线拟合
计算交点
最终的交点就作为亚像素角点。
部分内容参考:OpenCV Aruco 参数源码完整解析理解!(转载)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。