macro for OD calibration based on autoupdate of measured grey value

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

macro for OD calibration based on autoupdate of measured grey value

jarek-6
hello,

i written post about macro recorded by recorder for calibration of
optical density based on results of mean grey value in specified
location of x-ray image. i have a problem because when i apply this
macro to images other than i use for macro construction, still the same
grey values which were measured on first image are used.
this is a macro:

makeRectangle(8, 2, 32, 28);
run("Multiply...", "value=1.5");
makeRectangle(8, 2, 488, 28);
run("Enhance Contrast", "saturated=0 normalize update");
makeRectangle(44, 2, 452, 28);
makeRectangle(44, 2, 22, 28);
run("Set Measurements...", "  mean redirect=None decimal=3");
run("Measure");
run("Measure");
run("Measure");
run("Measure");
run("Measure");
run("Measure");
run("Calibrate...", "function=[Straight Line] unit=OD text1=[160.35
122.63 88.74 58.22 6.99 0.03 ] text2=[3.69 2.87 2.20 1.52 0.40 0]");

so i can't pass through last line i.e. (...) unit=OD text1=[160.35
122.63 88.74 58.22 6.99 0.03 ] (...) to be autoupdated on each next image.
second part of this line, i.e. (...) text2=[3.69 2.87 2.20 1.52 0.40
0]"); should stay unchanged cause its a thickness of ramp placed on
x-ray film.

i can attache the sample image i work on if anyone is interested....any
help more than very welcome.

with best regards,
jarek
Reply | Threaded
Open this post in threaded view
|

Macro for Converting Perkin-Elmer binary series to RGB stacks

Till Bretschneider
Hello,

I would like to contribute a macro which converts Perkin-Elmer binary
image series or stacks to a RGB-tiff stack.
It runs in batch mode and does so recursively for subfolders.
If you find bugs or have comments please let me know.

Till


//Convert-Perkin Macro by Till Bretschneider

// This macro recursively parses a folders with subdirectories
// and converts series of Perkin-Elmer binary images to a RGB-
// stack.
// The macros reads the 3-dimensions x,y, and z and t, the
// number of frames, from a *.cfg file in xml format.
// It handles timeseries and z-stacks of two color channels
// only. However, it is easy to extend it to any number of
// channels if required.
// Important: The RGB stack is created in the directory
// where the original data is located.
// You can open the RGB stack in ImageJ. If it is a 3-D stack
// you may wish to use the excellent Image5D plugin which can
// be found here: http://rsb.info.nih.gov/ij/plugins/image5d.html
// Call "Image5D->Convert RGB stack to Image5D" and select "z"
// for the "3rd dimension". "3rd dimension size" should be set
// to the number of z-slices as given in the Log file from
// the Convert-Perkin macro.

// Basis for the macro are the examples of BatchProcessFolders
// and OpenSeriesUsingFilter which can be found on
// http://rsb.info.nih.gov/ij/macros/



dir = getDirectory ("Choose Source Directory ");

convertFiles (dir);

