在这里插入图片描述

要基于建筑图片重建三维数字资产是一个复杂的计算机视觉任务,涉及图像采集、特征提取、相机姿态估计、稠密重建和三维模型优化等多个步骤。下面我将提供一个基于Python的解决方案框架,使用开源库实现从图片到三维模型的基本流程。

首先需要安装必要的库:

pip install opencv-python numpy matplotlib pycolmap trimesh open3d

下面是实现的核心代码,包含了从图像加载、特征匹配到三维点云生成的完整流程:

import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
import trimesh
import open3d as o3d
from pycolmap import Reconstruction, Image, Point3D# 1. 准备工作:设置路径和参数
class BuildingReconstructor:def __init__(self, image_dir, output_dir):self.image_dir = image_dirself.output_dir = output_dirself.image_paths = [os.path.join(image_dir, f) for f in os.listdir(image_dir) if f.lower().endswith(('.png', '.jpg', '.jpeg'))]self.reconstruction = None# 创建输出目录os.makedirs(output_dir, exist_ok=True)os.makedirs(os.path.join(output_dir, 'sparse'), exist_ok=True)os.makedirs(os.path.join(output_dir, 'dense'), exist_ok=True)# 2. 图像预处理def preprocess_images(self):"""对图像进行预处理,包括 resize 和去畸变"""processed_dir = os.path.join(self.output_dir, 'processed_images')os.makedirs(processed_dir, exist_ok=True)processed_paths = []for img_path in self.image_paths:img = cv2.imread(img_path)# 调整图像大小,保持比例h, w = img.shape[:2]max_dim = 1024if max(h, w) > max_dim:scale = max_dim / max(h, w)img = cv2.resize(img, (int(w*scale), int(h*scale)))# 保存处理后的图像filename = os.path.basename(img_path)save_path = os.path.join(processed_dir, filename)cv2.imwrite(save_path, img)processed_paths.append(save_path)self.image_paths = processed_pathsprint(f"预处理完成,共 {len(processed_paths)} 张图片")return processed_paths# 3. 特征提取与匹配(使用COLMAP进行稀疏重建)def run_sparse_reconstruction(self):"""使用COLMAP进行稀疏重建,获取相机参数和稀疏点云"""print("开始稀疏重建...")# 调用COLMAP进行特征提取和匹配from pycolmap import feature_extractor, exhaustive_matcher, mapper# 特征提取feature_extractor(database_path=os.path.join(self.output_dir, 'database.db'),image_path=self.image_dir,image_list=self.image_paths,camera_mode=0  # 自动选择相机模型)# 特征匹配exhaustive_matcher(database_path=os.path.join(self.output_dir, 'database.db'))# 三维重建self.reconstruction = mapper(database_path=os.path.join(self.output_dir, 'database.db'),image_path=self.image_dir,output_path=os.path.join(self.output_dir, 'sparse'),verbose=True)print(f"稀疏重建完成,生成 {len(self.reconstruction.points3D)} 个三维点")return self.reconstruction# 4. 稠密重建(生成密集点云)def run_dense_reconstruction(self):"""基于稀疏重建结果进行稠密重建"""if not self.reconstruction:raise ValueError("请先进行稀疏重建")print("开始稠密重建...")# 这里简化实现,实际项目中可以使用OpenMVS或COLMAP的稠密重建模块# 导出稀疏点云points = []colors = []for p3d in self.reconstruction.points3D.values():points.append(p3d.xyz)colors.append(p3d.color / 255.0)# 转换为Open3D点云pcd = o3d.geometry.PointCloud()pcd.points = o3d.utility.Vector3dVector(np.array(points))pcd.colors = o3d.utility.Vector3dVector(np.array(colors))# 点云下采样和去噪pcd = pcd.voxel_down_sample(voxel_size=0.05)cl, ind = pcd.remove_statistical_outlier(nb_neighbors=20, std_ratio=2.0)pcd = pcd.select_by_index(ind)# 保存稠密点云dense_pcd_path = os.path.join(self.output_dir, 'dense', 'point_cloud.ply')o3d.io.write_point_cloud(dense_pcd_path, pcd)print(f"稠密点云保存至 {dense_pcd_path},包含 {len(pcd.points)} 个点")return pcd# 5. 三维模型生成(从点云创建网格)def generate_mesh(self, pcd):"""从点云生成三维网格模型"""print("开始生成三维网格...")# 估计法向量pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30))# 使用泊松表面重建生成网格with o3d.utility.VerbosityContextManager(o3d.utility.VerbosityLevel.Debug) as cm:mesh, densities = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=9)# 裁剪低密度区域vertices_to_keep = densities > np.quantile(densities, 0.01)mesh = mesh.select_by_index(np.where(vertices_to_keep)[0])# 保存网格模型mesh_path = os.path.join(self.output_dir, 'building_mesh.ply')o3d.io.write_triangle_mesh(mesh_path, mesh)print(f"三维网格模型保存至 {mesh_path}")return mesh# 6. 可视化结果def visualize_results(self, pcd=None, mesh=None):"""可视化点云和网格模型"""if pcd:print("可视化点云...")o3d.visualization.draw_geometries([pcd], window_name="建筑点云")if mesh:print("可视化网格模型...")o3d.visualization.draw_geometries([mesh], window_name="建筑三维模型")# 执行完整流程def run_pipeline(self):"""执行完整的三维重建流程"""self.preprocess_images()self.run_sparse_reconstruction()pcd = self.run_dense_reconstruction()mesh = self.generate_mesh(pcd)self.visualize_results(pcd, mesh)return mesh# 主函数
def main():# 设置图片目录和输出目录image_dir = "building_images"  # 存放从小红书收集的建筑图片output_dir = "reconstruction_results"# 确保图片目录存在if not os.path.exists(image_dir) or len(os.listdir(image_dir)) == 0:print(f"错误:图片目录 {image_dir} 不存在或为空")print("请先在该目录下放置建筑的多角度图片")return# 创建重建器并运行reconstructor = BuildingReconstructor(image_dir, output_dir)mesh = reconstructor.run_pipeline()print("三维重建流程完成!")if __name__ == "__main__":main()

