Acuro二维码识别与降落对准

什么是Aruco码?

Aruco二维码

Aruco码能做什么?

 搜索任务、自主降落等辅助标识

 替代复杂任务中较难识别的目标(短期替代、长期替代)

 SLAM中的地标

 反解无人机位置、实现定点

 …

 最容易识别的目标之一

1 候选框检测

Aruco码外部由正方形框构成,因此,首先肯定要检测出候选框,由于透视变换的影响,导致正方形在图像上的投影可以为任意4边形,唯一可知的性质就是,这个4边形一定是具有凸性的,代码也是利用这个性质进行筛选的。

候选4边形检测算法分为三个阶段:

  • 凸四边形检测
  • 角点排序
  • 去除相似框

1.1 凸四边形检测

记检测过程的第一步之一是对输入图像进行自适应二值化处理adaptiveThreshWinSizeMin控制的是最小窗口,adaptiveThreshWinSizeMax控制的是最大窗口,adaptiveThreshWinSizeStep控制窗口步长,如果二维码太大,则窗口小可能会“破坏”标记边界,导致无法检测到它。如果二维码太小,则窗口小会产生相同的效果,并且还会降低性能。而且,该过程将趋向于全局阈值化,从而失去了自适应收益。

1.1 凸四边形检测

基于规则的凸四边形检测

  • 特别大特别小的轮廓一般都不会是目标,最小周长阈值为minPerimeterPixels = minPerimeterRate * max(rows, cols),最大周长阈值为maxPerimeterPixels = maxPerimeterRate * max(rows, cols)
  • 对这个轮廓进行多边形逼近approxPolyDP(contours[i], approxCurve, double(contours[i].size()) * polygonalApproxAccuracyRate, true);。
    double(contours[i].size()) * polygonalApproxAccuracyRate是对应的逼近精度,简单来说,越大的轮廓具有更大的逼近阈值。
  • 轮廓逼近点必须为4个点(4边形),且这个4边形一定是凸的,否则这个轮廓就一定不是目标轮廓。
  • 4边形的4个角点之间的最小距离minDistSq必须大于轮廓周长*minCornerDistanceRate,否则就不是候选。
  • 判断4边形是否存在一个角点离图像的边界非常近,打个比方,角点的坐标为(1,1),与图像边界非常近,如果有那么这个就扔掉,边界距离阈值为minDistanceToBorder。

1.2 角点排序

角点排序使用函数_reorderCandidatesCorners(candidates);,保证角点的顺序是顺时针方向,

仅此而已。

1.3 去除相似4边形

对于两个4边形,其4个角点之间的最短平均距离如果小于两个矩形的最小周长*minMarkerDistanceRate,那么就认为这两个矩形是相似的。矩形的周长就是轮廓像素个数,两个

相似4边形,周长小的会被扔掉。

2 二维码识别(比特提取)

2.1 对每个四边形利用getPerspectiveTransform和warpPerspective进行透视变换,透视变换的目标为方形,其边长为perspectiveRemovePixelPerCell*比特边长

例如,假设我们正在处理5x5位的标记和1位的边框大小。然后,每个维度的单元/位总数为5 + 2 * 1

= 7(边界必须计数两次)。单元格总数为7x7。 如果PerspectiveRemovePixelPerCell的值为10,则所获得图像的大小将为10 * 7 = 70-> 70x70像素。

2.2 判断四边形内部是否为全黑或全白。先移除边框,然后利用meanStdDev计算区域的均值和方差,如果方差小于minOtsuStdDev,说明是全黑或全白,如果均值大于127,则认为是全白,否则全黑。

2.3 利用大津阈值对透视变换后的图像做个二值化threshold(resultImg, resultImg, 125, 255,

THRESH_BINARY | THRESH_OTSU);

2.4 因为已经知道码标的边长的比特数,那么就直接对二值化图像提取出对应的图像块。图像块的四周靠近边界部分肯定有噪声,所以四周边界部分扔掉,那么这个边界宽度为cellMarginPixels =

perspectiveRemoveIgnoredMarginPerCell * perspectiveRemovePixelPerCell

3 对检测出的二维码候选进行过滤

检测结果中可能会出现两个码标ID一样,且其中一个码标在另一个码标里面,属于包含关系。

那么针对这个情况就要先找出具有包含关系的矩形,判断ID是否一样,一样就删掉。

4 角点修正

