【pytorch】如何用自有数据集训练3D gaussian

条件

已有场景数据:

在这里插入图片描述

videos中含34个不同视角拍摄的同一动作视频

cams中为34个不同视角对应的相机参数:内外参+焦距

思考

如何利用动态视频 完成用于处理静态场景的3D gaussian?

  1. 每个视角的对应帧 -> 合成一个文件夹 即34张图片 34个视角

  2. 暴力做法:单目视频

看上去第一种比较靠谱一点,试试就逝世(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系统,所以需要对其中的指令稍作调整:

 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

在这里插入图片描述

  • 22
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,下面是使用 PyTorch 和 Pascal VOC 数据集进行训练的一些步骤: 1. 下载 Pascal VOC 数据集并解压缩。您可以从 http://host.robots.ox.ac.uk/pascal/VOC/ 下载数据集并按照指示解压缩。 2. 安装 PyTorch。您可以从 PyTorch 网站(https://pytorch.org/get-started/locally/)获取安装说明并安装 PyTorch。 3. 安装 torchvision。您可以使用以下命令安装 torchvision: ``` pip install torchvision ``` 4. 准备数据集。您需要将 Pascal VOC 数据集转换为 PyTorch 可以读取的格式。您可以使用以下代码: ``` from torchvision import datasets, transforms data_transform = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) train_dataset = datasets.VOCDetection(root='path/to/PascalVOC', year='2012', image_set='train', transform=data_transform) val_dataset = datasets.VOCDetection(root='path/to/PascalVOC', year='2012', image_set='val', transform=data_transform) ``` 将 "/path/to/PascalVOC" 替换为您解压缩数据集的路径。 5. 定义模型。您可以使用现有的模型,如 ResNet 或 VGG,也可以自己定义模型。这里是一个使用 ResNet18 的示例: ``` import torch.nn as nn import torchvision.models as models model = models.resnet18(pretrained=True) # 替换最后一层全连接层 num_classes = 20 # Pascal VOC 数据集中有20个类别 model.fc = nn.Linear(model.fc.in_features, num_classes) ``` 6. 定义损失函数和优化器。这里使用交叉熵损失和随机梯度下降(SGD)优化器: ``` import torch.optim as optim criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9) ``` 7. 训练模型。您可以使用以下代码训练模型: ``` from torch.utils.data import DataLoader train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False) num_epochs = 10 for epoch in range(num_epochs): # 训练模型 model.train() for images, labels in train_loader: optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() optimizer.step() # 在验证集上评估模型 model.eval() with torch.no_grad(): total_correct = 0 total_samples = 0 for images, labels in val_loader: outputs = model(images) _, predicted = torch.max(outputs, 1) total_correct += (predicted == labels).sum().item() total_samples += labels.size(0) val_accuracy = total_correct / total_samples print('Epoch [{}/{}], Val Accuracy: {:.2f}%'.format(epoch+1, num_epochs, val_accuracy*100)) ``` 在每个 epoch 结束时,模型在验证集上进行评估,并打印准确率。 希望这些步骤可以帮助您开始使用 PyTorch 和 Pascal VOC 数据集进行训练。如果您需要更详细的说明或者代码示例,请告诉我!
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值