c++ - 3D 重建返回意大利面条结果
问题描述
我目前正在做我的毕业项目,对多张图像进行 3D 重建。我将项目分为两部分,一是使用运动结构恢复点云(我正在从这里学习代码,另一部分是从点云生成表面(我正在从本文中学习)。
他们两个都是......我猜是可以接受的吗?这是点云恢复的工作结果:
这是输入图像:
我想这还不错。如果输入数据集不是来自第一个数据集,例如这个兔子,表面重建部分的效果也不错:
但是,当我将第一个输入插入第二个时,这就是我得到的:
我完全不知道为什么会这样。我目前的估计是缺少功能,但我不知道真正的原因,也不知道如何增加可用功能。我在 OpenCV 中使用 ORB 并增加功能只会使匹配更加混乱,进而使结果点云更加混乱。
我已经坚持了好几天了,我将永远感激那些提供帮助的人。非常感谢!
代码
代码有点长,所以我将在此处发布摘录:
SfM 部分
Result SfM::run_sfm() {
if (images.empty()) {
LOG("There is no image to work on.");
return ERR;
}
// Initialize feature matcher
feature_util.init();
stereo_util.init();
// Initialize intrinsics
intrinsics.k = (cv::Mat_<float>(3, 3) << 2500, 0, images[0].cols / 2,
0, 2500, images[0].rows / 2,
0, 0, 1);
intrinsics.k_inv = intrinsics.k.inv();
intrinsics.distortion = cv::Mat_<float>::zeros(1, 4);
camera_poses.resize(images.size());
extract_features();
create_feature_match_matrix();
find_baseline_triangulation();
add_more_views_to_reconstruction();
return OK;
}
表面重建部分
auto Hoppe::run() -> bool {
if (pointcloud.points.size() == 0) {
HOPPE_LOG("ERR! Can't run without point cloud");
return false;
}
estimate_planes();
fix_orientations();
cube_march();
return true;
}
这是cube_march()
:
auto Hoppe::cube_march() -> void {
cv::Vec3f bounding_box_min, bounding_box_max;
calculate_bounds(bounding_box_min, bounding_box_max);
auto size = bounding_box_max - bounding_box_min;
HOPPE_LOG("Bounding box size: %f %f %f", size(0), size(1), size(2));
parameters.density = density_estimation(size);
cv::Vec3i marching_size(ceilf(size(0) / parameters.density),
ceilf(size(1) / parameters.density),
ceilf(size(2) / parameters.density));
auto volume = 0;
do {
volume = marching_size(0) * marching_size(1) * marching_size(2);
if (volume > parameters.max_volume) {
parameters.density *= 2.0f;
marching_size = cv::Vec3i(ceilf(size(0) / parameters.density),
ceilf(size(1) / parameters.density),
ceilf(size(2) / parameters.density));
}
} while (volume > parameters.max_volume);
HOPPE_LOG("Marching cube size: %d %d %d", marching_size(0),
marching_size(1), marching_size(2));
marcher.init(marching_size, parameters.density);
HOPPE_LOG("Estimated: from %f %f %f to %f %f %f",
bounding_box_min(0), bounding_box_min(1), bounding_box_min(2),
bounding_box_max(0), bounding_box_max(1), bounding_box_max(2));
marcher.march([&] (cv::Point3f p) {
return sdf(p);
}, VEC2POINT(bounding_box_min));
}
如果你问,我很乐意提供更多信息。谢谢!
解决方案
推荐阅读
- python - 将带有 MultiIndex 的 pandas DataFrame 与包含新标签的数据附加,但保留旧 MultiIndex 的整数位置
- powershell - 如何使用 PowerShell 执行不安全连接?
- scala - Scala:找到两个列表之间的区别
- angular - Angular / Ionic 中的 Observables
- android - Android 发布的应用程序无法访问互联网 Xamarin
- c# - 不能在接口的实现中使用更通用的属性类型?
- database - Spark MapWithState 管理会话状态
- java - android opencv 3.4.1 构建命令失败。未定义的引用
- c++ - 功能在特定时间内消耗墙壁时间
- c# - WPF组合框不以双向更新