条件
已有场景数据:
videos中含34个不同视角拍摄的同一动作视频
cams中为34个不同视角对应的相机参数:内外参+焦距
思考
如何利用动态视频 完成用于处理静态场景的3D gaussian?
-
每个视角的对应帧 -> 合成一个文件夹 即34张图片 34个视角
-
暴力做法:单目视频
看上去第一种比较靠谱一点,试试就逝世(bu)
视频转帧
设定30fps
import cv2
import os
def extract_frames(video_path, output_folder):
# 打开视频文件
video = cv2.VideoCapture(video_path)
# 获取视频的帧率
fps = video.get(cv2.CAP_PROP_FPS)
# 计算帧间隔
frame_interval = round(fps / 30) # 每秒 30 帧
# 初始化帧计数器
frame_count = 0
# 逐帧读取视频并保存帧序列
while True:
ret, frame = video.read()
# 如果无法读取到帧,则退出循环
if not ret:
break
# 按帧间隔保存帧
if frame_count % frame_interval == 0:
frame_filename = f"{output_folder}/{frame_count:05d}.jpg"
cv2.imwrite(frame_filename, frame)
frame_count += 1
# 释放资源
video.release()
def process_videos(input_folder, output_folder):
# 遍历输入文件夹中的所有文件
for filename in os.listdir(input_folder):
# 检查文件是否为视频文件
if filename.endswith(".mp4"):
video_path = os.path.join(input_folder, filename)
video_name = os.path.splitext(filename)[0]
video_output_folder = os.path.join(output_folder, video_name)
# 创建视频的输出文件夹
os.makedirs(video_output_folder, exist_ok=True)
# 提取帧序列
extract_frames(video_path, video_output_folder)
帧处理
将不同视频文件夹下相同命名的图像放到一个新文件夹下。
结果:每个文件夹34张不同视角的同一时刻图像。
import os
import shutil
def move_files_to_unique_folders(source_folder, destination_folder):
# 创建目标文件夹
os.makedirs(destination_folder, exist_ok=True)
# 获取源文件夹列表
source_folders = [f for f in os.listdir(source_folder) if os.path.isdir(os.path.join(source_folder, f))]
# 创建字典来存储相同文件名(不带后缀)和对应的文件夹路径
file_to_folder = {}
# 遍历源文件夹列表
for folder_name in source_folders:
# 获取源文件夹路径
folder_path = os.path.join(source_folder, folder_name)
# 获取源文件夹中的所有文件
files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))]
# 遍历文件列表
for filename in files:
# 分割文件名和文件扩展名
file_name, file_ext = os.path.splitext(filename)
# 检查文件名(不带后缀)是否已经在字典中存在
if file_name in file_to_folder:
# 如果文件名已经存在,将文件移动到对应的文件夹中
destination_path = os.path.join(file_to_folder[file_name], f'{int(folder_name):05d}.jpg')
else:
# 如果文件名不存在,创建新的文件夹,并将文件移动到该文件夹中
new_folder = os.path.join(destination_folder, file_name)
os.makedirs(new_folder, exist_ok=True)
file_to_folder[file_name] = new_folder
destination_path = os.path.join(new_folder, f'{int(folder_name):05d}.jpg')
source_path = os.path.join(folder_path, filename)
shutil.move(source_path, destination_path)
colmap生成位姿
点云生成过程参考:colmap简介及入门级使用
用meshlab打开欣赏一下重建效果:
这不就有了吗:
整理一下:
因为这里相机的格式不同于源码,所以接下来去调整一下3D gaussian读取数据的代码
调整
因为已经具备sparse和images,浅浅运行看能不能直接跑,
然后,报错:
if intr.model=="SIMPLE_PINHOLE":
focal_length_x = intr.params[0]
FovY = focal2fov(focal_length_x, height)
FovX = focal2fov(focal_length_x, width)
elif intr.model=="PINHOLE":
focal_length_x = intr.params[0]
focal_length_y = intr.params[1]
FovY = focal2fov(focal_length_y, height)
FovX = focal2fov(focal_length_x, width)
else:
assert False, "Colmap camera model not handled: only undistorted datasets (PINHOLE or SIMPLE_PINHOLE cameras) supported!"
看看intr.model到底是何方神圣:
原因:
在相机模型中,“Pinhole”(针孔)指的是一种理想化的相机模型,它假设光线通过一个小孔进入相机并形成图像。这种模型没有考虑相机镜头的畸变效应。
然而,实际的相机镜头会引入畸变,因此在实际应用中,常常会采用更复杂的相机模型来考虑畸变效应。其中一种常见的相机模型是"SIMPLE_RADIAL"(简单径向畸变模型),它是一种简化的径向畸变模型。
COLMAP 是一个开源的三维重建软件,它使用相机内参和畸变参数进行相机建模和三维重建。在 COLMAP 中,“SIMPLE_RADIAL” 可能是对针孔相机模型加入畸变模型的一种表示方式。
因此,尽管您的相机模型是针孔模型,但在 COLMAP 中,它可能以 “SIMPLE_RADIAL” 的形式进行表示,以考虑径向畸变效应。请注意,具体的相机模型表示方式可能因软件和工具的不同而有所差异。在使用 COLMAP 进行相机标定和三维重建时,建议参考相关文档以了解具体的相机模型表示方式和参数含义。
不管怎么说,先忽略径向畸变,看看训练结果吧。
(发现可以在colmap时指定相机模型为PINHOLE,下一节进行介绍)
在某些情况下,可以忽略径向畸变效应。特别是对于小焦距和高质量的相机镜头,径向畸变可能非常小,对图像质量的影响可以忽略不计。在这种情况下,可以使用简化的针孔相机模型,忽略径向畸变效应。
然而,在其他情况下,特别是对于大焦距镜头或低质量的相机镜头,径向畸变可能会较大地影响图像质量。在这种情况下,为了获得更准确的结果,应该考虑径向畸变效应并使用适当的畸变模型。
在进行相机标定和计算机视觉应用时,通常建议考虑相机的畸变效应,以提高精确度和准确性。通过进行相机标定,可以获取相机的内参矩阵和畸变参数,进而考虑径向畸变效应。
总之,是否可以忽略径向畸变效应取决于相机镜头的质量和所需的精度。对于一些特定的应用场景,可以根据实际情况决定是否忽略径向畸变,但一般建议在相机模型中考虑径向畸变效应,以获得更准确的结果。
于是手动指定一下:
def read_intrinsics_binary(path_to_model_file):
"""
see: src/base/reconstruction.cc
void Reconstruction::WriteCamerasBinary(const std::string& path)
void Reconstruction::ReadCamerasBinary(const std::string& path)
"""
cameras = {}
with open(path_to_model_file, "rb") as fid:
num_cameras = read_next_bytes(fid, 8, "Q")[0]
for _ in range(num_cameras):
camera_properties = read_next_bytes(
fid, num_bytes=24, format_char_sequence="iiQQ")
camera_id = camera_properties[0]
model_id = camera_properties[1]
model_name = CAMERA_MODEL_IDS[1].model_name # 指定PINHOLE
# model_name = CAMERA_MODEL_IDS[camera_properties[1]].model_name
【colmap】已知相机位姿情况下进行三维重建
PINHOLE
如上所述,在colmap生成相机位姿时输入相机模型参数
COLMAP命令行
因为是windows系统,所以需要对其中的指令稍作调整:文章来源:https://www.toymoban.com/news/detail-840739.html
D:\COLMAP-3.9.1-windows-cuda\COLMAP.bat automatic_reconstructor --workspace_path . --image_path ./images --sparse 1 --dense 0 --camera_model SIMPLE_PINHOLE
开始训练
python train.py -s <path to COLMAP or NeRF Synthetic dataset> --eval # Train with train/test split
python render.py -m <path to trained model> # Generate renderings
python metrics.py -m <path to trained model> # Compute error metrics on renderings
文章来源地址https://www.toymoban.com/news/detail-840739.html
到了这里,关于【pytorch】如何用自有数据集训练3D gaussian的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!