使用说明

这个代码实现了从建筑图片到三维模型的完整流程,主要分为以下几个步骤:

  1. 数据准备

    • 在"building_images"文件夹中放入从小红书收集的建筑图片
    • 建议收集15-30张不同角度、不同光照条件下的图片,覆盖建筑各个面
  2. 代码运行

    • 运行脚本后,程序会自动进行图像预处理
    • 接着进行特征提取和匹配,构建稀疏点云
    • 然后生成稠密点云并构建三维网格模型
    • 最后可视化结果并保存模型文件
  3. 结果输出

    • 处理后的图片
    • 稀疏点云和稠密点云数据
    • 最终的三维网格模型(PLY格式),可导入Blender等软件进一步编辑

注意事项

  1. 图片质量对重建结果影响很大,建议使用清晰、光照均匀的图片
  2. 拍摄时尽量围绕建筑移动,保持重叠区域,避免剧烈视角变化
  3. 对于复杂建筑,可能需要更多图片和后期手动优化
  4. 该代码需要安装COLMAP软件,具体安装方法请参考官方文档
  5. 从网络获取图片时请注意遵守版权规定和平台条款

如果需要更高质量的重建结果,可以考虑使用专业的三维重建软件如Agisoft Metashape,或在这个基础上增加纹理映射、模型简化等步骤。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/94863.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/94863.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/94863.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

⭐CVPR2025 自动驾驶半监督 LiDAR 分割新范式:HiLoTs 框架深度解析

