| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 | function Geometry = am2geom(AmiraMeshFile)% Geometry = am2geom(AmiraMeshFile) converts an AmiraMesh (.am) file to a % geometry structure, as long as the .am file is written in the recognized % format.  The Geometry structure has the form:%% Geometry = %          start: [3x1 double]%     voxel_size: [3x1 double]%           data: [MxNxQ double]%% Example acceptable .am file format:%% # AmiraMesh 3D BINARY 2.0% % # CreationDate: Thu Jun 01 15:42:59 2006% % % define Lattice 509 509 3% % Parameters {% Content "509x509x36 short, uniform coordinates",% BoundingBox -25.48 25.32 -25.48 25.32 9 26.5,% CoordType "uniform"% }% % Lattice { short Data } @1% % # Data section follows% @1%% Ryan T Flynn 23 August 2007% % ensure that the user input a stringif ~ischar(AmiraMeshFile)    error('AmiraMeshFile must be a character string.');end% open the filefid = fopen(AmiraMeshFile,'r');if fid == -1    error('Could not open %s.',AmiraMeshFile);end% Things to look for in the .am file:% 1) The 'BINARY' or 'ASCII' words% 2) The lattice size after the 'define Lattice' words% 3) The BoundingBox line, which is used to calculate start and voxel_size% 4) CoordType "uniform" linetline = fgetl(fid);% continue to read the file until the line containing only '@1' is foundwhile ~strncmp(tline,'@1',2)    if ~isempty(regexp(tline,'AmiraMesh 3D'))        % found the BINARY or ASCII specification line        p = regexp(tline,'AmiraMesh 3D');  % find the position of the key words        r = tline(p+length('AmiraMesh 3D'):end);  % get the remainder of the string        binORascii = strtok(r);  % pop off the data type (either BINARY or ASCII)    end    if ~isempty(regexp(tline,'define Lattice'))        % found the lattice definition line        p = regexp(tline,'define Lattice');  % find the position of the key words        r = tline(p+length('define Lattice'):end);  % get the remainder of the string        siz = str2num(r);  % convert the remainder to the lattice dimensions        if length(siz) ~= 3            error('Data lattice must be 3D.');        end    end        if ~isempty(regexp(tline,'BoundingBox'))        % found the bounding box line        p = regexp(tline,'BoundingBox');  % position of BoundingBox word        r = tline(p+length('BoundingBox'):end); % remainder of the string        box = str2num(r);  % convert the remainder to the box dimensions        if length(box) ~= 6            error('Number of parameters in BoundingBox line must be 6.');        end    end    % Lattice { short Data } @1    if ~isempty(regexp(tline,'Lattice {'))        % found line that contains the data type for the grid        p = regexp(tline,'Lattice {');  % position of BoundingBox word        r = tline(p+length('Lattice {'):end); % remainder of the string        AmiraDataType = strtok(r);  % pop off the data type        % Figure out what the data type is        for k=1:6            if strcmp(AmiraDataType,'byte')                MatlabDataType = 'int8';            elseif strcmp(AmiraDataType,'short')                MatlabDataType = 'int16';            elseif strcmp(AmiraDataType,'ushort')                MatlabDataType = 'uint16';            elseif strcmp(AmiraDataType,'int32')                MatlabDataType = 'int32';            elseif strcmp(AmiraDataType,'float')                MatlabDataType = 'single';            elseif strcmp(AmiraDataType,'double')                MatlabDataType = 'double';            else                error('Amira data type in %s is not supported by Matlab.',AmiraMeshFile);            end        end    end    tline = fgetl(fid);end% ensure that all of the required lines were foundif ~exist('binORascii')    error('Could not determine of data are stored in binary or ascii format.');endif ~exist('siz')    error('Could not find the data dimensions during the reading process.');endif ~exist('box')    error('Could not find the bounding box in the reading process.');endif ~exist(MatlabDataType)    error('Could not find the data type for file %s.',AmiraMeshFile);end% ensure that the data are stored in binary formatif ~strcmp(binORascii,'BINARY')    error('Data in %s must be stored in binary format.',AmiraMeshFile);end% calculate the voxel_size vectorif siz(1) == 1    Geometry.voxel_size(1) = box(2) - box(1);elseif siz(1) > 1    Geometry.voxel_size(1) = (box(2) - box(1))/(siz(1)-1);else    error('First dimension of data lattice must be greater than zero.');endif siz(2) == 1    Geometry.voxel_size(2) = box(4) - box(3);elseif siz(2) > 1    Geometry.voxel_size(2) = (box(4) - box(3))/(siz(2)-1);else    error('Second dimension of data lattice must be greater than zero.');endif siz(3) == 1    Geometry.voxel_size(3) = box(6) - box(5);elseif siz(3) > 1    Geometry.voxel_size(3) = (box(6) - box(5))/(siz(3)-1);else    error('Third dimension of data lattice must be greater than zero.');end% calculate the start vectorGeometry.start(1) = box(1);Geometry.start(2) = box(3);Geometry.start(3) = box(5);% allocate space for the dataGeometry.data = zeros(siz,MatlabDataType);% read in the dataGeometry.data = fread(fid,[MatlabDataType '=>' MatlabDataType],'ieee-be');% If reading byte-by-byte, throw out last byte -- it's just a carriage returnif strcmp(MatlabDataType,'int8')    Geometry.data(end,:) = [];endGeometry.data = reshape(Geometry.data,siz(1),siz(2),siz(3));% close the AmiraMesh filefclose(fid);
 |