1
$\begingroup$

I have 2D image data set for 3D image. Since my data is very large, in this question, I use sample data.

testdata = Import["ExampleData/CTengine.tiff", "Image3D"];
sl = Image3DSlices[testdata];

(The the structure of my own data is same as "sl".)

Now, I want to color certain pixels (in the different color from the "sl" depicting color) of 30th picture in the 2D positions of

{{25, 30}, {27, 32}, {26, 31}}

100th picture in 2D positions of

{ {{63 ;; 65}, {42 ;; 45}}, {150, 70}, {{200 ;; 205}, {230, 234}} }

250th picture in 2D positions of

{{12, 90}, {100, 180}, {3, 48}, {230, 250}}

So I made another 3D data set for depicting spots as

SpotdataForEachz = Table[Table[0, 256], 256];
stack = Table[SpotdataForEachz, 256];   

stack[[30]][[25]][[30]] = 1;
stack[[30]][[27]][[32]] = 1;
stack[[30]][[26]][[31]] = 1;

stack[[30]][[63 ;; 65]][[42 ;; 45]] = 1;
stack[[30]][[150]][[70]] = 1;
stack[[30]][[200 ;; 205]][[230 ;; 234]] = 1;

stack[[100]][[12]][[90]] = 1;
stack[[100]][[100]][[180]] = 1;
stack[[100]][[3]][[48]] = 1;
stack[[100]][[230]][[250]] = 1;

stack[[250]][[12]][[90]] = 1;
stack[[250]][[100]][[180]] = 1;
stack[[250]][[3]][[48]] = 1;
stack[[250]][[230]][[250]] = 1;

ima = Image[#] & /@ stack;

Then I tried to overlay

Overlay[{Image3D[sl], Image3D[im]}]

However it didn't work. Also, I think there might be a better way of doing this. Does anyone have nice idea for this problem?

$\endgroup$

1 Answer 1

2
$\begingroup$

You can't directly reassign the value of a pixel in an Image object using Part ([[ ... ]]). Instead, use ReplacePixelValue. For instance, for your first specification you could write:

ReplacePixelValue[sl[[30]], {{25, 30}, {27, 32}, {26, 31}} -> 1]

To avoid repeated typing, you can wrap it all in a MapThread expression, giving it a list of images to be modified, and a corresponding list of modifications for each image. The function being applied to each pair modifies each specified 2D slice in place inside sl, leaving th.

testdata = Import["ExampleData/CTengine.tiff", "Image3D"];
sl = Image3DSlices[testdata];

MapThread[
 (sl[[#1]] = ReplacePixelValue[sl[[#1]], #2 -> 1]) &,
 {
   (* list of images to modify *)
   {1, 80, 100},
  
   (* list of positions to modify in each image *)
   {
     {{63 ;; 90, 10 ;; 50}, {150, 70}, {230, 234}}, 
     {{25, 30}, {27, 32}, {26, 31}},
     {{12, 90}, {100, 180}, {3, 48}, {230, 250}}
   }
 }
]

Finally, you reconstruct a 3D image by feeding the modified list of slices to Image3D:

Image3D[sl]

modified 3D image

Note that in the code above I changed the list of images so it would work with your sample data (which only contains 110 images). Your list of modifications also contained an inconsistent specification ({{200 ;; 205}, {230, 234}}) which I didn't know how to interpret, so I dropped it. Otherwise this should be straightforward to apply to your own image stack.

$\endgroup$
1
  • $\begingroup$ Thank you very much!! Oh, your explaination is very clear. I could get the 3D image which I wanted. (I'm sorry for having made mistake in typing. {{200 ;; 205}, {230, 234}} should be {{200 ;; 205}, {230;;234}}.) $\endgroup$
    – rani
    Commented Mar 12 at 15:08

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.