Opening images from Different folders for stacking

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Opening images from Different folders for stacking

degussa
This post was updated on .
Hello,

Please i am having problems with writing a multiple image processing macro.
I want the macro to open three different folders, each with images from 20-1000. i want to pick corresponding images from each folder and make a stack, then find the standard deviation of the stack and save to a result folder. The macro works fine for just two folder, but, i want to adapt it for  three folders and up. Below is the macro i am using, please what are my doing wrong or what should i add. i absolutely need to make sure the images stacked correspond to each other in terms of number. eg, i need to stack image 20 from folder 1,2,3


requires("1.33s");
dir1 = getDirectory("Choose the Directory for the reference images");
dir2 = getDirectory("Choose the directory for time series images");
dir3 = getDirectory("Choose the directory for time series2 images");
dir4 = getDirectory("Choose a directory for Difference images ");

  Dialog.create("SET UP INPUT PARAMETERS");
//
  Dialog.addMessage("BINNING PARAMETERS")   // multiple lines by inserting new line characters ("\n") into the string.
  Dialog.addNumber("1st Bin factor; 1 for no binning:", 1);
  Dialog.addNumber("2nd Bin factor; 1 for no binning:", 1);
//
  Dialog.addMessage("RECTANGULAR ROI FOR CROPPING");
  Dialog.addNumber("X Value; 0 for no cropping:", 0);
  Dialog.addNumber("Y Value; 0 for no cropping:", 0);
  Dialog.addNumber("Width; total Width for no cropping:", 1024);
  Dialog.addNumber("Height; total Height for no cropping:", 1024);
//
  Dialog.addMessage("PROVIDE A NAME FOR THE OUTPUT TEXT FILE");
  fname = "file name";
  Dialog.addString("File Name:", fname);
//
  Dialog.addMessage("DATASET IMAGE FILE EXTENSION");
  Dialog.addString("Reference Image File Extension:", ".tif");
  Dialog.addString("Time Series Image File Extension:", ".tif");
  Dialog.addString("Time Series2 Image File Extension:", ".tif");
  Dialog.show();
//
  BIN1 = Dialog.getNumber();
  BIN2 = Dialog.getNumber();
  BINTOT = BIN1*BIN2;
  RECTX = Dialog.getNumber();
  RECTY = Dialog.getNumber();
  RECTW = Dialog.getNumber();
  RECTH = Dialog.getNumber();
  fname = Dialog.getString();
  f = File.open(dir3+fname+".txt");
  exten1 = Dialog.getString();
  exten2 = Dialog.getString();
  exten3 = Dialog.getString();
//  Set up the header in the gsv output file for generating 1-D profiles

    setBatchMode(true);  // prevents display of images

// Batch process two directories of files

// Read lists of file names into arrays

  list1 = getFileList(dir1);
  list2 = getFileList(dir2);
  list3 = getFileList(dir3);

  count = 0;