前面步骤检测出的角点都是像素级的,用于后续位姿估计时候可能会有误差,因此检测出角点之后,需要对其进行细化,得到亚像素角点,细化方法有两种,分别为:角点细化(CORNER_REFINE_SUBPIX)和拟合直线细化(CORNER_REFINE_CONTOUR)。细化方法的选择,指定参数cornerRefinementMethod即可,算法默认是不细化的。

5 姿态估计

PnP(Perspective-n-Point)是求解3D到2D点对运动的方法。它描述了已知n个3D空间点及其

图像上的投影位置时,如何估计相机的位姿。

PnP问题有很多种求解方法,例如,用3对点估计位姿的P3P、直接线性变换(DLT)、EPnP、

UPnP,等等。此外,还能用非线性优化的方法,构建最小二乘问题并迭代求解,也就是Bundle

Adjustment。

Prometheus中的二维码识别与封装

Aruco检测代码位置

Modules\object_detection\aruco_det.cpp

如何使用Prometheus控制接口进行目标跟踪?

**代码位置:**Modules\mission\autonomous_landing\autonomous_landing_aruco.cpp

订阅识别模块的输出(大部分都需要坐标转换,并进行数据处理)

"/prometheus/object_detection/aruco_det"

订阅无人机的状态(除了xyz信息之外,判断飞机当前模式、解锁等)

"/prometheus/drone_state"

发布控制指令

“/prometheus/control_command”

简易状态机的实现(处理好初始化、起飞、丢失目标、检测到目标、任务失败等逻辑处理),这些不同的状态会对应不同的控制策略,即不同控制指令

核心状态:目标追踪

目标追踪

今天不讨论vision-based追踪,只说position-based追踪

已知目标位置(一般来说只能追静止目标)

 直接飞到那个位置,发送 期望目标点 至控制模块

 将目标位置和当前无人机位置做差,乘以系数得到 期望速度 发至控制模块(推荐)

已知目标位置和速度(可追动态目标)

 此处不展开

代码讲解与演示环节

启动脚本一: 用于检测识别算法的输出是否准确

Simulator\gazebo_simulator\launch_detection\sitl_aruco_detection.launch
**roslaunch Prometheus_gazebo sitl_aruco_detection.launch**

启动脚本二: 基于Aruco码的自主降落

Simulator\gazebo_simulator\launch_detection\sitl_landing_on_aruco_marker.launch
**roslaunch Prometheus_gazebo sitl_landing_on_aruco_marker.launch**

Aruco识别

Modules\object_detection\aruco_det.cpp

追踪控制:

Modules\mission\autonomous_landing\autonomous_landing_aruco.cpp

启动脚本:

Simulator\gazebo_simulator\launch_detection\sitl_aruco_detection.launch (识别测试)
Simulator\gazebo_simulator\launch_detection\sitl_landing_on_aruco_marker.launch (基于
Aruco码的自主降落)
  • 0
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
多层嵌套的 ArUco 识别可以通过以下步骤实现: 1. 导入必要的库和模块: ```python import cv2 import numpy as np import cv2.aruco as aruco ``` 2. 定义 ArUco 的参数和字典: ```python aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250) parameters = aruco.DetectorParameters_create() ``` 3. 加载图像并检测 ArUco : ```python img = cv2.imread('path/to/image.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) corners, ids, rejectedImgPoints = aruco.detectMarkers(gray, aruco_dict, parameters=parameters) ``` 4. 如果检测到 ArUco ,则对每个 ArUco 进行处理: ```python if len(corners) > 0: # 绘制检测到的 ArUco img = aruco.drawDetectedMarkers(img, corners, ids) # 循环处理每个 ArUco for i in range(len(ids)): # 检测当前 ArUco 中是否嵌套了其他 ArUco nested_corners, nested_ids, _ = aruco.detectMarkers(gray, aruco_dict, parameters=parameters, cameraMatrix=camera_matrix, distCoeff=dist_coeff, corners=corners[i]) # 如果检测到嵌套的 ArUco ,则对其进行处理 if len(nested_corners) > 0: # 绘制检测到的嵌套的 ArUco img = aruco.drawDetectedMarkers(img, nested_corners, nested_ids) # 循环处理每个嵌套的 ArUco for j in range(len(nested_ids)): # 处理嵌套的 ArUco # ... else: # 处理不嵌套的 ArUco # ... ``` 在上述代中,`camera_matrix` 和 `dist_coeff` 是相机的内参和畸变系数,可以通过相机标定获得。 注意,多层嵌套的 ArUco 需要按照嵌套的顺序进行处理。例如,如果一个 ArUco 嵌套了另一个 ArUco ,那么应该先处理嵌套的 ArUco ,再处理外层的 ArUco

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值