MATLAB对ply文件格式的读取和显示
转自:https://blog.csdn.net/lafengxiaoyu/article/details/60574150
在网上搜索这个题目可以找到一些类似的文章,其来源大致都是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 );endBuf = 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 filePropertyNames = []; % structure of lists of property nameswhile ( 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;endend
%
% 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.');endend
%
% Read a comment.
%case 'comment'NumComments = NumComments + 1;Comments{NumComments} = '';for i = 2 : CountComments{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},'''.']);endNumElements = 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]);endelseerror(['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])');elsefclose ( fid );if ( isempty(CurElement) )error(['Property definition without element definition: ',Buf]);elseerror(['Bad property definition: ',Buf]);endend
%
% End of header.
%case 'end_header'break;endendend
%
% Set reading for specified data format.
%if ( isempty ( Format ) )warning('Data format unspecified, assuming ASCII.');Format = 'ascii';endswitch Formatcase 'ascii'Format = 0;case 'binary_little_endian'Format = 1;case 'binary_big_endian'Format = 2;otherwisefclose ( 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' );elsefid = 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/LFi = [i,findstr(Buf,['end_header',10])]; % look for end_header + LFif ( isempty(i) )tmp = tmp + BufSize;Buf = [Buf(BufSize+1:BufSize+10),char(fread(fid,BufSize,'uchar')')];endend
%
% 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 : NumPropertiesToken = getfield(CurPropertyTypes,CurPropertyNames{j});if ( strcmpi(Token{1},'list') )Type(j) = 1;elseType(j) = 0;end
%
% Glenn Ramsey 20120827
% Initialise Type2{} to prevent uninitialised value error.
%Type2{j} = '';end
%
% Parse the buffer.
%if ( ~any(Type) )% no list typesData = reshape ( ...Buf(BufOff:BufOff+ElementCount(i)*NumProperties-1), ...NumProperties, ElementCount(i) )';BufOff = BufOff + ElementCount(i) * NumProperties;elseListData = cell(NumProperties,1);for k = 1 : NumPropertiesListData{k} = cell(ElementCount(i),1);end
%
% list type
%for j = 1 : ElementCount(i)for k = 1 : NumPropertiesif ( ~Type(k) )Data(j,k) = Buf(BufOff);BufOff = BufOff + 1;elsetmp = Buf(BufOff);ListData{k}{j} = Buf(BufOff+(1:tmp))';BufOff = BufOff + tmp + 1;endendendend
%
% Read binary data.
%else
% translate PLY data type names to MATLAB data type namesListFlag = 0; % = 1 if there is a list typeSameFlag = 1; % = 1 if all types are the samefor j = 1 : NumPropertiesToken = getfield(CurPropertyTypes,CurPropertyNames{j});
%
% Non-list type.
%if ( ~strcmp(Token{1},'list' ) )tmp = rem(strmatch(Token{1},PlyTypeNames,'exact')-1,8)+1;if ( ~isempty(tmp) )TypeSize(j) = SizeOf(tmp);Type{j} = MatlabTypeNames{tmp};TypeSize2(j) = 0;Type2{j} = '';SameFlag = SameFlag & strcmp(Type{1},Type{j});elsefclose(fid);error(['Unknown property data type, ''',Token{1},''', in ', ...ElementNames{i},'.',CurPropertyNames{j},'.']);endelse % list typeif ( length(Token) == 3 )ListFlag = 1;SameFlag = 0;tmp = rem(strmatch(Token{2},PlyTypeNames,'exact')-1,8)+1;tmp2 = rem(strmatch(Token{3},PlyTypeNames,'exact')-1,8)+1;if ( ~isempty(tmp) & ~isempty(tmp2) )TypeSize(j) = SizeOf(tmp);Type{j} = MatlabTypeNames{tmp};TypeSize2(j) = SizeOf(tmp2);Type2{j} = MatlabTypeNames{tmp2};elsefclose(fid);error(['Unknown property data type, ''list ',Token{2},' ',Token{3},''', in ', ...ElementNames{i},'.',CurPropertyNames{j},'.']);endelsefclose(fid);error(['Invalid list syntax in ',ElementNames{i},'.',CurPropertyNames{j},'.']);endendend
% read fileif ( ~ListFlag )
%
% No list types, all the same type (fast)
%if ( SameFlag )Data = fread(fid,[NumProperties,ElementCount(i)],Type{1})';
%
% No list types, mixed type.
%elseData = zeros(ElementCount(i),NumProperties);for j = 1 : ElementCount(i)for k = 1 : NumPropertiesData(j,k) = fread(fid,1,Type{k});endendendelseListData = cell(NumProperties,1);for k = 1 : NumPropertiesListData{k} = cell(ElementCount(i),1);endif ( NumProperties == 1 )BufSize = 512;SkipNum = 4;j = 0;
%
% List type, one property (fast if lists are usually the same length)
%while ( j < ElementCount(i) )BufSize = min(ElementCount(i)-j,BufSize);Position = ftell(fid);
%
% Read in BufSize count values, assuming all counts = SkipNum
%[Buf,BufSize] = fread(fid,BufSize,Type{1},SkipNum*TypeSize2(1));Miss = find(Buf ~= SkipNum); % find first count that is not SkipNumfseek(fid,Position + TypeSize(1),-1); % seek back to after first countif ( isempty(Miss) )
% all counts are SkipNumBuf = fread(fid,[SkipNum,BufSize],[int2str(SkipNum),'*',Type2{1}],TypeSize(1))';fseek(fid,-TypeSize(1),0); % undo last skipfor k = 1:BufSizeListData{1}{j+k} = Buf(k,:);endj = j + BufSize;BufSize = floor(1.5*BufSize);else
%
% Some counts are SkipNum.
%if ( 1 < Miss(1) )Buf2 = fread(fid,[SkipNum,Miss(1)-1],[int2str(SkipNum),'*',Type2{1}],TypeSize(1))';for k = 1:Miss(1)-1ListData{1}{j+k} = Buf2(k,:);endj = j + k;end
%
% Read in the list with the missed count.
%SkipNum = Buf(Miss(1));j = j + 1;ListData{1}{j} = fread(fid,[1,SkipNum],Type2{1});BufSize = ceil(0.6*BufSize);endendelse
%
% List type(s), multiple properties (slow)
%Data = zeros(ElementCount(i),NumProperties);for j = 1:ElementCount(i)for k = 1:NumPropertiesif ( isempty(Type2{k}) )Data(j,k) = fread(fid,1,Type{k});elsetmp = fread(fid,1,Type{k});ListData{k}{j} = fread(fid,[1,tmp],Type2{k});endendendendendend
%
% Put data into Elements structure
%for k = 1 : NumPropertiesif ( ( ~Format && ~Type(k) ) || (Format && isempty(Type2{k})) )eval(['Elements.',ElementNames{i},'.',CurPropertyNames{k},'=Data(:,k);']);elseeval(['Elements.',ElementNames{i},'.',CurPropertyNames{k},'=ListData{k};']);endendendclear Dataclear ListData;fclose ( fid );
%
% Output the data as a triangular mesh pair.
%if ( ( nargin > 1 & strcmpi(Str,'Tri') ) || nargout > 2 )
%
% Find vertex element field
%Name = {'vertex','Vertex','point','Point','pts','Pts'};Names = [];for i = 1 : length(Name)if ( any ( strcmp ( ElementNames, Name{i} ) ) )Names = getfield(PropertyNames,Name{i});Name = Name{i};break;endendif ( any(strcmp(Names,'x')) & any(strcmp(Names,'y')) & any(strcmp(Names,'z')) )eval(['varargout{1}=[Elements.',Name,'.x,Elements.',Name,'.y,Elements.',Name,'.z];']);elsevarargout{1} = zeros(1,3);endvarargout{1} = varargout{1}';varargout{2} = Elements;varargout{3} = Comments;Elements = [];
%
% Find face element field
%Name = {'face','Face','poly','Poly','tri','Tri'};Names = [];for i = 1 : length(Name)if ( any(strcmp(ElementNames,Name{i})) )Names = getfield(PropertyNames,Name{i});Name = Name{i};break;endendif ( ~isempty(Names) )% find vertex indices property subfieldPropertyName = {'vertex_indices','vertex_indexes','vertex_index','indices','indexes'};for i = 1 : length(PropertyName)if ( any(strcmp(Names,PropertyName{i})) )PropertyName = PropertyName{i};break;endend
%
% Convert face index list to triangular connectivity.
%if ( ~iscell(PropertyName) )eval(['FaceIndices=varargout{2}.',Name,'.',PropertyName,';']);N = length(FaceIndices);Elements = zeros(3,N*2);Extra = 0;for k = 1 : NElements(1:3,k) = FaceIndices{k}(1:3)';
%
% The original code had an error in the following loop.
%for j = 4 : length(FaceIndices{k})Extra = Extra + 1;Elements(1,N + Extra) = FaceIndices{k}(1);Elements(2,N + Extra) = FaceIndices{k}(j-1);Elements(3,N + Extra) = FaceIndices{k}(j);endend
%
% Add 1 to each vertex value; PLY vertices are zero based.
%Elements = Elements(:,1:N+Extra) + 1;endendelsevarargout{1} = Comments;endreturn
end
输入的参数是两个,一个是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));
MATLAB对ply文件格式的读取和显示相关推荐
- imread函数 matlab_【MATLAB图像处理学习】1.读取和显示图片
CHAPTER2 图像处理的基础函数 [使用的教材:冈萨雷斯 数字图像处理MATLAB(Digital image processing with Matlab] [原书图片下载地址:点这里] 先介绍 ...
- PLY文件读取与显示
用OpenGL写了一份读取PLY文件并显示的代码,支持以下关键字: ply/format/element vertex/property/element face/end_header 以及数据类型: ...
- matlab显示YCrCb的图像,【Matlab系列】读取并显示YUV视频文件
Date: 2019-5-12 1.读取并显示YUV视频文件Matlab代码 %% 1.读取视频内容并显示 fid = fopen('akiyo_cif.yuv','r'); %读入YUV文件 row ...
- PLY点云数据在PCL中读取与显示
今天开始着手处理PLY数据,由于之前没有接触过PCL,所以连最简单的数据读取与显示都搞了半天,现在将代码公布出来以供参考. 使用的环境是:vs2015+pcl1.8.1 #include " ...
- 用Matlab读取、显示并保存图片
用Matlab读取.显示并保存图片 文章目录 用Matlab读取.显示并保存图片 读取图片 显示图片 保存图片 读取图片 建立读取图片的脚本 x=imread('图像名.bmp'); %这里是相对路径 ...
- matlab怎么输出图像文件夹,Matlab读取图片 显示和保存图像的相关操作
当前有部份朋友还不清楚Matlab读取图片 显示和保存图像的操作,所以下面绿软吧就带来Matlab读取图片 显示和保存图像的相关操作,一起来看看吧! Matlab读取图片 显示和保存图像的相关操作 打 ...
- PLY文件格式及其MATLAB读写操作
PLY是一种电脑档案格式,全名为多边形档案(Polygon File Format)或 斯坦福三角形档案(Stanford Triangle Format). 史丹佛大学的 The Digital M ...
- livechart 只显示 y 值_基于Python语言的SEGY格式地震数据读取与显示编程
敬请关注<地学新视野> 摘要:本文简单介绍了SEG-Y地震数据文件格式,以及如何用Python语言编写读写SEG-Y格式的地震数据并绘制地震剖面,其中用到了Segyio和matplotli ...
- Matlab数字图像处理——图像文件的读取
文章目录 一.Matlab中获取图像信息的函数 imfinfo 二.Matlab读取图像文件的函数 imread 三.Matlab保存图像文件的函数 imwrite 完整目录 一.Matlab中获取图 ...
最新文章
- 扩展运算符,Object.assign
- Matplotlib - 柱状图、直方图、条形图 bar() barh() 所有用法详解
- BugkuCTF-WEB题GET和POST
- spring-kafka、kafka-client 和springboot的版本对应关系
- Output Arcade for Mac - 新型音频合成器
- python 离散点 等高线_飞时达软件离散点高程、等高线高程、特征线高程等检查与处理...
- 解决vmware16安装win7时安装不了vmtools
- 《我与长安城的朝花夕拾》
- 为什么设置了面容ID,仍然需要输入密码解锁iPhone?
- nats断链情况总结
- 微信小程序开发者工具的使用
- LaTex 最狠的网站 嘎嘎狠
- 化工行业危化品实时监控/厂区监控解决方案:EasyGBS如何保障危化品安全生产?
- SSL代理是什么?有哪些使用场景?
- excel图表技巧:如何在折线图上标注极值
- 2021年全国职业技能大赛:网络系统管理项目
- html转pdf中文不显示解决方法
- Pycharm项目使用pyinstalle打包过程中问题及解决方案
- 调整计算机启动顺序,电脑双硬盘双系统bios调整硬盘启动顺序的图文教程
- Word+Excel+PPT 2016三合一