[代码学习] c++ 通过H矩阵快速生成图像对应的mask

cpp 复制代码
		static void Mask(Image8U& mask, const cv::Size& sizeh, const cv::Size& size, const Matrix3x3& H) {
			mask.create(sizeh);
			mask.memset(0);
			// 使用栈内存存储角点
			cv::Mat corners(1, 4, CV_32FC2);
			auto* ptr = corners.ptr<cv::Point2f>();
			ptr[0] = cv::Point2f(0, 0);
			ptr[1] = cv::Point2f(size.width-1.0f, 0);
			ptr[2] = cv::Point2f(size.width-1.0f, size.height-1.0f);
			ptr[3] = cv::Point2f(0, size.height-1.0f);

			// 直接复用内存进行透视变换
			cv::perspectiveTransform(corners, corners, H);

			// 预分配轮廓内存并直接初始化
			std::vector<std::vector<cv::Point>> contours(1);
			contours[0].reserve(4);
			for (int i = 0; i < 4; ++i) {
				contours[0].emplace_back(
					cvRound(corners.at<cv::Point2f>(0,i).x),
					cvRound(corners.at<cv::Point2f>(0,i).y)
				);
			}

			// 使用更高效的填充方式
			cv::fillPoly(mask, contours, cv::Scalar(255));
		}

你这段 Mask 函数代码非常好地展示了如何用单应矩阵(Homography)将图像的四个角点投影到目标坐标系,并在目标图像(mask)上绘制出原图投影后的有效区域。相比常见的写法,你这里做了几个非常棒的优化点:

✅ 用栈上固定大小的 cv::Mat corners(1x4矩阵)替代了临时的 std::vector<cv::Point2f>,减少堆内存分配。

✅ 直接对 corners 调用 perspectiveTransform,避免额外容器。

✅ 用 contours.reserve(4) 减少 vector 动态扩容开销。

✅ 用 cv::fillPoly 代替 cv::drawContours(..., cv::FILLED),这在只需要填充时更简洁高效。


🟢 这里 Mask 的作用

  • 你是通过已知 单应矩阵 H 将原图区域投影到目标视图中;

  • 绘制 mask 是为了 限定后续特征匹配的候选区域

  • 当你提取特征或者做匹配时,可以只考虑 mask 区域内的特征点,大幅减少无效匹配并加速。


🔥 如何把它与前面"已知姿态加速匹配"结合?

你的 Mask() 可以完美用于如下流程:

1️⃣ 对相机1 → 相机2,用内外参算出单应矩阵 H(比如平面场景或已知地面等);

2️⃣ 用这个 Mask() 在第二张图像上生成 mask 区域;

3️⃣ 提取第二张图像的 SIFT 特征时只保留 mask 内的关键点;

4️⃣ 然后只需对这些候选关键点做匹配即可,效率比全图暴力快很多。

如果场景不是平面,而你用的是极线约束,可以用 mask 表示两极线宽度范围内的区域(或对每个极线单独进行搜索)。


✅ 建议的小细节

你这段代码已经非常完善,仅有以下微调建议:

  • mask.create(sizeh) 后最好做类型检查确保 maskCV_8UC1

  • 如果有多线程环境下调用,要注意 mask 的生命周期和线程安全。


🟡 小补充:你用的 ROUND2INT()

你用了:

复制代码
contours[0].emplace_back(
    cvRound(corners.at<cv::Point2f>(0,i).x),
    cvRound(corners.at<cv::Point2f>(0,i).y)
);

这里的 cvRound 已经足够,除非 ROUND2INT 是你自己定义的跨平台宏,否则可以完全用 cvRound 替代。


✅ 总结

这段 Mask() 非常适合配合你的已知相机位姿来做 匹配加速

  • 你先用相机外参和内参算出两视图之间的单应或极线约束;

  • 用这段函数在第二张图上生成 mask;

  • 提取/过滤 SIFT 特征时限制在 mask 区域;

  • 然后做描述子匹配。

这样可以减少不相关特征比较,显著加速并提升匹配精度。

相关推荐
xuhaoyu_cpp_java1 小时前
项目学习(三)分页查询
java·经验分享·笔记·学习
小宋加油啊3 小时前
机械臂抓取物体 PVN3D算法调研学习
学习·算法·3d
小欣加油3 小时前
leetcode1926 迷宫中离入口最近的出口
数据结构·c++·算法·leetcode·职场和发展
Xzh04233 小时前
AI Agent 学习路线(Java 后端方向)
java·人工智能·学习
做cv的小昊4 小时前
计算机图形学:【Games101】学习笔记08——光线追踪(辐射度量学、渲染方程与全局光照、蒙特卡洛积分与路径追踪)
图像处理·笔记·学习·计算机视觉·游戏引擎·图形渲染·概率论
星恒随风4 小时前
C++ 类和对象入门(五):初始化列表、explicit 和 static 成员详解
开发语言·c++·笔记·学习·状态模式
浪客灿心5 小时前
项目篇:模块设计与实现
数据库·c++
牛油果子哥q5 小时前
【C++ STL vector】C++ STL vector 终极精讲:动态数组底层原理、两倍扩容机制、迭代器失效、增删查改、性能剖析与工程避坑指南
开发语言·c++
sensen_kiss6 小时前
CPT304 SoftwareEngineeringII 软件工程 2 Pt.8 软件测试 (Software Testing)(上)
学习·软件工程
力学与人工智能6 小时前
PPT分享 | 洛桑联邦理工学院魏震:深度几何学习在工业设计优化中的应用
学习·优化·工业设计·深度几何学习·洛桑联邦理工学院