当前位置: 首页 > news >正文

详细解释aruco::markdetection _detectInitialCandidates函数

_detectInitialCandidates 是 OpenCV 的 ArUco 模块中一个非常关键的函数,它负责检测图像中的候选 ArUco 标记。该函数的主要目标是:

  • 使用多个尺度(scale)对输入图像进行自适应阈值处理;
  • 在每个尺度下提取轮廓并筛选出符合要求的四边形角点;
  • 将这些候选标记及其对应的轮廓保存到输出参数中。

📌 函数签名

static void _detectInitialCandidates(const Mat &grey,vector<vector<Point2f> > &candidates,vector<vector<Point> > &contours,const DetectorParameters &params)

参数说明:

参数名类型含义
greyconst Mat &输入的灰度图像
candidatesvector<vector<Point2f> > &输出的候选标记角点(4个点组成的矩形)
contoursvector<vector<Point> > &输出的与候选角点对应的完整轮廓信息
paramsconst DetectorParameters &检测器参数,控制检测过程的行为

🔍 功能详解

1️⃣ 设置自适应阈值窗口大小范围

CV_Assert(params.adaptiveThreshWinSizeMin >= 3 && params.adaptiveThreshWinSizeMax >= 3);
CV_Assert(params.adaptiveThreshWinSizeMax >= params.adaptiveThreshWinSizeMin);
CV_Assert(params.adaptiveThreshWinSizeStep > 0);

确保传入的参数合法:

  • 自适应阈值窗口最小和最大尺寸 ≥ 3(OpenCV 要求)
  • 步长必须大于 0

2️⃣ 计算要使用的窗口大小数量(即图像金字塔层数)

int nScales = (params.adaptiveThreshWinSizeMax - params.adaptiveThreshWinSizeMin) /params.adaptiveThreshWinSizeStep + 1;

根据设定的最小、最大窗口大小和步长,计算需要尝试多少种不同的窗口大小。

例如:min=20max=40step=5 → nScales = 5


3️⃣ 为每种窗口大小准备容器

vector<vector<vector<Point2f> > > candidatesArrays((size_t) nScales);
vector<vector<vector<Point> > > contoursArrays((size_t) nScales);

  • candidatesArrays[i]:第 i 个窗口大小下的所有候选标记角点集合。
  • contoursArrays[i]:对应的所有轮廓。

4️⃣ 多线程处理不同尺度(parallel_for_)

parallel_for_(Range(0, nScales), [&](const Range& range) {for (int i = begin; i < end; i++) {int currScale = params.adaptiveThreshWinSizeMin + i * params.adaptiveThreshWinSizeStep;Mat thresh;_threshold(grey, thresh, currScale, params.adaptiveThreshConstant);_findMarkerContours(thresh, candidatesArrays[i], contoursArrays[i],params.minMarkerPerimeterRate, params.maxMarkerPerimeterRate,params.polygonalApproxAccuracyRate, params.minCornerDistanceRate,params.minSideLengthCanonicalImg);}
});

对于每一个窗口大小:
  1. 调用 _threshold() 进行自适应阈值处理
    • 用于将图像二值化,便于后续提取轮廓。
  2. 调用 _findMarkerContours() 提取轮廓并筛选出可能的 ArUco 标记角点
    • 筛选条件包括:周长范围、是否为凸四边形、角点距离等。

5️⃣ 合并所有尺度的结果

for(int i = 0; i < nScales; i++) {for(unsigned int j = 0; j < candidatesArrays[i].size(); j++) {candidates.push_back(candidatesArrays[i][j]);contours.push_back(contoursArrays[i][j]);}
}

将不同尺度下检测到的候选标记统一合并到最终输出变量 candidates 和 contours 中。


🧠 关键辅助函数说明

✅ _threshold()

static void _threshold(InputArray _in, OutputArray _out, int winSize, double constant)
  • 使用 adaptiveThreshold() 对图像进行自适应二值化。
  • 确保窗口大小为奇数。
  • 采用 ADAPTIVE_THRESH_MEAN_C 方法,反向二值化 (THRESH_BINARY_INV)。

✅ _findMarkerContours()

static void _findMarkerContours(const Mat &in,vector<vector<Point2f> > &candidates,vector<vector<Point> > &contoursOut,double minPerimeterRate,double maxPerimeterRate,double accuracyRate,double minCornerDistanceRate,int minSize)

