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

Octave读取混合类型二进制数组及二进制.ply文件方法咨询

Octave实现二进制PLY文件读取

需求说明

我正在编写用于读取二进制格式.ply文件的函数,逻辑为:先读取文件头,跳转到二进制数据起始位置后直接读取整块数据,现在需要在Octave中复现该功能。

现有读取头代码

fid = fopen('/path/to/file.ply');
tline = fgetl(fid); % 读取第一行
len = 0;
prop = {};
dtype = {};
fmt = 'binary';

while ~strcmp(tline, "end_header")

    len = len + length(tline) + 1; % 统计头长度,+1包含换行符
    tline = strsplit(tline); % 拆分字符串
    if strcmp('format', tline{1}) && strcmp('ascii', tline{2}) % 判断是否为ascii格式文件
        fmt = 'ascii';
    end
    if strcmp('element', tline{1}) && strcmp('vertex', tline{2}) % 读取顶点数量
        N = tline{3};
    end
    if strcmp('property', tline{1}) % 识别字段
        dtype = [dtype, tline{2}];
        prop = [prop, tline{3}];
    end
    tline = fgetl(fid);
end
len = len + length(tline) + 1; % 把end_header行的长度计入总头长度

已获取的参数

目前已经解析得到数据类型数组:

dtype =
{
  [1,1] = float
  [1,2] = float
  [1,3] = float
  [1,4] = int
  [1,5] = int
  [1,6] = int
  [1,7] = float
  [1,8] = float
  [1,9] = float
}

以及顶点数量:

N = 61415

问题描述

想知道Octave中是否有可以替代numpy fromfile的函数,是否可以通过seek定位到文件中二进制数据的起始位置(已通过len变量获取到二进制数据的起始偏移量)读取混合类型的二进制数组?

我尝试了如下代码:

fseek(fid, len);
fread(fid, 3, 'float')

这段代码返回了正确的3个float值,但接下来的int值读取错误:

fread(fid, 4, 'float')

arr =

  -1.4298e+00
  -5.3943e+00
   1.6623e+01
   1.5274e-43 <<<< 预期值为109

最终解决方案

最终通过循环实现了功能,代码如下:

function pts = read_ply(fn)

    fid = fopen(fn);
    tline = fgetl(fid); % 读取第一行

    len = 0;
    prop = {};
    % dtype_map = {'float': 'f4', 'uchar': 'B', 'int':'i'}
    dtype = {};
    fmt = 'binary';

    while ~strcmp(tline, "end_header")

        len = len + length(tline) + 1; % 统计头长度,+1包含换行符

        tline = strsplit(tline); % 拆分字符串
        if strcmp('format', tline{1}) && strcmp('ascii', tline{2}) % 判断是否为ascii格式文件
            fmt = 'ascii';
        elseif strcmp('element', tline{1}) && strcmp('vertex', tline{2}) % 读取顶点数量
            N = str2num(tline{3});
        elseif strcmp('property', tline{1}) % 识别字段
            dtype = [dtype, tline{2}];
            prop = [prop, tline{3}];
        endif
        tline = fgetl(fid);
    endwhile

    len = len + length(tline) + 1; % 把end_header行的长度计入总头长度
    
% 计算二进制数据总长度
fseek(fid, 0, 1);
file_length = ftell(fid) - len;

types = struct('float', 4, 'int', 4, 'float64', 8);
pts = struct();
seek_plus = 0;

for i = 1:length(prop)
    fseek(fid, len + seek_plus);
    dt = types.(dtype{i}); % 读取对应字段的字节长度
    pts.(prop{i}) = fread(fid, N, dtype{i}, int32(file_length / N) - dt);
    seek_plus = seek_plus + dt;
endfor

该方案使用了循环,虽然没有直接找到替代numpy fromfile的函数,但运行效率不错,最终可以通过如下方式构造数组:

xyz = [pts.x, pts.y, pts.z];

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 22:36:03