// Loop over the reference images

  for (i=0; i<list1.length; i++) {
                path1 = dir1+list1[i];
                open(path1); // Reference Dataset
            showProgress(count++, list1.length);
            t1 = getTitle();
                IDa = getImageID();
        index2 = indexOf(t1, exten1);
               index1 = index2-4;
               title1 = substring(t1, 0, index2);
               number1 = substring(t1, index1, index2);

                run("Set Scale...", "distance=0 known=1 pixel=1 unit=inch");

// This next step allows you to specify the ROI (X, Y, W, H)to crop
                 makeRectangle(RECTX, RECTY, RECTW, RECTH);

// The next step crops the image, retaining the portion that is inside the specified ROI
                 run("Crop");

// The next step is the binning - imagej does not allow more than 4 x 4 binning in a single step
// but additional binning steps can be added in multiple lines
      run("Binner ", "x="+BIN1+" y="+BIN1+" bin=average");
      IDb = getImageID();
        run("Binner ", "x="+BIN2+" y="+BIN2+" bin=average");
      IDc = getImageID();
      selectImage(IDa);
      close();
      selectImage(IDb);
      close();
//  Loop over the time-series images

        for (j=0; j<list2.length; j++) {

         index4 = indexOf(list2[j], exten2);
         index3 = index4-4;
         number2 = substring(list2[j], index3, index4);

    if(number1 == number2) {
                path2 = dir2+list2[j];
                open(path2); // Time-series Dataset

         IDe = getImageID();
           t2 = getTitle();
         title2 = substring(list2[j], 0, index4);

         run("Set Scale...", "distance=0 known=1 pixel=1 unit=inch");

// This next step allows you to specify the ROI (X, Y, W, H)to crop
                 makeRectangle(RECTX, RECTY, RECTW, RECTH);

// The next step crops the image, retaining the portion that is inside the specified ROI
                 run("Crop");

// The next step is the binning - imagej does not allow more than 4 x 4 binning in a single step
// but additional binning steps can be added in multiple lines
               
                run("Binner ", "x="+BIN1+" y="+BIN1+" bin=average");
                IDf = getImageID();
                run("Binner ", "x="+BIN2+" y="+BIN2+" bin=average");
                IDg = getImageID();
      selectImage(IDe);
      close();
      selectImage(IDf);
      close();
// Loop over the time-series images

        for (k=0; k<list3.length; k++) {

         index4 = indexOf(list3[k], exten3);
         index5 = index6-4;
//         number3 = substring(list3[j], index5, index6);

    if(number2 == number3) {
                path3 = dir3+list3[k];
                open(path3); // Time-series Dataset

         IDh = getImageID();
           t3 = getTitle();
         title3 = substring(list3[k], 0, index4);

         run("Set Scale...", "distance=0 known=1 pixel=1 unit=inch");

// This next step allows you to specify the ROI (X, Y, W, H)to crop
                 makeRectangle(RECTX, RECTY, RECTW, RECTH);

// The next step crops the image, retaining the portion that is inside the specified ROI
                 run("Crop");

// The next step is the binning - imagej does not allow more than 4 x 4 binning in a single step
// but additional binning steps can be added in multiple lines
               
                run("Binner ", "x="+BIN1+" y="+BIN1+" bin=average");
                IDm = getImageID();
                run("Binner ", "x="+BIN2+" y="+BIN2+" bin=average");
                IDn = getImageID();
      selectImage(IDh);
      close();
      selectImage(IDm);
      close();



// The next step performs the image subtraction - Reference image minus Time-Series or Saturated image
// imageCalculator("Subtract create 32 bit", IDg, IDc);
         run("Images to Stack");
         IDk = getImageID();
         run("Z Project...", "start=1 stop=2 projection=[Standard Deviation]");
         selectImage(IDk);
         close();
         run("Specify...", "width=512 height=512 x=256 y=256 oval");
         run("Measure");
         meanstdDev = getResult("Mean", 0);
         stdDev =getResult("StdDev",0);
         print(title1+" ,"+title2+" ,"+number1+", "+meanstdDev+", "+stdDev);    
         print(f,title1+" ,"+title2+" ,"+number1+", "+meanstdDev+", "+stdDev);
         run("Select None");
         run("Clear Results");
         IDq = getImageID();
         roiManager("Reset")

// The name is assigned to the output file
                outputname = "Diff_"+title2+"_"+number1;
                rename(outputname);
                saveAs("Text Image", dir3+outputname+".txt");
                saveAs("Tiff", dir3+outputname+".tif");

//         selectImage(IDc);
//         close();
//         selectImage(IDg);
//         close();
         selectImage(IDq);
         close();
}
   else {
}
}
}
   File.close(f)
   print(count+" files processed");
   print("All done");

}
<b>------------------------------------------------------------------------------------------------

I hereby attach sample of three folders i am using.
 I will appreciate  help please. Thank

Mosi
Reply | Threaded
Open this post in threaded view
|

Re: Opening images from Different folders for stacking

dscho
Hi,

On Mon, 15 Dec 2008, degussa wrote:

> for (k=0; k<list3.length; k++) {
>
>          index4 = indexOf(list3[k], exten3);
>          index5 = index6-4;
> //         number3 = substring(list3[j], index5, index6);
>
>     if(number1 == number2) {

This wants to be number3 instead of number2.

BTW your code could use some serious refactoring: it seems that you do the
same step in all three loops; just put that code into a function, and you
macro gets much more readable.

Also, once you found the match ("if (number1 == number2)") you might want
to "break;" in order to avoid running through the loops unnecessarily.

However, you might want to avoid the inner loops altogether: apparently
you want to know if the other two directories have a file of the same
name?  You can do that much quicker by saying

        for (i = 0; i < list1.length; i++) {
                if (File.exists(dir2 + list1[i]) &&
                                File.exists(dir3 + list1[i])) {
                        // do your thing
                }
        }

Hth,
Dscho
Reply | Threaded
Open this post in threaded view
|

Re: Opening images from Different folders for stacking

degussa

Johannes Schindelin wrote

        for (i = 0; i < list1.length; i++) {
                if (File.exists(dir2 + list1[i]) &&
                                File.exists(dir3 + list1[i])) {
                        // do your thing
                }
        }

Hth,
Dscho

 Hi Johannes,

I agree with you on the repeating steps, but its necessary here because the files  i need must have just the last four numbers in the file names common to them. The folders i am using have equal numbers of files (1-1000), but different file name prefix such as MW24C2_1_S101_0020( folder 1), MW24C2_2_S101_0020( folder 2), MW24C2_3_S101_0020( folder 3).

Then the operation i need to perform requires the images to be open, which is why i cannot just check if they exist, i need to open the file and check that they all correspond in terms of the last four digit in their name before i make  a stack of them. but the code you suggested below only checks for the existence of the files and will not necessarily open them, and they need to be all open for the stack operation to take place.
The main problem with the macro which i cannot resolve is the non performance of the third loop. Thanks

Mosi degussa
Reply | Threaded
Open this post in threaded view
|

Re: Opening images from Different folders for stacking

dscho
Hi,

On Wed, 17 Dec 2008, degussa wrote:

> Johannes Schindelin wrote:
> >
> > for (i = 0; i < list1.length; i++) {
> > if (File.exists(dir2 + list1[i]) &&
> > File.exists(dir3 + list1[i])) {
> > // do your thing
> > }
> > }
> >
> > I agree with you on the repeating steps, but its necessary here
> > because the files i need must have just the last four numbers in the
> > file names common to them. The folders i am using have equal numbers
> > of files (1-1000), but different file name prefix such as
> > MW24C2_1_S101_0020( folder 1), MW24C2_2_S101_0020( folder 2),
> > MW24C2_3_S101_0020( folder 3).

Okay, fair enough.  Still, I would decouple that test, then (and maybe use
a higher-level language that has something like hashsets):

        function inList(list, extension, last4digits) {
                for (i = 0; i < list.length; i++) {
                        extensionIndex = indexOf(list[i], extension);
                        if (extensionIndex < 4)
                                continue;
                        if (substring(list[i], extensionIndex - 4, 4)
                                         == last4digits)
                                return list[i];
                }
                return "";
        }

Then I'd call this function in the loop, and only open the images when all
three of them are found:

        for (i = 0; i < list1.length; i++) {
                extensionIndex = indexOf(list1[i], exten1);
                if (extensionIndex < 4)
                        continue;
                last4digits = substring(list1[i], extensionIndex - 4, 4);

                name2 = inList(list2, exten2, last4digits);
                name3 = inList(list3, exten3, last4digits);
                if (name2 == "" || name3 == "")
                        continue;

                // only now open dir1 + list1[i], dir2 + name2
                // and dir3 + name3

                // then do the operations you need to do
        }

It's just a hint how to structure your code better, so that you do not
miss an unadjusted number, which is a consequence of heavy copy-pasting.

Of course, you are free to let this advice go unheeded, and just fix the
number2 to number3 I pointed out in my first reply.

Ciao,
Dscho
Reply | Threaded
Open this post in threaded view
|

Re: Opening images from Different folders for stacking

degussa

Johannes Schindelin wrote
Hi,

On Wed, 17 Dec 2008, degussa wrote:

> Johannes Schindelin wrote:
> >
> > for (i = 0; i < list1.length; i++) {
> > if (File.exists(dir2 + list1[i]) &&
> > File.exists(dir3 + list1[i])) {
> > // do your thing
> > }
> > }
> >
> > I agree with you on the repeating steps, but its necessary here
> > because the files i need must have just the last four numbers in the
> > file names common to them. The folders i am using have equal numbers
> > of files (1-1000), but different file name prefix such as
> > MW24C2_1_S101_0020( folder 1), MW24C2_2_S101_0020( folder 2),
> > MW24C2_3_S101_0020( folder 3).

Okay, fair enough.  Still, I would decouple that test, then (and maybe use
a higher-level language that has something like hashsets):

        function inList(list, extension, last4digits) {
                for (i = 0; i < list.length; i++) {
                        extensionIndex = indexOf(list[i], extension);
                        if (extensionIndex < 4)
                                continue;
                        if (substring(list[i], extensionIndex - 4, 4)
                                         == last4digits)
                                return list[i];
                }
                return "";
        }

Then I'd call this function in the loop, and only open the images when all
three of them are found:

        for (i = 0; i < list1.length; i++) {
                extensionIndex = indexOf(list1[i], exten1);
                if (extensionIndex < 4)
                        continue;
                last4digits = substring(list1[i], extensionIndex - 4, 4);

                name2 = inList(list2, exten2, last4digits);
                name3 = inList(list3, exten3, last4digits);
                if (name2 == "" || name3 == "")
                        continue;

                // only now open dir1 + list1[i], dir2 + name2
                // and dir3 + name3

                // then do the operations you need to do
        }

It's just a hint how to structure your code better, so that you do not
miss an unadjusted number, which is a consequence of heavy copy-pasting.

Of course, you are free to let this advice go unheeded, and just fix the
number2 to number3 I pointed out in my first reply.

Ciao,
Dscho
Thanks for you help so far, i have tried working with your suggestion, but its not achieving my purpose and is not opening my image to enable me stack them. Fixing the issues of number 2 and number 3 as you pointed out in my earlier code does not improve the code and it actually does not affect the output of the code if it runs. Thanks
Reply | Threaded
Open this post in threaded view
|

Re: Opening images from Different folders for stacking

degussa
degussa wrote
Johannes Schindelin wrote
Hi,

On Wed, 17 Dec 2008, degussa wrote:

> Johannes Schindelin wrote:
> >
> > for (i = 0; i < list1.length; i++) {
> > if (File.exists(dir2 + list1[i]) &&
> > File.exists(dir3 + list1[i])) {
> > // do your thing
> > }
> > }
> >
> > I agree with you on the repeating steps, but its necessary here
> > because the files i need must have just the last four numbers in the
> > file names common to them. The folders i am using have equal numbers
> > of files (1-1000), but different file name prefix such as
> > MW24C2_1_S101_0020( folder 1), MW24C2_2_S101_0020( folder 2),
> > MW24C2_3_S101_0020( folder 3).

Okay, fair enough.  Still, I would decouple that test, then (and maybe use
a higher-level language that has something like hashsets):

        function inList(list, extension, last4digits) {
                for (i = 0; i < list.length; i++) {
                        extensionIndex = indexOf(list[i], extension);
                        if (extensionIndex < 4)
                                continue;
                        if (substring(list[i], extensionIndex - 4, 4)
                                         == last4digits)
                                return list[i];
                }
                return "";
        }

Then I'd call this function in the loop, and only open the images when all
three of them are found:

        for (i = 0; i < list1.length; i++) {
                extensionIndex = indexOf(list1[i], exten1);
                if (extensionIndex < 4)
                        continue;
                last4digits = substring(list1[i], extensionIndex - 4, 4);

                name2 = inList(list2, exten2, last4digits);
                name3 = inList(list3, exten3, last4digits);
                if (name2 == "" || name3 == "")
                        continue;

                // only now open dir1 + list1[i], dir2 + name2
                // and dir3 + name3

                // then do the operations you need to do
        }

It's just a hint how to structure your code better, so that you do not
miss an unadjusted number, which is a consequence of heavy copy-pasting.

Of course, you are free to let this advice go unheeded, and just fix the
number2 to number3 I pointed out in my first reply.

Ciao,
Dscho
Thanks for you help so far, i have tried working with your suggestion, but its not achieving my purpose and is not opening my image to enable me stack them. Fixing the issues of number 2 and number 3 as you pointed out in my earlier code does not improve the code and it actually does not affect the output of the code if it runs. Thanks
Fixing the number 2 and number error you pointed out doesn.t still make the code to run, i keep on having  this error message which i do not understand,

index(-5) is outside of the 0-49 range in line 208.
number3 = substring (list3 [k], index5, index6<)>;

Please can anyone let me know what this error message implies. Thanks
Reply | Threaded
Open this post in threaded view
|

Re: Opening images from Different folders for stacking

Ben Tupper
On Dec 29, 2008, at 5:05 PM, degussa wrote:

>
>
> index(-5) is outside of the 0-49 range in line 208.
> number3 = substring (list3 [k], index5, index6<)>;
> Please can anyone let me know what this error merssage implies. Thanks
>

Hi,

It implies that one of your indices (k, index5 or index6) has a value  
of -5 which is out of the allowed range of 0-49.  We can't know which  
index it is from the info you have provided.

I think you might insert...

print("k=" + k + ", index5=" + index5 + ", index6=" + index6);

... into your macro at a strategic location to help track down the  
error. I'll bet you figure it out pretty quickly from that info.

Cheers,
Ben