function convertFiles (dir)
{
  list = getFileList (dir);
  for (i = 0; i < list.length; i++)
    {
      if (endsWith (list[i], "/"))
    convertFiles ("" + dir + list[i]);
      else if (endsWith (list[i], ".cfg"))
    {

      cfg = File.openAsString (dir + list[i]);
      lines = split (cfg, "\n");

        X=parseCfg(lines,"X");
        Y=parseCfg(lines,"Y");
        Z=parseCfg(lines,"Z");
        T=parseCfg(lines,"T");

      print ("####");
      print (dir + list[i]);
      print ("X: " + X + " Y: " + Y + " Z: " + Z + " T: " + T);
      print ("####");

//###############################
//main routine

      index2 = indexOf (list[i], ".cfg");
      basename = substring (list[i], 0, index2);
      files=create_file_list(Z,basename,3);
   
      setBatchMode (true);

      openList (files, X, Y);
      green = basename + "-green";
      rename ("green");
      Ngreen = nSlices;
      print ("green imported");

      files=create_file_list(Z,basename,4);

      openList (files, X, Y);
      red = basename + "-red";
      rename ("red");
      Nred = nSlices;
      print ("red imported");


      if (Nred > Ngreen)
        {
          selectImage ("red");
          for (d = 0; d < Nred - Ngreen; d++)
        {
          setSlice (nSlices);
          run ("Delete Slice");
        }
        }
      else if (Nred < Ngreen)
        {
          selectImage ("green");
          for (d = 0; d < Ngreen - Nred; d++)
        {
          setSlice (nSlices);
        }
          run ("Delete Slice");
        }



      run ("RGB Merge...", "red=red green=green blue=*None*");
      rename (basename + "-RGB");
      saveAs ("Tiff", dir + basename + "-RGB.tif");
      print ("written RGB file: " + basename + "-RGB.tif");
      close ();
//###############################

      i = list.length;    //break after config file was found



    }
    }


//#######################################################################
  function openList (list, w, h)
  {
    stack = 0;


    for (i = 0; i < list.length; i++)
      {
    showProgress (i, list.length);
    if (File.exists (list[i]))
      {

        run ("Raw...", "open=[" + list[i] + "] image=[16-bit Unsigned]
width=" + w +     " height=" + h + " offset=0 number=1 gap=0
little-endian");

        run ("Copy");
        if (stack == 0)
          {
        stack = getImageID ();
          }
        else
          {
        close ();
        selectImage (stack);
        run ("Add Slice");
          }

        run ("Paste");

      }

      }                // if exists
    if (stack != 0)
      setSlice (1);

  }

}                //function openList(list,w,h) {

//#######################################################################
function itostring (i)
{

  if (i > 99)
    string = "" + i;
  else if (i > 9)
    string = "0" + i;
  else
    string = "00" + i;

  return string;

}

//#######################################################################
function parseCfg(lines,item) {

      for (l = 0; l < lines.length; l++)
        {

          index1 = indexOf (lines[l], "<"+item+">");
          if (index1 >= 0)
        {
          index2 = indexOf (lines[l], "</"+item+">");
          sub = substring (lines[l], index1 + 3, index2);
          return parseInt (sub);
        }
    }

exit ("could not parse variable: "+item);

}

//#######################################################################
function create_file_list(Z,basename,first) {


      if (Z == 0)
        files = newArray (T);
      else
        files = newArray (Z * T);

      count = 0;

      if (Z == 0)
        for (n = first; n < first + 2 * T - 1; n += 2)
          {
        files[(n - first) / 2] = dir + basename + "." + toHex (n);
          }
      else
        for (n = first; n < first + 2 * T - 1; n += 2)
          {
        for (z = 0; z < Z; z++)
          {
            zstring = itostring (z);
            files[count] =   dir + basename + "_" + zstring + "." +
toHex (n);
            count++;
          }

          }

return files;

}
//#######################################################################

--
Dr. Till Bretschneider
AG Celldynamics (Gerisch)
Max-Planck-Institut fuer Biochemie
Am Klopferspitz 18a
D-82152 Martinsried, Germany

Tel: +49-89-8578-2329
Fax: +49-89-8578-3885
E-mail: [hidden email]
WWW: http://www.till-bretschneider.de
Reply | Threaded
Open this post in threaded view
|

Correction: Macro for Converting Perkin-Elmer binary series to RGB stacks

Till Bretschneider
In the very last process of cleaning the code I introduced a bug which
should be corrected in the version below.
( I still wonder why the first version ran through without giving any
errors)

Cheers,

Till

Till Bretschneider wrote:

> Hello,
>
> I would like to contribute a macro which converts Perkin-Elmer binary
> image series or stacks to a RGB-tiff stack.
> It runs in batch mode and does so recursively for subfolders.
> If you find bugs or have comments please let me know.
>
> Till
>
corrected version:

//Convert-Perkin Macro by Till Bretschneider

// This macro recursively parses a folders with subdirectories
// and converts series of Perkin-Elmer binary images to a RGB-
// stack.
// The macros reads the 3-dimensions x,y, and z and t, the
// number of frames, from a *.cfg file in xml format.
// It handles timeseries and z-stacks of two color channels
// only. However, it is easy to extend it to any number of
// channels if required.
// Important: The RGB stack is created in the directory of
// where the original data is located.
// You can open the RGB stack in ImageJ. If it is a 3-D stack
// you may wish to use the excellent Image5D plugin which can
// be found here: http://rsb.info.nih.gov/ij/plugins/image5d.html
// Call "Image5D->Convert RGB stack to Image5D" and select "z"
// for the "3rd dimension". "3rd dimension size" should be set
// to the number of z-slices as given in the Log file from
// the Convert-Perkin macro.

// Basis for the macro are the examples of BatchProcessFolders
// and OpenSeriesUsingFilter which can be found on
// http://rsb.info.nih.gov/ij/macros/



dir = getDirectory ("Choose Source Directory ");

convertFiles (dir);

function convertFiles (dir)
{
  list = getFileList (dir);
  for (i = 0; i < list.length; i++)
    {
      if (endsWith (list[i], "/"))
    convertFiles ("" + dir + list[i]);
      else if (endsWith (list[i], ".cfg"))
    {

      cfg = File.openAsString (dir + list[i]);
      lines = split (cfg, "\n");

        X=parseCfg(lines,"X");
        Y=parseCfg(lines,"Y");
        Z=parseCfg(lines,"Z");
        T=parseCfg(lines,"T");

      print ("####");
      print (dir + list[i]);
      print ("X: " + X + " Y: " + Y + " Z: " + Z + " T: " + T);
      print ("####");

//###############################
//main routine

      index2 = indexOf (list[i], ".cfg");
      basename = substring (list[i], 0, index2);
      files=create_file_list(Z,T,basename,3);
   
      setBatchMode (true);

      openList (files, X, Y);
      green = basename + "-green";
      rename ("green");
      Ngreen = nSlices;
      print ("green imported");

      files=create_file_list(Z,T,basename,4);

      openList (files, X, Y);
      red = basename + "-red";
      rename ("red");
      Nred = nSlices;
      print ("red imported");


      if (Nred > Ngreen)
        {
          selectImage ("red");
          for (d = 0; d < Nred - Ngreen; d++)
        {
          setSlice (nSlices);
          run ("Delete Slice");
        }
        }
      else if (Nred < Ngreen)
        {
          selectImage ("green");
          for (d = 0; d < Ngreen - Nred; d++)
        {
          setSlice (nSlices);
        }
          run ("Delete Slice");
        }



      run ("RGB Merge...", "red=red green=green blue=*None*");
      rename (basename + "-RGB");
      saveAs ("Tiff", dir + basename + "-RGB.tif");
      print ("written RGB file: " + basename + "-RGB.tif");
      close ();
//###############################

      i = list.length;    //break after config file was found



    }
    }


//#######################################################################
  function openList (list, w, h)
  {
    stack = 0;


    for (i = 0; i < list.length; i++)
      {
    showProgress (i, list.length);
    if (File.exists (list[i]))
      {

        run ("Raw...", "open=[" + list[i] + "] image=[16-bit Unsigned]
width=" + w +     " height=" + h + " offset=0 number=1 gap=0
little-endian");

        run ("Copy");
        if (stack == 0)
          {
        stack = getImageID ();
          }
        else
          {
        close ();
        selectImage (stack);
        run ("Add Slice");
          }

        run ("Paste");

      }

      }                // if exists
    if (stack != 0)
      setSlice (1);

  }

}                //function openList(list,w,h) {

//#######################################################################
function itostring (i)
{

  if (i > 99)
    string = "" + i;
  else if (i > 9)
    string = "0" + i;
  else
    string = "00" + i;

  return string;

}

//#######################################################################
function parseCfg(lines,item) {

      for (l = 0; l < lines.length; l++)
        {

          index1 = indexOf (lines[l], "<"+item+">");
          if (index1 >= 0)
        {
          index2 = indexOf (lines[l], "</"+item+">");
          sub = substring (lines[l], index1 + 3, index2);
          return parseInt (sub);
        }
    }

exit ("could not parse variable: "+item);

}

//#######################################################################
function create_file_list(Z,T,basename,first) {


      if (Z == 0)
        files = newArray (T);
      else
        files = newArray (Z * T);

      count = 0;

      if (Z == 0)
        for (n = first; n < first + 2 * T - 1; n += 2)
          {
        files[(n - first) / 2] = dir + basename + "." + toHex (n);
          }
      else
        for (n = first; n < first + 2 * T - 1; n += 2)
          {
        for (z = 0; z < Z; z++)
          {
            zstring = itostring (z);
            files[count] =   dir + basename + "_" + zstring + "." +
toHex (n);
            count++;
          }

          }

return files;

}

--
Dr. Till Bretschneider
AG Celldynamics (Gerisch)
Max-Planck-Institut fuer Biochemie
Am Klopferspitz 18a
D-82152 Martinsried, Germany

Tel: +49-89-8578-2329
Fax: +49-89-8578-3885
E-mail: [hidden email]
WWW: http://www.till-bretschneider.de
Reply | Threaded
Open this post in threaded view
|

Re: macro for OD calibration based on autoupdate of measured grey value

jarek-6
In reply to this post by jarek-6
jarek napisał(a):

> hello,
>
> i written post about macro recorded by recorder for calibration of
> optical density based on results of mean grey value in specified
> location of x-ray image. i have a problem because when i apply this
> macro to images other than i use for macro construction, still the
> same grey values which were measured on first image are used.
> this is a macro:
>
> makeRectangle(8, 2, 32, 28);
> run("Multiply...", "value=1.5");
> makeRectangle(8, 2, 488, 28);
> run("Enhance Contrast", "saturated=0 normalize update");
> makeRectangle(44, 2, 452, 28);
> makeRectangle(44, 2, 22, 28);
> run("Set Measurements...", "  mean redirect=None decimal=3");
> run("Measure");
> run("Measure");
> run("Measure");
> run("Measure");
> run("Measure");
> run("Measure");
> run("Calibrate...", "function=[Straight Line] unit=OD text1=[160.35
> 122.63 88.74 58.22 6.99 0.03 ] text2=[3.69 2.87 2.20 1.52 0.40 0]");
>
> so i can't pass through last line i.e. (...) unit=OD text1=[160.35
> 122.63 88.74 58.22 6.99 0.03 ] (...) to be autoupdated on each next
> image.
> second part of this line, i.e. (...) text2=[3.69 2.87 2.20 1.52 0.40
> 0]"); should stay unchanged cause its a thickness of ramp placed on
> x-ray film.
>
> i can attache the sample image i work on if anyone is
> interested....any help more than very welcome.
>
> with best regards,
> jarek
>
>
>
hello,

i repeat my question once more,
i try to apply the getResult command to insert measured values in line
of text1 of OD calibration.... i use :

for (i=0; i<nResults; i++)
     getResult("Mean",i));