这个函数负责从二值图像中提取轮廓,并筛选出可能是 ArUco 标记的四边形。

主要步骤:
  1. 查找所有轮廓

    findContours(in, contours, RETR_LIST, CHAIN_APPROX_NONE);
  2. 逐个轮廓筛选

    • 周长在指定范围内;
    • 多边形逼近后为凸四边形;
    • 四个角点之间最小距离满足要求;
    • 如果启用 ArUco3 功能,则额外判断最小边长。
  3. 将符合条件的轮廓加入输出

    • 角点存入 candidates
    • 完整轮廓存入 contoursOut

📈 总结流程图

_detectInitialCandidates()
│
├─ 设置参数检查
│
├─ 计算使用多少种窗口大小(nScales)
│
├─ 并行遍历每个窗口大小:
│   ├─ 图像二值化(_threshold)
│   └─ 提取并筛选候选标记(_findMarkerContours)
│       ├─ 查找轮廓
│       ├─ 筛选轮廓(凸四边形、周长、角点距离等)
│       └─ 添加进临时容器
│
└─ 合并所有窗口大小下的结果到输出

🧰 参数影响分析(DetectorParameters)

参数名作用
adaptiveThreshWinSizeMin最小阈值窗口大小,决定最小可检测标记大小
adaptiveThreshWinSizeMax最大阈值窗口大小,决定最大可检测标记大小
adaptiveThreshWinSizeStep窗口大小递增步长
minMarkerPerimeterRate最小周长比例(相对于图像宽度/高度)
maxMarkerPerimeterRate最大周长比例
polygonalApproxAccuracyRate多边形逼近精度比例
minCornerDistanceRate角点间最小距离比例
minSideLengthCanonicalImgArUco3 功能中最小边长限制

📝 示例说明

假设你有如下代码调用:

Mat grey = ...; // 输入灰度图
vector<vector<Point2f>> candidates;
vector<vector<Point>> contours;
DetectorParameters params = DetectorParameters::create();
_detectInitialCandidates(grey, candidates, contours, params);

这段代码会:

  • 使用多个窗口大小对图像进行自适应阈值;
  • 提取轮廓并筛选出潜在的 ArUco 标记;
  • 返回所有候选标记的四个角点坐标及其原始轮廓。

✅ 总结

特性描述
功能检测图像中所有可能的 ArUco 标记候选区域
输入灰度图像、检测参数
输出候选角点列表、对应轮廓列表
关键技术自适应阈值、轮廓检测、多边形逼近、几何筛选
性能优化使用 parallel_for_ 实现多线程加速
后续处理通常交给 _reorderCandidatesCorners() 排序角点顺序

相关文章:

  • Java八股文——Spring「MyBatis篇」
  • Linux开发工具之VsCode(Filezila、MobaXterm、Vim三合一)
  • git的常用方法
  • 【Unity优化】提高热更新和打包速度
  • 架空线路智能监控系统的应用与优势剖析
  • Android Studio 无法安装HAXM,点击之后无反应
  • Vue-Typed-JS打字动画效果
  • C#.Net 使用NPOI库导出Excel(含列宽度自适应) 及 根据Excel文件生成DataTable
  • c#实现绝对路径和相对路径的转换
  • 【网络】每天掌握一个Linux命令 - netperf
  • 【题解-洛谷】P2935 [USACO09JAN] Best Spot S
  • 2025年5月一区SCI-状态优化算法Status-based Optimization-附Matlab免费代码
  • CVE-2017-12615源码分析与漏洞复现(Tomcat 任意文件上传)
  • 工程论文: TORL: Scaling Tool-Integrated RL
  • day28/60
  • 1005. Maximize Sum Of Array After K Negations
  • 如何用python读取大的xml文件,示例为1.9G的xml文件
  • HarmonyOS - UIObserver(无感监听)
  • Windows 安装以及配置Docker全流程 - Docker Toolbox
  • vibe coding 2025工具全景图
  • 网站做好怎么开始做推广/小程序开发流程
  • 400网站建设/2020年百度搜索排名
  • 开发网站开始的工作/珠海百度关键字优化
  • 做机械设备类网站用什么颜色好/aso优化注意什么
  • 如何做网站 百度/百度一下网页入口
  • 个体户网站备案/西安百度快速排名提升