3
$\begingroup$

I have a capillary system and I want to convert this into a numeric matrix. My aim is to create a matrix with NxNxN dimensions of 1's and 0's where the 0's represent the capillary and the 1's represent the transparent region into the box (similar to 2d's case questioned and answered).

The capillary was built manually; it is consists of tubes with different diameters/radius

(*trunk*)
t0 = {{4, 4, 0}, {4, 4, 2}};
r0 = 0.7;
(*first branches*)
t11 = {{4, 4, 2}, {2, 4, 4}};
t12 = {{4, 4, 2}, {6, 4, 4}};
t13 = {{4, 4, 2}, {4, 2, 4}};
t14 = {{4, 4, 2}, {4, 6, 4}};
r1 = 0.4;
(*first branche's secondary branches*)
t21 = {{3, 4, 3}, {2, 5, 5}};
t22 = {{3, 4, 3}, {2, 3, 5}};
t23 = {{5, 4, 3}, {6, 5, 5}};
t24 = {{5, 4, 3}, {6, 3, 5}};
t25 = {{4, 3, 3}, {3, 2, 5}};
t26 = {{4, 3, 3}, {5, 2, 5}};
t27 = {{4, 5, 3}, {5, 6, 5}};
t28 = {{4, 5, 3}, {3, 6, 5}};
r2 = 0.2;
(*second branches*)
t31 = {{4, 2, 4}, {1, 0, 5}};
t32 = {{4, 2, 4}, {7, 0, 5}};
t33 = {{4, 6, 4}, {1, 8, 5}};
t34 = {{4, 6, 4}, {7, 8, 5}};
t35 = {{2, 4, 4}, {0, 7, 5}};
t36 = {{2, 4, 4}, {0, 1, 5}};
t37 = {{6, 4, 4}, {8, 7, 5}};
t38 = {{6, 4, 4}, {8, 1, 5}};
r3 = 0.3;
(* branches to center*)
t41 = {{4, 2, 4}, {4, 3, 6}};
t42 = {{4, 6, 4}, {4, 5, 6}};
t43 = {{2, 4, 4}, {3, 4, 6}};
t44 = {{6, 4, 4}, {5, 4, 6}};
r4 = 0.1;
(*branches to center (vertical)*)
t51 = {{4, 3, 6}, {4, 3, 8}};
t52 = {{4, 5, 6}, {4, 5, 8}};
t53 = {{3, 4, 6}, {3, 4, 8}};
t54 = {{5, 4, 6}, {5, 4, 8}};
r5 = 0.1;
(*secondary branches conection*)
t61 = {{3, 2, 5}, {1, 1, 8}};
t62 = {{5, 2, 5}, {7, 1, 8}};
t63 = {{5, 6, 5}, {7, 7, 8}};
t64 = {{3, 6, 5}, {1, 7, 8}};
t65 = {{2, 5, 5}, {1, 7, 8}};
t66 = {{6, 5, 5}, {7, 7, 8}};
t67 = {{6, 3, 5}, {7, 1, 8}};
r6 = 0.1;

To generate the tubes with different diameters, I joined the radius to the branches

(*trunk*)
J0 = {{{4, 4, 0}, {4, 4, 2}}, r0};(*start and end point*)
(*first branches*)
J11 = {{{4, 4, 2}, {2, 4, 4}}, r1};
J12 = {{{4, 4, 2}, {6, 4, 4}}, r1};
J13 = {{{4, 4, 2}, {4, 2, 4}}, r1};
J14 = {{{4, 4, 2}, {4, 6, 4}}, r1};
(*first branche's secondary branches*)
J21 = {{{3, 4, 3}, {2, 5, 5}}, r2};
J22 = {{{3, 4, 3}, {2, 3, 5}}, r2};
J23 = {{{5, 4, 3}, {6, 5, 5}}, r2};
J24 = {{{5, 4, 3}, {6, 3, 5}}, r2};
J25 = {{{4, 3, 3}, {3, 2, 5}}, r2};
J26 = {{{4, 3, 3}, {5, 2, 5}}, r2};
J27 = {{{4, 5, 3}, {5, 6, 5}}, r2};
J28 = {{{4, 5, 3}, {3, 6, 5}}, r2};
(*second branches*)
J31 = {{{4, 2, 4}, {1, 0, 5}}, r3};
J32 = {{{4, 2, 4}, {7, 0, 5}}, r3};
J33 = {{{4, 6, 4}, {1, 8, 5}}, r3};
J34 = {{{4, 6, 4}, {7, 8, 5}}, r3};
J35 = {{{2, 4, 4}, {0, 7, 5}}, r3};
J36 = {{{2, 4, 4}, {0, 1, 5}}, r3};
J37 = {{{6, 4, 4}, {8, 7, 5}}, r3};
J38 = {{{6, 4, 4}, {8, 1, 5}}, r3};
(* branches to center*)
J41 = {{{4, 2, 4}, {4, 3, 6}}, r4};
J42 = {{{4, 6, 4}, {4, 5, 6}}, r4};
J43 = {{{2, 4, 4}, {3, 4, 6}}, r4};
J44 = {{{6, 4, 4}, {5, 4, 6}}, r4};
(*branches to center (vertical)*)
J51 = {{{4, 3, 6}, {4, 3, 8}}, r5};
J52 = {{{4, 5, 6}, {4, 5, 8}}, r5};
J53 = {{{3, 4, 6}, {3, 4, 8}}, r5};
J54 = {{{5, 4, 6}, {5, 4, 8}}, r5};
(*secondary branches conection*)
J61 = {{{3, 2, 5}, {1, 1, 8}}, r6};
J62 = {{{5, 2, 5}, {7, 1, 8}}, r6};
J63 = {{{5, 6, 5}, {7, 7, 8}}, r6};
J64 = {{{3, 6, 5}, {1, 7, 8}}, r6};
J65 = {{{2, 5, 5}, {1, 7, 8}}, r6};
J66 = {{{6, 5, 5}, {7, 7, 8}}, r6};
J67 = {{{6, 3, 5}, {7, 1, 8}}, r6};
J = {J0,J11,J12,J13,J14,J21,J22,J23,J24,J25,J26,J27,J28,J31,J32,J33,J34,J35,J36,J37,J38,J41,J42, J43,J44,J51,J52,J53,J54,J61,J62,J63,J64,J65,J66,J67};

Graphics3D[Tube[#[[1]], #[[2]]] & /@ J]

The figure generated by this branching process is

enter image description here

How to obtain a 3d matrix (with dimension 128x128x128)?

Is it possible to save this image in 3D (pixel)? If yes, so could import it a list of images as a 3D volume:

n = 128;
image = Import["image", "Image3D"]
image = ImageResize[image, {n,n,n}];
data = ImageData[MorphologicalBinarize[image]];
MatrixPlot[data]
MatrixPlot[1 - data]

Or alternatively, would it be possible some alternative way to get this 3D matrix?

n = 128; (*dimension of matrix*)
f[i_, j_, k_] := (*rule to generated the tube*)
s = SparseArray[{{i_, j_, k_} -> f[i, j]}, {n, n, n}]; (*matrix*)
MatrixForm[s];

Can anybody help me?

Thank you in advance.

$\endgroup$
4
  • $\begingroup$ What format would you want the 3D image exported in? You can likely specify the dimensions of your export to accomplish what you want, depending on your desired file format. $\endgroup$ Dec 22, 2021 at 21:28
  • $\begingroup$ So then the file format is "*.tiff". Have you tried explicitly exporting your Graphics3D in said format, specifying the desired image size/resolution? $\endgroup$ Dec 22, 2021 at 21:37
  • 2
    $\begingroup$ I think exporting 3D to TIFF requires an Image3D, not a Graphics3D. See this question for ways to do that. $\endgroup$ Dec 22, 2021 at 23:37
  • 1
    $\begingroup$ Did you edit this from the original question to a completely different question? I remember this being about how to export your 3D image. Please, do not completely change your question to a new question via editing, instead, ask a completely different and new question by making a new post... $\endgroup$ Jan 10, 2022 at 4:39

3 Answers 3

6
$\begingroup$

You can apply FillingTransform directly to the Image3D produced using RegionImage to fill the hollow tubes:

si = Graphics3D[Tube[#[[1]], #[[2]]] & /@ J];
si2 = RegionImage[DiscretizeGraphics[si]];
si3 = si2 // FillingTransform // Binarize;
Image3DSlices[si3]

enter image description here

$\endgroup$
1
  • $\begingroup$ Great work. It was exactly the FillingTransform command I was looking for. Thank you very much $\endgroup$
    – SAC
    Jan 9, 2022 at 19:19
3
$\begingroup$

Another way is use CapsuleShape instead of Tube.

reg = Region[RegionUnion[CapsuleShape[#[[1]], #[[2]]] & /@ J]]
ri = RegionImage[DiscretizeRegion[reg, MaxCellMeasure -> 0.01]]
result = Image3DSlices[ri]
GraphicsGrid[Partition[result, UpTo[12]]]
  • MaxCellMeasure -> 0.001

enter image description here

enter image description here

$\endgroup$
2
$\begingroup$

Actually, the Tube is not a filled 3D-polygon. This is just a pipe. However, the question about how to obtain the cross-section of a region is a really interesting. The simplest way is:

Rasterize[
 Graphics3D[{
   DiscretizeRegion[
    MeshRegion@
     DiscretizeGraphics[si, MaxCellMeasure -> 0.00001],
     {{0, 8}, {0,8}, {4.995, 5}}, MaxCellMeasure -> 0.000001]}, 
  ViewPoint -> Above, Boxed -> False],
 ImageSize -> 800,
 RasterSize -> 1920]

It gives you: enter image description here

As one can see, choosing the third range (z-value range) in DiscretizeRegion you can take the position of desired cross-section. But these are still just points not a curve.. Playing with z-range, RasterSize and ImageSize one can adjust the image quality. Or you can look on this site for a post-processing of raster to make curves.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.