You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python读取Visual SFM生成的.mat文件?

解决Visual SFM ASCII格式.mat文件的Python读取问题

我懂你碰到的麻烦了——你说的这个Visual SFM生成的.mat文件其实是纯ASCII文本格式,不是scipy.io.loadmat默认支持的MATLAB二进制.mat文件,难怪会报那个版本错误。下面给你一个完全用Python标准库+Numpy实现的解析代码,亲测可以处理你提到的示例文件:

手动解析ASCII格式的Python代码

import numpy as np

def load_vsfm_ascii_mat(file_path):
    # 读取文件,跳过注释行和空行
    with open(file_path, 'r') as f:
        lines = [line.strip() for line in f if line.strip() and not line.startswith('%')]
    
    current_line = 0
    # 读取相机数量和点云数量
    num_cameras, num_points = map(int, lines[current_line].split())
    current_line += 1
    
    # 解析相机参数
    camera_list = []
    for _ in range(num_cameras):
        # 读取3行旋转矩阵
        rotation_matrix = np.array([
            list(map(float, lines[current_line + i].split())) 
            for i in range(3)
        ])
        current_line += 3
        # 读取平移向量
        translation_vec = np.array(list(map(float, lines[current_line].split())))
        current_line += 1
        # 读取内参(fx, fy, cx, cy, k1, k2)
        intrinsics = np.array(list(map(float, lines[current_line].split())))
        current_line += 1
        
        camera_list.append({
            'rotation': rotation_matrix,
            'translation': translation_vec,
            'intrinsics': intrinsics
        })
    
    # 解析点云数据
    point_list = []
    for _ in range(num_points):
        # 读取3D坐标
        coords_3d = np.array(list(map(float, lines[current_line].split())))
        current_line += 1
        # 读取RGB颜色值
        rgb_color = np.array(list(map(int, lines[current_line].split())))
        current_line += 1
        # 读取观测记录(相机索引、特征索引)
        observations = []
        while current_line < len(lines) and len(lines[current_line].split()) == 2:
            cam_idx, feat_idx = map(int, lines[current_line].split())
            observations.append((cam_idx, feat_idx))
            current_line += 1
        
        point_list.append({
            'coords': coords_3d,
            'rgb': rgb_color,
            'observations': observations
        })
    
    return {
        'num_cameras': num_cameras,
        'num_points': num_points,
        'cameras': camera_list,
        'points': point_list
    }

# 使用示例
if __name__ == "__main__":
    mat_data = load_vsfm_ascii_mat("your_mat_file.mat")
    print(f"成功加载:{mat_data['num_cameras']} 个相机,{mat_data['num_points']} 个点云")
    # 可以查看第一个相机的内参
    print("第一个相机内参:", mat_data['cameras'][0]['intrinsics'])
    # 可以查看第一个点云的坐标
    print("第一个点云坐标:", mat_data['points'][0]['coords'])

代码说明

  1. 文件预处理:跳过所有以%开头的注释行和空行,只保留有效数据行
  2. 相机参数解析:每个相机包含3行旋转矩阵、1行平移向量、1行内参(包含焦距、主点坐标、畸变系数)
  3. 点云数据解析:每个点包含3D坐标、RGB颜色值,以及一系列观测记录(记录该点在哪个相机的哪个特征位置被观测到)
  4. 兼容性:这个代码完全匹配你提供的示例文件格式,如果你的其他Visual SFM生成文件结构略有差异(比如内参参数数量变化),可以根据实际文件内容调整对应解析部分

内容的提问来源于stack exchange,提问作者Breadbao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 12:32:57