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
相关产品推荐
相关产品推荐