but don't know how to make macro to read these values.
please, would you be so kind and help to resolve this problem?

thanks in advance,

jarek
Reply | Threaded
Open this post in threaded view
|

Re: macro for OD calibration based on autoupdate of measured grey value

dscho
Hi,

On Wed, 22 Nov 2006, jarek wrote:

> > run("Calibrate...", "function=[Straight Line] unit=OD text1=[160.35 122.63
> > 88.74 58.22 6.99 0.03 ] text2=[3.69 2.87 2.20 1.52 0.40 0]");
>
> i try to apply the getResult command to insert measured values in line of
> text1 of OD calibration.... i use :
>
> for (i=0; i<nResults; i++)
>     getResult("Mean",i));
>
> but don't know how to make macro to read these values.

How about something like this:

text1 = "[";
for (i = 0; i < nResults; i++) {
        if (i > 0)
                text1 += " ";
        text1 += getResult("Mean", i);
}
text1 = "]";

run("Calibrate...", "function=[Straight Line] unit=OD text1=["
        + text1 + " text2=[3.69 2.87 2.20 1.52 0.40 0]");

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

Re: macro for OD calibration based on autoupdate of measured grey value

jarek-6
Johannes Schindelin napisał(a):

> Hi,
>
> On Wed, 22 Nov 2006, jarek wrote:
>
>  
>>> run("Calibrate...", "function=[Straight Line] unit=OD text1=[160.35 122.63
>>> 88.74 58.22 6.99 0.03 ] text2=[3.69 2.87 2.20 1.52 0.40 0]");
>>>      
>> i try to apply the getResult command to insert measured values in line of
>> text1 of OD calibration.... i use :
>>
>> for (i=0; i<nResults; i++)
>>     getResult("Mean",i));
>>
>> but don't know how to make macro to read these values.
>>    
>
> How about something like this:
>
> text1 = "[";
> for (i = 0; i < nResults; i++) {
> if (i > 0)
> text1 += " ";
> text1 += getResult("Mean", i);
> }
> text1 = "]";
>
> run("Calibrate...", "function=[Straight Line] unit=OD text1=["
> + text1 + " text2=[3.69 2.87 2.20 1.52 0.40 0]");
>
> Hth,
> Dscho
>
>
>
>  
hi, Johannes.
thanks for reply. i checked your proposition. i work on imagej 1.38a and
when i run your macro the following dialog appears:

'=' expected in line 4. text1<+=>" ";

and nothing happends,
if i remowe '+' according to suggestion of imagej, the dialog is displayed:
"To create a calibration curve, the left column must contain a list of
measured mean pixel values and the right column must contain the same
number of calibration standard values. Use the Measure command to add
mean pixel value measurements to the left column.

Left column: 0 values
Right collumn: 6 values"

is it working fine on your version of imagej? thanks again and hope to
cooperate to fix my problem?

thx,
jarek
Reply | Threaded
Open this post in threaded view
|

Re: macro for OD calibration based on autoupdate of measured grey value

dscho
Hi Jarek,

On Wed, 22 Nov 2006, jarek wrote:

> '=' expected in line 4. text1<+=>" ";

My fault. Try to replace "text1 += " by "text1 = text1 + ".

Hth,
Dscho