【计算机视觉】 相机姿态估计之标记检测-检测ChArUco角点3
来源:互联网 发布:php过滤所有的空格 编辑:程序博客网 时间:2024/05/17 23:20
检测ChArUco角点
来源OpenCV
http://docs.opencv.org/master/df/d4a/tutorial_charuco_detection.html
这张图片:
结果将是:
在闭塞的存在。 像下面的图片,虽然有些角落清晰可见,并不是所有周围的标记已发现由于阻塞,因此,他们不是插值:
2 原理介绍
ArUco标记和板非常有用因为他们的快速检测和多功能性。 然而,ArUco标记的问题之一是,角落的位置的准确性不是太高,即使应用亚像素细分。
相反,棋盘模式的角落可以更准确地提炼因为每个角落周围是两个黑色方块。 然而,找到一个棋盘模式不像找到一个通用的ArUco板:它必须是完全可见,遮挡不允许。
ChArUco板试图结合这两种方式的好处:
ArUco部分用于插入棋盘角落的位置,这样它的多功能性标记板,因为它允许遮挡或部分视图。 此外,由于插值角落属于一个棋盘,他们非常准确的亚像素精度。
当精度高是必要的,比如在相机标定,Charuco板是一个更好的选择比标准Aruco板。
ChArUco板创造
aruco模块提供了 简历:aruco::CharucoBoard
类代表一个Charuco板和继承的 板
类。
ChArUco余下的功能,这个类中定义:
定义一个 CharucoBoard
,它是必要的:
- 在X方向上棋盘方格的数量。
- 棋盘方格的数量在Y方向上。
- 广场边的长度。
- 标记的长度。
- 字典的标记。
- id的所有标记。
至于 GridBoard
对象,aruco模块提供了一个函数来创建 CharucoBoard
很容易。 这个函数是静态函数 cv::aruco::CharucoBoard::create()
:
- 第一和第二参数是方块的数量分别在X和Y方向。
- 第三个和第四个参数分别广场和标记的长度。 他们可以在任何单位提供,记住,估计姿势这个委员会将以相同的单位(通常是使用米)。
- 最后,提供了标记的字典。
每一个标记的id分配默认按升序,从0开始,喜欢 GridBoard:create()
。 这可以很容易地定制的访问id向量通过 board.ids
,就像在 板
父类。
一旦我们有 CharucoBoard
对象,我们可以创建一个图像打印它。 这可以完成了
{CharucoBoard::draw()```}``` c++ cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(5, 7, 0.04, 0.02, dictionary); cv::Mat boardImage; board->draw( cv::Size(600, 500), boardImage, 10, 1 );
- 第一个参数是输出图像的像素大小。 在这种情况下600 x500像素。 如果这不是板规模成正比,它将以图像为中心。
boardImage
:输出图像。- 第三个参数(可选)边缘的像素,所以所有的标记都触碰图像边界。 在这种情况下,保证是10。
- 最后,标记边界的大小,类似
drawMarker()
函数。 默认值是1。
输出图像将是这样的:
一个完整的工作包含在示例 create_board_charuco.cpp
模块内的样本文件夹。
注意:样品现在通过命令行通过输入 OpenCV命令行解析器 。 这个文件的示例参数
ChArUco板检测
当你检测ChArUco板,你实际上是检测是棋盘上的每一个角落。
上的每一个角落ChArUco板都有一个唯一的标识符(id)。 这些id从0到角落的总数。
所以,发现ChArUco板包括:
std::vector<cv::Point2f> charucoCorners
: list of image positions of the detected corners.std::vector<int> charucoIds
: ids for each of the detected corners incharucoCorners
.
ChArUco角落的检测是基于前面的检测标记。 因此,首先检测到标记,然后ChArUco角落从标记插入。
的功能检测ChArUco角落 CV::aruco::interpolateCornersCharuco()
。 这个例子展示了整个过程。 首先,检测到标记,然后ChArUco角落从这些标记将被内插。
cv::Mat inputImage;cv::Mat cameraMatrix, distCoeffs;// camera parameters are read from somewherereadCameraParameters(cameraMatrix, distCoeffs);cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(5, 7, 0.04, 0.02, dictionary);...std::vector<int> markerIds;std::vector<std::vector<cv::Point2f>> markerCorners;cv::aruco::detectMarkers(inputImage, board.dictionary, markerCorners, markerIds);// if at least one marker detectedif(markerIds.size() > 0) { std::vector<cv::Point2f> charucoCorners; std::vector<int> charucoIds; cv::aruco::interpolateCornersCharuco(markerCorners, markerIds, inputImage, board, charucoCorners, charucoIds, cameraMatrix, distCoeffs);}
的参数 interpolateCornersCharuco()
函数是:
markerCorners
和markerIds
:检测到标记detectMarkers()
函数。inputImage
:标记检测的原始图像。 执行所需的图像亚像素细分ChArUco角落。板
:CharucoBoard
对象charucoCorners
和charucoIds
:输出插入Charuco角落cameraMatrix
和distCoeffs
:可选相机标定参数- 插值函数返回的数量Charuco角落。
在这种情况下,我们有电话 interpolateCornersCharuco()
提供摄像机标定参数。 然而这些参数是可选的。 没有这些参数类似的例子是:
cv::Mat inputImage;cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(5, 7, 0.04, 0.02, dictionary);...std::vector<int> markerIds;std::vector<std::vector<cv::Point2f>> markerCorners;cv::Ptr<cv::aruco::DetectorParameters> params;params->cornerRefinementMethod = cv::aruco::CORNER_REFINE_NONE;cv::aruco::detectMarkers(inputImage, board.dictionary, markerCorners, markerIds, params);// if at least one marker detectedif(markerIds.size() > 0) { std::vector<cv::Point2f> charucoCorners; std::vector<int> charucoIds; cv::aruco::interpolateCornersCharuco(markerCorners, markerIds, inputImage, board, charucoCorners, charucoIds);}
如果校准参数提供,ChArUco角落内插,首先,估计ArUco标记和一个粗略的姿势,然后,reprojecting ChArUco角落回到形象。
另一方面,如果不提供校准参数,ChArUco角落被计算相应的插值ChArUco平面和ChArUco图像之间的单应性投影。
使用单应性的主要问题是,插值更明智的图像失真。 实际上,单应性只使用最接近的执行标记每个ChArUco角落减少失真的影响。
当检测标记ChArUco板特别是当使用单应性,建议禁用标志的角落细化。 这个的原因是,由于接近棋盘的广场,构造过程可以产生重要的在角落位置偏差,这些偏差传播到插值ChArUco角落,产生不良的结果。
此外,只有那些角落里的两个周围标记返回。 如果任何周围的两个标记没有被检测到,这通常意味着有阻塞或区域的图像质量不好。 在任何情况下,最好不要考虑到角落里,因为我们想要确保插值ChArUco角落非常准确。
ChArUco角落已经插入后,进行亚像素细分。
一旦我们有插值ChArUco角落,我们可能会想画,看看他们的检测是正确的。 这可以很容易地使用完成 drawDetectedCornersCharuco()
功能:
图像
是将图像的角落(它将通常是相同的图像的角落发现了)。- 的
outputImage
将是一个克隆的inputImage
的角落。 charucoCorners
和charucoIds
的发现Charuco角落吗interpolateCornersCharuco()
函数。- 最后,最后一个参数(可选)的颜色我们要画的角落,类型的
简历:标量
。
这张图片:
结果将是:
在闭塞的存在。 像下面的图片,虽然有些角落清晰可见,并不是所有周围的标记已发现由于阻塞,因此,他们不是插值:
最后,这是一个完整的示例ChArUco检测(不使用校准参数):
cv::VideoCapture inputVideo;inputVideo.open(0);cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(5, 7, 0.04, 0.02, dictionary);cv::Ptr<cv::aruco::DetectorParameters> params;params->cornerRefinementMethod = cv::aruco::CORNER_REFINE_NONE;while (inputVideo.grab()) { cv::Mat image, imageCopy; inputVideo.retrieve(image); image.copyTo(imageCopy); std::vector<int> ids; std::vector<std::vector<cv::Point2f>> corners; cv::aruco::detectMarkers(image, dictionary, corners, ids, params); // if at least one marker detected if (ids.size() > 0) { cv::aruco::drawDetectedMarkers(imageCopy, corners, ids); std::vector<cv::Point2f> charucoCorners; std::vector<int> charucoIds; cv::aruco::interpolateCornersCharuco(corners, ids, image, board, charucoCorners, charucoIds); // if at least one charuco corner detected if(charucoIds.size() > 0) cv::aruco::drawDetectedCornersCharuco(imageCopy, charucoCorners, charucoIds, cv::Scalar(255, 0, 0)); } cv::imshow("out", imageCopy); char key = (char) cv::waitKey(waitTime); if (key == 27) break;}
一个完整的工作包含在示例 detect_board_charuco.cpp
模块内的样本文件夹。
注意:样品现在通过命令行通过输入 OpenCV命令行解析器 。 这个文件的示例参数
ChArUco姿势估计
ChArUco板的最终目标是找到角落非常准确地高精度校准或估计。
aruco模块提供了一个函数来执行ChArUco姿势容易估计。 就像在 GridBoard
的坐标系统 CharucoBoard
被放置在板平面与Z轴指出,集中在板的左下角。
造成估计的函数 estimatePoseCharucoBoard()
:
- 的
charucoCorners
和charucoIds
参数的检测从charuco角落interpolateCornersCharuco()
函数。 - 第三个参数是
CharucoBoard
对象。 - 的
cameraMatrix
和distCoeffs
摄像机标定参数为姿势估计是必要的。 - 最后,
rvec
和tvec
参数输出Charuco板的构成。 - 函数返回true,如果姿势是正确估计和错误的。 失败的主要原因是没有足够的角落姿势估计或他们在同一条线上。
轴可以用 drawAxis()
检查姿势正确估计。 结果是:(X:红Y:绿色,Z:蓝色)
一个完整的例子与姿势估计ChArUco检测:
一个完整的工作包含在示例 detect_board_charuco.cpp
模块内的样本文件夹。
注意:样品现在通过命令行通过输入 OpenCV命令行解析器 。 这个文件的示例参数
- 【计算机视觉】 相机姿态估计之标记检测-检测ChArUco角点3
- 【计算机视觉】 相机姿态估计之标记检测-相机标定ArUco和ChArUco 5
- 【计算机视觉】 相机姿态估计之标记检测-ArUco标记检测1
- 【计算机视觉】 相机姿态估计之标记检测-ArUco钻石标记的检测4
- 【计算机视觉】 相机姿态估计之标记检测-检测ArUco板2
- 【计算机视觉】 相机姿态估计之标记检测-Aruco模块常见问题解答 6
- 计算机视觉----Harris 角点检测
- SLAM基础技术点之基于计算机视觉求解相机姿态变化的方法汇总
- 【计算机视觉】opencv靶标相机姿态解算2 根据四个特征点估计相机姿态 及 实时位姿估计与三维重建相机姿态
- 计算机视觉——Harris角点检测
- 计算机视觉之(一)利用Harris检测子进行角点特征检测(含matlab源码)
- 计算机视觉篇二:图像的匹配之FAST角点检测算法
- 计算机视觉---3---边缘检测
- 菜鸟看论文——U-V-Disparity与地面检测、相机姿态估计
- PnP 单目相机位姿估计(三):二维码角点检测
- 检测与姿态估计的评价标准
- 【计算机视觉】opencv靶标相机姿态解算3 根据两幅图像的位姿估计结果求某点的世界坐标 (三维重建)
- 【计算机视觉】目标检测之ECCV2016
- Spark中广播的使用
- 网上关于视频网站的视频地址解析的方法有哪些?
- 面试题目2:实现单例模式
- Spring中泛型依赖注入
- Vuex 模块化实现待办事项的状态管理
- 【计算机视觉】 相机姿态估计之标记检测-检测ChArUco角点3
- Kotlin Android 扩展
- python2.5与python3虚拟环境使用
- Vuex 通俗版教程
- IOS上webView中使用html5 video的问题
- Ubuntu-Python2.7安装 scipy,numpy,matplotlib
- 与MQ通讯的完整JAVA程序
- Android实现推送方式解决方案
- vue学习笔记之——v-for与局部组件的传值