承接(一)由数组到图像:统一matlab、商业软件avizo以及开源软件quant3d、homogenization坐标系
(二)由图像到数组:统一matlab和avizo坐标系
对于微观结构,通过CT扫描获得影像数据并且在商业软件avizo中处理,因此本文以avizo中的坐标系为基准,探索其导出的结果导入matlab后坐标系是否一致
avizo中做完阈值分割后的三维二值图像有两种导出3d文件的方式
- 直接导出3d文件,导出.raw格式的文件(对应Raw Data 3D格式)
- 另一种格式的3d文件,.mrc格式(MRC Stack)。mrc与raw格式的区别在于,对于二值图像,raw必须知道图像的每个维度的尺寸,而mrc文件中已经包含了。
对于非阈值分割的原始XCT灰度图像,要利用ReadGreyMRC3d函数。ReadBinaryMRC3d函数针对的是二值化图像。其区别在图像储存精度的差异,如下
对于序列的2d文件,如2D的tif以及dcm格式的有待进一步验证
将avizo的图像导出,然后用matlab读取,代码如下
clc
clear
A3d=fread(fopen('test.raw'));
A3d=reshape(A3d,[100,100,100]);
myvolshow(A3d)
filepath = 'test.mrc';
A3dmrc=ReadBinaryMRC3d(filepath);
myvolshow(A3dmrc)
filepath='XCT.mrc';
A3dmrc=ReadGreyMRC3d(filepath);
myvolshow(A3dmrc>9500) %9500为分割的阈值
function A3dmrc=ReadBinaryMRC3d(filepath)
% % 指定.mrc文件的路径
% filepath = 'test.mrc';
% 打开.mrc文件
fileID = fopen(filepath, 'r', 'ieee-le'); % 'ieee-le'表示小端序(Little-Endian)
% 读取.mrc文件的头信息
headerSize = 1024; % MRC文件头信息的大小(通常是1024字节)
header = fread(fileID, headerSize, 'int32');
% 读取.mrc文件中的三维数据
xSize = header(1);
ySize = header(2);
zSize = header(3);
numSlices = zSize; % 3D数据的切片数量就是z轴的大小
% 计算数据区域的大小
dataSize = xSize * ySize * zSize;
% 移动文件指针到数据区域
fseek(fileID, headerSize, 'bof');
% 读取三维数据(根据实际数据类型选择正确的格式)
imageStack = fread(fileID);
% 将线性数组转换为三维数组
A3dmrc = reshape(imageStack, [xSize, ySize, zSize]);
% 关闭文件
fclose(fileID);
end
function A3dmrc=ReadGreyMRC3d(filepath)
% % 指定.mrc文件的路径
% filepath = 'test.mrc';
% 打开.mrc文件
% 打开文件进行读取
fid = fopen(filepath, 'rb');
% 解析文件头部信息
header_data = fread(fid, 3, 'int32');
image_width = header_data(1);
image_height = header_data(2);
image_depth = header_data(3);
headerSize = 1024; % MRC文件头信息的大小(通常是1024字节)
% 移动文件指针到数据区域
fseek(fid, headerSize, 'bof');
% 读取三维图像数据(16 位无符号整数)
image_data = fread(fid, 'uint16');
% 将一维图像数据重新整理为三维数据
A3dmrc = reshape(image_data, [image_width, image_height, image_depth]);
fclose(fid);
end
function myvolshow(A3d)
%以行索引递增为x轴正向
%列索引递增为y正向
%第三维度递增为z轴正向
[m, n, p] = size(A3d);
newA3d=zeros(n,m,p);
for i=1:p
newA3d(:,:,i)=A3d(:,:,i)';
end
figure();
col=[.7 .7 .8];
hiso = patch(isosurface(newA3d,0),'FaceColor',col,'EdgeColor','none');
hiso2 = patch(isocaps(newA3d,0),'FaceColor',col,'EdgeColor','none');
axis equal;
lighting phong;
isonormals(newA3d,hiso);
alpha(0.5);
set(gca,'DataAspectRatio',[1 1 1])
camlight;
hold on;
axis off
%x轴红色
quiver3(0,0,0,1.1*m,0,0,'r','LineWidth',5,'MaxHeadSize',0.5);
text(1.1*m,0,0,'x','FontSize',30,'Color','r');
%y轴蓝色
quiver3(0,0,0,0,1.1*n,0,'b','LineWidth',5,'MaxHeadSize',0.5);
text(0,1.1*n,0,'y','FontSize',30,'Color','b');
%z轴绿色
quiver3(0,0,0,0,0,1.1*p,'g','LineWidth',5,'MaxHeadSize',0.5);
text(0,0,1.1*p,'z','FontSize',30,'Color','g');
view(135,45)
end
由此可见,利用以上的读取方式,坐标系完全一致。