首页 > 代码库 > MATLAB对ply文件格式的读取和显示
MATLAB对ply文件格式的读取和显示
在网上搜索这个题目可以找到一些类似的文章,其来源大致都是http://people.sc.fsu.edu/~jburkardt/m_src/ply_io/ply_io.html。但是并没有说明怎样运行和显示,因此我做这篇博客详细讲解一下。首先是这个ply_read.m文件
function [ Elements, varargout ] = PLY_READ ( Path, Str ) %*****************************************************************************80 % %% PLY_READ reads a PLY 3D data file. % % [DATA,COMMENTS] = PLY_READ(FILENAME) reads a version 1.0 PLY file % FILENAME and returns a structure DATA. The fields in this structure % are defined by the PLY header; each element type is a field and each % element property is a subfield. If the file contains any comments, % they are returned in a cell string array COMMENTS. % % [TRI,PTS] = PLY_READ(FILENAME,‘tri‘) or % [TRI,PTS,DATA,COMMENTS] = PLY_READ(FILENAME,‘tri‘) converts vertex % and face data into triangular connectivity and vertex arrays. The % mesh can then be displayed using the TRISURF command. % % Note: This function is slow for large mesh files (+50K faces), % especially when reading data with list type properties. % % Example: % [Tri,Pts] = PLY_READ(‘cow.ply‘,‘tri‘); % [Tri,Pts] = PLY_READ(‘bunny.ply‘,‘tri‘); % trisurf(Tri,Pts(:,1),Pts(:,2),Pts(:,3)); % colormap(gray); axis equal; % % Discussion: % % The original version of this program had a mistake that meant it % did not properly triangulate files whose faces were not already triangular. % This has been corrected (JVB, 25 February 2007). % % Glenn Ramsey pointed out and corrected a problem that occurred % with an uninitialized value of Type2, 27 August 2012. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 27 August 2012 % % Author: % % Pascal Getreuer 2004 % % Parameters: % % Local Parameters: % % COMMENTS, any comments from the file. % % ELEMENTCOUNT, the number of each type of element in file. % % ELEMENTS, the element data. % % PROPERTYTYPES, the element property types. % % SIZEOF, size in bytes of each type. % % % Open the input file in "read text" mode. % [ fid, Msg ] = fopen ( Path, ‘rt‘ ); if ( fid == -1 ) error ( Msg ); end Buf = fscanf ( fid, ‘%s‘, 1 ); if ( ~strcmp ( Buf, ‘ply‘ ) ) fclose ( fid ); error(‘Not a PLY file.‘); end % % Read the header. % Position = ftell(fid); Format = ‘‘; NumComments = 0; Comments = {}; NumElements = 0; NumProperties = 0; Elements = []; ElementCount = []; PropertyTypes = []; ElementNames = {}; % list of element names in the order they are stored in the file PropertyNames = []; % structure of lists of property names while ( 1 ) % % Read a line from the file. % Buf = fgetl ( fid ); BufRem = Buf; Token = {}; Count = 0; % % Split the line into tokens. % while ( ~isempty(BufRem) ) [ tmp, BufRem ] = strtok(BufRem); % % Count the tokens. % if ( ~isempty ( tmp ) ) Count = Count + 1; Token{Count} = tmp; end end % % Parse the line. % if ( Count ) switch lower ( Token{1} ) % % Read the data format. % case ‘format‘ if ( 2 <= Count ) Format = lower ( Token{2} ); if ( Count == 3 & ~strcmp ( Token{3}, ‘1.0‘ ) ) fclose ( fid ); error(‘Only PLY format version 1.0 supported.‘); end end % % Read a comment. % case ‘comment‘ NumComments = NumComments + 1; Comments{NumComments} = ‘‘; for i = 2 : Count Comments{NumComments} = [Comments{NumComments},Token{i},‘ ‘]; end % % Read an element name. % case ‘element‘ if ( 3 <= Count ) if ( isfield(Elements,Token{2}) ) fclose ( fid ); error([‘Duplicate element name, ‘‘‘,Token{2},‘‘‘.‘]); end NumElements = NumElements + 1; NumProperties = 0; Elements = setfield(Elements,Token{2},[]); PropertyTypes = setfield(PropertyTypes,Token{2},[]); ElementNames{NumElements} = Token{2}; PropertyNames = setfield(PropertyNames,Token{2},{}); CurElement = Token{2}; ElementCount(NumElements) = str2double(Token{3}); if ( isnan(ElementCount(NumElements)) ) fclose ( fid ); error([‘Bad element definition: ‘,Buf]); end else error([‘Bad element definition: ‘,Buf]); end % % Read an element property. % case ‘property‘ if ( ~isempty(CurElement) & Count >= 3 ) NumProperties = NumProperties + 1; eval([‘tmp=isfield(Elements.‘,CurElement,‘,Token{Count});‘],... ‘fclose(fid);error([‘‘Error reading property: ‘‘,Buf])‘); if ( tmp ) error([‘Duplicate property name, ‘‘‘,CurElement,‘.‘,Token{2},‘‘‘.‘]); end % % Add property subfield to Elements. % eval([‘Elements.‘,CurElement,‘.‘,Token{Count},‘=[];‘], ... ‘fclose(fid);error([‘‘Error reading property: ‘‘,Buf])‘); % % Add property subfield to PropertyTypes and save type. % eval([‘PropertyTypes.‘,CurElement,‘.‘,Token{Count},‘={Token{2:Count-1}};‘], ... ‘fclose(fid);error([‘‘Error reading property: ‘‘,Buf])‘); % % Record property name order. % eval([‘PropertyNames.‘,CurElement,‘{NumProperties}=Token{Count};‘], ... ‘fclose(fid);error([‘‘Error reading property: ‘‘,Buf])‘); else fclose ( fid ); if ( isempty(CurElement) ) error([‘Property definition without element definition: ‘,Buf]); else error([‘Bad property definition: ‘,Buf]); end end % % End of header. % case ‘end_header‘ break; end end end % % Set reading for specified data format. % if ( isempty ( Format ) ) warning(‘Data format unspecified, assuming ASCII.‘); Format = ‘ascii‘; end switch Format case ‘ascii‘ Format = 0; case ‘binary_little_endian‘ Format = 1; case ‘binary_big_endian‘ Format = 2; otherwise fclose ( fid ); error([‘Data format ‘‘‘,Format,‘‘‘ not supported.‘]); end % % Read the rest of the file as ASCII data... % if ( ~Format ) Buf = fscanf ( fid, ‘%f‘ ); BufOff = 1; else % % ...or, close the file, and reopen in "read binary" mode. % fclose ( fid ); % % Reopen the binary file as LITTLE_ENDIAN or BIG_ENDIAN. % if ( Format == 1 ) fid = fopen ( Path, ‘r‘, ‘ieee-le.l64‘ ); else fid = fopen ( Path, ‘r‘, ‘ieee-be.l64‘ ); end % % Find the end of the header again. % Using ftell on the old handle doesn‘t give the correct position. % BufSize = 8192; Buf = [ blanks(10), char(fread(fid,BufSize,‘uchar‘)‘) ]; i = []; tmp = -11; while ( isempty(i) ) i = findstr(Buf,[‘end_header‘,13,10]); % look for end_header + CR/LF i = [i,findstr(Buf,[‘end_header‘,10])]; % look for end_header + LF if ( isempty(i) ) tmp = tmp + BufSize; Buf = [Buf(BufSize+1:BufSize+10),char(fread(fid,BufSize,‘uchar‘)‘)]; end end % % seek to just after the line feed % fseek ( fid, i + tmp + 11 + (Buf(i + 10) == 13), -1 ); end % % Read element data. % % PLY and MATLAB data types (for fread) % PlyTypeNames = {‘char‘,‘uchar‘,‘short‘,‘ushort‘,‘int‘,‘uint‘,‘float‘,‘double‘, ... ‘char8‘,‘uchar8‘,‘short16‘,‘ushort16‘,‘int32‘,‘uint32‘,‘float32‘,‘double64‘}; MatlabTypeNames = {‘schar‘,‘uchar‘,‘int16‘,‘uint16‘,‘int32‘,‘uint32‘,‘single‘,‘double‘}; SizeOf = [1,1,2,2,4,4,4,8]; for i = 1 : NumElements % % get current element property information % eval([‘CurPropertyNames=PropertyNames.‘,ElementNames{i},‘;‘]); eval([‘CurPropertyTypes=PropertyTypes.‘,ElementNames{i},‘;‘]); NumProperties = size(CurPropertyNames,2); % fprintf(‘Reading %s...\n‘,ElementNames{i}); % % Read ASCII data. % if ( ~Format ) for j = 1 : NumProperties Token = getfield(CurPropertyTypes,CurPropertyNames{j}); if ( strcmpi(Token{1},‘list‘) ) Type(j) = 1; else Type(j) = 0; end % % Glenn Ramsey 20120827 % Initialise Type2{} to prevent uninitialised value error. % Type2{j} = ‘‘; end % % Parse the buffer. % if ( ~any(Type) ) % no list types Data = http://www.mamicode.com/reshape ( ...>输入的参数是两个,一个是ply文件的位置,另一个是打开方式,一般为‘tri‘对于ply格式的解答这里有几篇文章可以参考:PLY文件格式剖析(一),PLY文件格式剖析(二)
PLY_DISPLAY这个函数也是类似的
但是事实上用txt直接读取ply格式确是有可能出现乱码的
但是某些只有点和面的信息的格式是被允许的
例如下图的棱锥
ply format ascii 1.0 comment created by MATLAB ply_write element vertex 5 property float x property float y property float z element face 6 property list uchar char vertex_indices end_header 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.500000 0.500000 1.600000 3 1 0 3 3 1 3 2 3 0 1 4 3 0 4 3 3 3 4 2 3 1 2 4此外,更为复杂的cow可以在我的资源页处下载,下面就是读取ply格式的文件了,这里文中给定的例子略微有点问题,应该调用的是矩阵的转置[Tri,Pts] = PLY_READ(‘coww.ply‘,‘tri‘); Pts=Pts‘; trisurf(Tri‘,Pts(:,1),Pts(:,2),Pts(:,3));
cow MATLAB绘制效果 meshlab显示效果 但是对于一般的ply文件利用这个函数却不能正确读出Tri来。。可能他的代码还有待改善吧。。MATLAB对ply文件格式的读取和显示
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。