matlab - 如何通过 3D 图像可视化解决此问题?

标签 matlab image-processing multidimensional-array plot visualization

我有需要可视化的 3D 图像数据。我已经能够使用 imshow3D 通过 2D 切片对其进行可视化,但我希望在 3D 空间中查看图像数据。

我使用的代码如下(礼貌: How do i create a rectangular mask at known angles? ),但我不知道为什么它不显示:

% create input image
imageSizeX = 120;
imageSizeY = 200;
imageSizeZ = 50

% generate 3D grid
[columnsInImage, rowsInImage, pagesInImage] = meshgrid(1:imageSizeX, 1:imageSizeY, 1:imageSizeZ);

% create the sphere in the image.
centerY  = imageSizeY/2;
centerX  = imageSizeX/2;
centerZ  = imageSizeZ/2;
diameter = 56;
radius   = diameter/2;

sphereVoxels = (rowsInImage - centerY).^2 ...
    + (columnsInImage - centerX).^2 + (pagesInImage - centerZ).^2 <= radius.^2;


% change image from logical to numeric labels.
Img   = double(sphereVoxels);
for ii = 1:numel(Img)
    if Img(ii) == 0
        Img(ii) = 2;  % intermediate phase voxels
    end 
 end



% specify the desired angle
angle = 60;                     

% specify desired pixel height and width of solid
width  = imageSizeX;    
height = imageSizeY;
page   = imageSizeZ;

% Find the row point at which theta will be created
y = centerY - ( radius*cos(angle * pi/180) ) 

% determine top of the solid bar
y0 = max(1, y-height); 

% label everything from y0 to y to be = 3 (solid)
Img(y0:y, 1:width, 1:page)=3;   
% figure, imshow3D(Img);
% axis on;
% grid on;


% display it using an isosurface 
fv = isosurface(Img, 0);
patch(fv,'FaceColor',[0 0 .7],'EdgeColor',[0 0 1]);  title('Binary volume of a sphere');
view(45,45);
axis tight;
grid on;
xlabel('x-axis [pixels]'); ylabel('y-axis [pixels]'); zlabel('z-axis [pixels]')

尽管实心条不是如下图所示的对角线,但我希望图像与此类似:

enter image description here

我不知道我到底做错了什么。

最佳答案

关于代码中的问题,看来您将球体内的点设置为 1,然后将球体外部的所有剩余点设置为 2,然后将 y 平面的截面设置为 3。没有值在本例中,卷中的值为 0,因此尝试获取 isosurface值为 0 时不会找到任何内容。

但是,如果您想创建一个类似 Minecraft 的“体素化”表面,就像在示例图像中显示体素的各个方面一样,那么我为您提供了另一个选择...

首先,我按照您在示例中所做的那样创建了一组体积数据,但我省略了将值设置为 2 的 for 循环,而是将实心条的值设置为 2。

接下来,我使用了一个在我的一些 3D 项目中使用过的函数 build_voxels:

function [X, Y, Z, C] = build_voxels(roiMask)
  maskSize = size(roiMask);

  % Create the ROI surface patches pointing toward -x:
  index = find(diff(padarray(roiMask, [1 0 0], 'pre'), 1, 1) > 0);
  [X1, Y1, Z1, C1] = make_patches([-1 -1 -1 -1], [1 1 -1 -1], [-1 1 1 -1]);

  % Create the ROI surface patches pointing toward +x:
  index = find(diff(padarray(roiMask, [1 0 0], 'post'), 1, 1) < 0);
  [X2, Y2, Z2, C2] = make_patches([1 1 1 1], [-1 -1 1 1], [-1 1 1 -1]);

  % Create the ROI surface patches pointing toward -y:
  index = find(diff(padarray(roiMask, [0 1 0], 'pre'), 1, 2) > 0);
  [X3, Y3, Z3, C3] = make_patches([-1 -1 1 1], [-1 -1 -1 -1], [-1 1 1 -1]);

  % Create the ROI surface patches pointing toward +y:
  index = find(diff(padarray(roiMask, [0 1 0], 'post'), 1, 2) < 0);
  [X4, Y4, Z4, C4] = make_patches([1 1 -1 -1], [1 1 1 1], [-1 1 1 -1]);

  % Create the ROI surface patches pointing toward -z:
  index = find(diff(padarray(roiMask, [0 0 1], 'pre'), 1, 3) > 0);
  [X5, Y5, Z5, C5] = make_patches([1 1 -1 -1], [-1 1 1 -1], [-1 -1 -1 -1]);

  % Create the ROI surface patches pointing toward +z:
  index = find(diff(padarray(roiMask, [0 0 1], 'post'), 1, 3) < 0);
  [X6, Y6, Z6, C6] = make_patches([-1 -1 1 1], [-1 1 1 -1], [1 1 1 1]);

  % Collect patch data:
  X = [X1 X2 X3 X4 X5 X6];
  Y = [Y1 Y2 Y3 Y4 Y5 Y6];
  Z = [Z1 Z2 Z3 Z4 Z5 Z6];
  C = [C1 C2 C3 C4 C5 C6];

  function [Xp, Yp, Zp, Cp] = make_patches(Xo, Yo, Zo)
    [Xp, Yp, Zp] = ind2sub(maskSize, index);
    Xp = bsxfun(@plus, Xp, Xo./2).';
    Yp = bsxfun(@plus, Yp, Yo./2).';
    Zp = bsxfun(@plus, Zp, Zo./2).';
    Cp = index(:).';
  end
end

此函数接受 3D 矩阵,最好是要为其创建表面的体积区域的逻辑掩码,并返回 4 个 4×N 矩阵:X/Y/Z 矩阵用于体素面片和索引矩阵C,可用于从体数据矩阵获取值以用于为每个表面着色。

这是渲染表面的代码:

[X, Y, Z, C] = build_voxels(Img > 0);
rgbData = reshape([1 0 0; 1 1 0], [2 1 3]);
hSurface = patch(X, Y, Z, rgbData(Img(C), :, :), ...
                 'AmbientStrength', 0.5, ...
                 'BackFaceLighting', 'unlit', ...
                 'EdgeColor', 'none', ...
                 'FaceLighting', 'flat');
axis equal;
axis tight;
view(45, 45);
grid on;
xlabel('x-axis (voxels)');
ylabel('y-axis (voxels)');
zlabel('z-axis (voxels)');
light('Position', get(gca, 'CameraPosition'), 'Style', 'local');

情节如下:

enter image description here

请注意,球体和条形表面的颜色不同,因为它们在体积数据 Img 中分别标记为值 1 和 2。这些值是使用 CImg 中提取的,然后用作 rgbData 的索引,其中包含红色(第一行)和黄色(第二行) ) RGB 三元组。这将创建一个 N×1×3 矩阵 polygon face colors .

关于matlab - 如何通过 3D 图像可视化解决此问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43948680/

相关文章:

language-agnostic - 文档图像处理

vb.net - 加载图像时出现内存不足异常

java - Java中Hypergraph上实现节点的JSON结构

c - 在 C 中将静态分配的二维数组作为函数参数传递

MATLAB:当有多个最大值时,如何不获取第一个元素而是从 "max"获取随机索引?

matlab - 是否可以在 Windows 8 上安装适用于 Windows 7 的 Windows SDK?

image-processing - OpenCV:如何知道HaarTraining的进度状态

python - 如何根据目标像素替换 Numpy 图像数组中的所有 RGB 值

matlab - 如何在 MATLAB 中找到矩阵列中最大值的索引?

matlab - 什么是函数句柄,它有什么用?