0
$\begingroup$

I have 3474 images (png, 8bit, gey scale, horizontal size x=3107 pixels, vertical size y=1200 pixels).

The images can be downloaded here:

https://drive.google.com/open?id=1rK7xlbFIGMG4O3Z-w82cgqQQTJwEbVvU

They are obtained from a depth scan in the perpendicular z direction.

I want to reproduce from all x-y images the corresponding x-z images.


I thought first to read in all images via Image3D.

To read in the images I used:

fNames = FileNames["*.png"];
numFiles = Length[fNames]; (* = 3747 *)
readImage[ index_] := Import[fNames[[index]]]; 
AbsoluteTiming[image3d=Image3D[Table[readImage[i],{i,numFiles}]];]
{201.538,Null}

So the waiting time is not so critical.

But I have no idea how to access image slices in the x-z direction?

Do you know if Image3D can be used for my problem?


If Image3D cannot be used I thought I could try the following:

imagesArray3d=Array[0&, {3747, 1200, 3107}];

Do[
   imagesArray3d[[i]] = ImageData[Import[fNames[[i]],"PNG"]];
   ,{i, 3747}
];

To access a single x-z image e.g. at y=600 I could use:

Image[imagesArray3d[[All, 600, All]]]

The main problem here is I cannot allocate enough memory:

imagesArray3d=Array[0&, {3747, 1200, 3107}];

gives me:

General::nomem: The current computation was aborted because there was insufficient memory available to complete the computation.
Throw::sysexc: Uncaught SystemException returned to top level. Can be caught with Catch[…, _SystemException].

Do you know a solution how to extract the x-z images.

$\endgroup$
2
$\begingroup$

Maybe this is not very fast, but the RAM usage is low:

zMax = 3474;
data = "C:\\ims\\all.dat";
files = FileNames["C:\\ims\\*.png"][[;; zMax]];

Quiet[Close[data]; Close[str]];
str = BinaryWrite[data, {}];

Dynamic[track]
MapIndexed[(track = #2; BinaryWrite[str, ImageData[Import[#], "Byte"]]) &, files];
Close[str];

str = OpenRead[data, BinaryFormat -> True];
Do[Export["c:\\ims\\xz\\" <> ToString[y] <> ".png",
  Image[Table[track = y; SetStreamPosition[str, 3107*(y - 1) + 3107*1200*(z - 1)];
    BinaryReadList[str, "Byte", 3107], {z, zMax}], "Byte"]], {y, 1200}];
Close[str];
$\endgroup$
  • $\begingroup$ This is great and I have never seen something similar which uses such a small amount of RAM. Your MapIndexed part takes on my computer 276 sec. So if I compare that with my solution, the total time is similar … BUT YOUR CODE can handle many more images. Great! Can you please insert some comments between the code what your idea was. I am not experienced how you work with the files. Thank you. $\endgroup$ – mrz Jul 25 '18 at 12:27
0
$\begingroup$

Another solution which uses rotation of the 3d image and then allows with Image3DSlices to get the orhogonal images:

fNames = FileNames["*.png"];

numFiles = Length[fNames]; (* = 3747 *)

readImage[ index_] := Import[fNames[[index]]]; 

image3d = 
   Image3D[Table[readImage[i], {i, numFiles}]]; // AbsoluteTiming

{189.654, Null}

image3dXZ = ImageRotate[image3d, {Pi/2, {1, 0, 0}}]; // AbsoluteTiming

{67.4332, Null}

ImageAdjust[Image3DSlices[image3dXZ, 600], {0, 5}] ( * cut throught y = 600* )

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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