基于SFM结合Mask RCNN的车辆三维重建问题咨询
基于SFM的车辆三维重建问题解决方案
问题根因说明
你当前的核心错误是直接裁剪目标区域后resize作为SFM输入,破坏了原图的相机投影关系,这是相机参数混乱、重建不全的主要诱因。
各问题具体解决方案
- 问题1:目标车辆无法实现完整重建
- 先调整采集策略,保证多视角图像覆盖车辆全部表面,相邻视角重叠率不低于70%,针对车漆这类弱纹理区域,可临时粘贴少量易识别的标记点辅助特征匹配
- 不要使用裁剪后的小图做SFM,先用完整原图跑完SFM得到所有相机参数和稀疏点云,再用掩码过滤掉不属于车辆的点云,最后再做稠密重建
- 问题2:Mask RCNN输出的目标掩码尺寸不固定,无法满足SFM的运行要求
- 不需要让掩码尺寸统一,将生成的掩码resize回和原始输入图像完全一致的尺寸,掩码中车辆区域记为1、背景记为0,后续用来过滤点云即可
- 无需将掩码直接作为SFM的图像输入,SFM的输入仍使用原始尺寸的完整图像
- 问题3:最终重建得到的目标模型中仍存在背景噪声残留
- 适当提高Mask RCNN的掩码阈值减少误检,同时对输出掩码做形态学开运算,去除掩码边缘的细碎噪点
- SFM重建完成后,用对应视角的掩码对每帧的特征点做过滤,仅保留掩码范围内的特征点参与重建,后续稠密重建时也仅重建掩码覆盖的区域
- 问题4:仅将不同视角下输出的掩码输入SFM时,相机参数会出现混乱
- 完全放弃当前直接输入裁剪掩码图到SFM的逻辑:SFM计算相机参数依赖图像的全局特征匹配以及原始的内参信息,裁剪+resize会改变投影关系,导致无法匹配特征、相机位姿计算错误
- 正确流程:原始图像输入SFM完成位姿解算 -> 用对应视角的掩码过滤所有属于背景的点云 -> 仅保留车辆区域的点云做后续优化和稠密重建
代码修改建议
你当前的drawBox函数直接裁剪目标区域并resize的逻辑完全不符合SFM的输入要求,修改逻辑如下:
// 修改后的drawBox函数,输出和原图同尺寸的掩码,而非裁剪后的小图 void drawBox(Mat& frame, int classId, float conf, Rect box, Mat& objectMask, std::vector<Mat> &mask_list) { // 初始化和原图同尺寸的全0掩码 Mat full_mask = Mat::zeros(frame.size(), CV_8U); // Resize mask到检测框的尺寸 resize(objectMask, objectMask, Size(box.width, box.height)); Mat roi_mask = (objectMask > maskThreshold); roi_mask.convertTo(roi_mask, CV_8U); // 把检测框内的掩码复制到全图掩码对应位置 roi_mask.copyTo(full_mask(box)); // 可选:做形态学开运算去除掩码噪点 Mat kernel = getStructuringElement(MORPH_RECT, Size(3,3)); morphologyEx(full_mask, full_mask, MORPH_OPEN, kernel); mask_list.push_back(full_mask); }
相关实验结果展示
Mask RCNN分割结果



SFM原始重建结果

内容的提问来源于stack exchange,提问作者Andre Ahmed
相关产品推荐
相关产品推荐