📄论文题目:HiLoTs: High-Low Temporal Sensitive Representation Learning for Semi-Supervised LiDAR Segmentation in Autonomous Driving ✍️作者及机构: R.D. Lin、Pengcheng Weng、Yinqiao Wang、Fei Wang(西安交通大学软件…

【 MYSQL | 基础篇 函数与约束 】

摘要:本文介绍数据库中的函数与约束,函数含字符串、数值、日期、流程四类,可实现字符串处理、数值计算等需求。约束分六类,重点讲外键约束的语法、删除更新行为,保证数据正确完整。思维导图1. 函数函数是指一段可以直接…

Oracle 数据库性能调优:从瓶颈诊断到精准优化之道

引言:性能优化的本质在当今数据驱动的时代,数据库性能直接关系到企业的运营效率和用户体验。Oracle 作为全球领先的关系型数据库管理系统,承载着众多企业的核心业务。然而,随着数据量的增长和业务复杂度的提升,数据库性…

杨校老师竞赛课堂之C++语言GESP一级笔记

考试大纲 GESP一级考试大纲 计算机基础与编程环境 计算机历史 变量的定义与使用 基本数据类型(整型、浮点型、字符型、布尔型) 输入与输出(cin与cout、scanf与printf) 基本运算(算术运算、关系运算、逻辑运算&am…

操作系统-管程

1. 为什么需要管程?—— 信号量 (Semaphore) 的困境在理解管程之前,你必须先知道它要解决什么问题。之前,我们使用信号量 (Semaphore) 来实现进程/线程间的同步与互斥。虽然信号量功能强大,但它存在两个主要问题:编程复…

日志的实现

目录 日志与策略模式 Log.hpp class LogStrategy基类 class ConsoleLogStrategy派生类 classFileLogStrategy派生类 日志等级 获得时间戳 localtime_r函数详解 函数原型 struct tm结构的指针 Logger类(重点) class LogMessage 日志信息类 std::stringstream 用法 重…

【论文阅读】Sparse4D v2:Recurrent Temporal Fusion with Sparse Model

标题: Sparse4D v2:Recurrent Temporal Fusion with Sparse Model 作者: Xuewu Lin, Tianwei Lin, Zixiang Pei, Lichao Huang, Zhizhong Su motivation 在v1的基础上,作者发现长时序有更好的效果,但v1的计算量太大&am…

构建免费的音视频转文字工具:支持多语言的语音识别项目

在当今数字时代,音视频内容越来越多,但如何快速将其转换为文字一直是一个挑战。本项目提供了一个免费的解决方案,支持将视频和音频文件转换为文字,并且支持多语言识别。 一个支持中英文的音视频转文字工具,集成了 Vos…

【开题答辩全过程】以 基于SpringBootVue的智能敬老院管理系统为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人,语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

Linux 830 shell:expect,ss -ant ,while IFS=read -r line,

[rootsamba caozx26]# scp /home/caozx26/pub root192.168.235.3:~/ root192.168.235.3s password: /home/caozx26/pub: not a regular file [rootsamba caozx26]# ls app km nntp.sh ntp.sh until1.sh 公共 图片 音乐 find.sh l2 ntp1.sh pub u…

​​​​​​​GPT-5发布引爆争议,奥特曼连夜回应!付费充值的Plus用户成最大赢家?

摘要: GPT-5发布后,社区口碑两极分化,从“强无敌”到“还我4o”的呼声并存。面对技术故障和用户质疑,OpenAI CEO萨姆奥尔特曼及团队火速回应,公布了一系列补救措施和未来计划。本文将带你速览这场风波始末,…

Python 操作 Redis 的客户端 - Redis Stream

Python 操作 Redis 的客户端 - Redis Stream1. Redis Stream2. Redis Commands2.1. CoreCommands.xadd() (生产端)2.2. CoreCommands.xlen() (生产端)2.3. CoreCommands.xdel() (生产端)2.4. CoreCommands.xrange() (生产端)2.5. RedisClusterCommands.delete()3. Redis Stream…

【Qt开发】按钮类控件(一)-> QPushButton

目录 1 -> 什么是 PushButton? 2 -> 相关属性 3 -> 代码示例 3.1 -> 带有图标的按钮 3.2 -> 带有快捷键的按钮 4 -> 总结 1 -> 什么是 PushButton? 在 Qt 框架中,QPushButton 是最基础且最常用的按钮控件之一&am…

Citrix 零日漏洞自五月起遭积极利用

安全研究员 Kevin Beaumont 披露了有关 CVE-2025-6543 的惊人细节,这是一个严重的 Citrix NetScaler 漏洞,在该公司发布补丁之前的几个月里,该漏洞被积极利用作为零日攻击。 Citrix 最初将其轻描淡写为简单的“拒绝服务”漏洞,但…

【系列08】端侧AI:构建与部署高效的本地化AI模型 第7章:架构设计与高效算子

第7章:架构设计与高效算子 要将AI模型成功部署到端侧,除了对现有模型进行压缩和优化,更根本的方法是在设计之初就考虑其在资源受限环境下的运行效率。本章将深入探讨如何设计高效的网络架构,以及如何理解并优化常用的核心算子。高…

42-Ansible-Inventory

文章目录Ansible基本概述手动运维时代(原始社会)自动化运维时代自动化运维工具的优势Ansible的功能及优点Ansible的架构Ansible的执行流程安装AnsibleAnsible配置文件生效顺序Ansible inventory主机清单Ansible基于免秘钥方式管理客户端小结Ansible-Adho…

Go语言runtime/trace工具全面解析

基本概念与功能 Go语言的runtime/trace是Go标准库中内置的性能分析工具,主要用于追踪和可视化Go程序的运行时行为。它能够记录程序执行期间的各种事件,包括goroutine调度、系统调用、垃圾回收(GC)、网络I/O、锁等待等关键信息。 trace工具的核心功能包括: goroutine生命周期…

Docker(自写)

Docker程序是跑在操作系统上的,而操作系统上又装了各种不同版本的依赖库和配置程序依赖环境,环境不同,程序就可能跑不起来,如果我们能将环境和程序一起打包docker就是可以将程序和环境一起打包并运行的工具软件基础镜像DockerFile…

深度拆解 OpenHarmony 位置服务子系统:从 GNSS 到分布式协同定位的全链路实战

1. 系统概述 OpenHarmony 的“定位子系统”就是硬件服务子系统集里的 “位置服务子系统”(Location SubSystem)。它向下对接 GNSS/GPS、基站、Wi-Fi 等定位模组,向上以 标准位置 API 形式为应用提供 实时位置、轨迹、地理围栏 等能力,并可与分布式软总线联动,实现 跨设备…

React Native基本用法

1,index调用registerComponent,把appName注入到React Native的根节点。 2,package.json是全局大管家,package-lock.json锁定版本,不会手动编辑,通过install安装 3, bebal.config.json bebal.config.json是翻…