macro help please

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

macro help please

Larry Nolan
I'm creating a macro to process a directory of forest canopy images.  
Here's what I've got so far after wrapping a recorded macro for one  
image file:

    dir = getDirectory("Choose a Directory ");
    list = getFileList(dir);
    setOption("display labels", true);
    setBatchMode(true);

    for (i=0; i<list.length; i++) {
        path = dir+list[i];
        showProgress(i, list.length);

        open(path);

        run("8-bit");
        setAutoThreshold();
        //run("Threshold...");
        setThreshold(0, 128);
        run("Convert to Mask");
        run("Measure");

        close();
    }

My question is that I want each image to get it's own threshold set  
automatically but I'm not sure how to do that to replace the  
setThreshold(0,128) call.  What I want is to open each image, convert  
to greyscale, do an autothreshold, then convert to Binary and do the  
Measure function to calculate the percentage of black pixel which  
represent the canopy.  I think I'm close but would appreciate a review  
of what I've done so far.

  thanks,

Larry
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Gabriel Landini
On Tuesday 15 December 2009 22:28:09 you wrote:

> I'm creating a macro to process a directory of forest canopy images.
> Here's what I've got so far after wrapping a recorded macro for one
> image file:
>
>     dir = getDirectory("Choose a Directory ");
>     list = getFileList(dir);
>     setOption("display labels", true);
>     setBatchMode(true);
>
>     for (i=0; i<list.length; i++) {
>         path = dir+list[i];
>         showProgress(i, list.length);
>
>         open(path);
>
>         run("8-bit");
>         setAutoThreshold();
>         //run("Threshold...");
>         setThreshold(0, 128);
>         run("Convert to Mask");
>         run("Measure");
>
>         close();
>     }
>
> My question is that I want each image to get it's own threshold set
> automatically but I'm not sure how to do that to replace the
> setThreshold(0,128) call.

Leave "setAutoThreshold();" and delete the "setThreshold(0,128);"
While recording macros, both commands get recorded because it is not possible
to guess what the user wants, whether the automatic method or the value. You
need the first one, not the 2nd one.

Cheers,

G.
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Gabriel Lapointe-2
In reply to this post by Larry Nolan
Hi Larry,
The macro recorder put a counter productive setThreshold(min, max)
command after the set autoThreshold function. Just remove (or comment
out //) the line and it should work fine.

Good luck
Gabbriel

Gabriel Lapointe, MSc.
Laboratoire de Luc DesGroseillers, PhD.
Pavillon Roger-Gaudry Local A-538
Département de biochimie
Faculté de Médecine de l'Université de Montréal
2900 boul. Édouard-Montpetit,
Montréal, Qc, H3T 1J4
[hidden email]


On Tue, 2009-12-15 at 16:28 -0600, Larry Nolan wrote:

> I'm creating a macro to process a directory of forest canopy images.  
> Here's what I've got so far after wrapping a recorded macro for one  
> image file:
>
>     dir = getDirectory("Choose a Directory ");
>     list = getFileList(dir);
>     setOption("display labels", true);
>     setBatchMode(true);
>
>     for (i=0; i<list.length; i++) {
>         path = dir+list[i];
>         showProgress(i, list.length);
>
>         open(path);
>
>         run("8-bit");
>         setAutoThreshold();
>         //run("Threshold...");
>         setThreshold(0, 128);
>         run("Convert to Mask");
>         run("Measure");
>
>         close();
>     }
>
> My question is that I want each image to get it's own threshold set  
> automatically but I'm not sure how to do that to replace the  
> setThreshold(0,128) call.  What I want is to open each image, convert  
> to greyscale, do an autothreshold, then convert to Binary and do the  
> Measure function to calculate the percentage of black pixel which  
> represent the canopy.  I think I'm close but would appreciate a review  
> of what I've done so far.
>
>   thanks,
>
> Larry
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

jmutterer
In reply to this post by Larry Nolan
Larry Nolan <[hidden email]> wrote:
setAutoThreshold();
setThreshold(0, 128);


Larry,
In addition to Gabriels' answers, you might also be wanting to record the
actual threshold values used for your measurements. In that case, you could
add them to your results table by adding the following lines to your code:

...
setAutoThreshold();
getThreshold(lower, upper);
run("Convert to Mask");
run("Measure");
setResult("Lower",nResults-1,lower);
setResult("Upper",nResults-1,upper);
updateResults();
close();
...

Sincerely,
Jerome



On Tue, Dec 15, 2009 at 11:28 PM, Larry Nolan <[hidden email]> wrote:

> I'm creating a macro to process a directory of forest canopy images.
>  Here's what I've got so far after wrapping a recorded macro for one image
> file:
>
>   dir = getDirectory("Choose a Directory ");
>   list = getFileList(dir);
>   setOption("display labels", true);
>   setBatchMode(true);
>
>   for (i=0; i<list.length; i++) {
>       path = dir+list[i];
>       showProgress(i, list.length);
>
>       open(path);
>
>       run("8-bit");
>       setAutoThreshold();
>       //run("Threshold...");
>       setThreshold(0, 128);
>       run("Convert to Mask");
>       run("Measure");
>
>       close();
>   }
>
> My question is that I want each image to get it's own threshold set
> automatically but I'm not sure how to do that to replace the
> setThreshold(0,128) call.  What I want is to open each image, convert to
> greyscale, do an autothreshold, then convert to Binary and do the Measure
> function to calculate the percentage of black pixel which represent the
> canopy.  I think I'm close but would appreciate a review of what I've done
> so far.
>
>  thanks,
>
> Larry
>
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Larry Nolan
Thanks for the additional suggestion; I think I do want to record the  
threshold limits.

Appreciate the contribution.

Larry
On Dec 15, 2009, at 4:58 PM, Jerome Mutterer wrote:

> Larry Nolan <[hidden email]> wrote:
> setAutoThreshold();
> setThreshold(0, 128);
>
>
> Larry,
> In addition to Gabriels' answers, you might also be wanting to  
> record the
> actual threshold values used for your measurements. In that case,  
> you could
> add them to your results table by adding the following lines to your  
> code:
>
> ...
> setAutoThreshold();
> getThreshold(lower, upper);
> run("Convert to Mask");
> run("Measure");
> setResult("Lower",nResults-1,lower);
> setResult("Upper",nResults-1,upper);
> updateResults();
> close();
> ...
>
> Sincerely,
> Jerome
>
>
>
> On Tue, Dec 15, 2009 at 11:28 PM, Larry Nolan <[hidden email]>  
> wrote:
>
>> I'm creating a macro to process a directory of forest canopy images.
>> Here's what I've got so far after wrapping a recorded macro for one  
>> image
>> file:
>>
>>  dir = getDirectory("Choose a Directory ");
>>  list = getFileList(dir);
>>  setOption("display labels", true);
>>  setBatchMode(true);
>>
>>  for (i=0; i<list.length; i++) {
>>      path = dir+list[i];
>>      showProgress(i, list.length);
>>
>>      open(path);
>>
>>      run("8-bit");
>>      setAutoThreshold();
>>      //run("Threshold...");
>>      setThreshold(0, 128);
>>      run("Convert to Mask");
>>      run("Measure");
>>
>>      close();
>>  }
>>
>> My question is that I want each image to get it's own threshold set
>> automatically but I'm not sure how to do that to replace the
>> setThreshold(0,128) call.  What I want is to open each image,  
>> convert to
>> greyscale, do an autothreshold, then convert to Binary and do the  
>> Measure
>> function to calculate the percentage of black pixel which represent  
>> the
>> canopy.  I think I'm close but would appreciate a review of what  
>> I've done
>> so far.
>>
>> thanks,
>>
>> Larry
>>
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Larry Nolan
In reply to this post by Gabriel Lapointe-2
Thank you - to both Gabriels.  I was confused by the two Threshold  
functions.

Larry

On Dec 15, 2009, at 4:51 PM, Gabriel Lapointe wrote:

> Hi Larry,
> The macro recorder put a counter productive setThreshold(min, max)
> command after the set autoThreshold function. Just remove (or comment
> out //) the line and it should work fine.
>
> Good luck
> Gabbriel
>
> Gabriel Lapointe, MSc.
> Laboratoire de Luc DesGroseillers, PhD.
> Pavillon Roger-Gaudry Local A-538
> Département de biochimie
> Faculté de Médecine de l'Université de Montréal
> 2900 boul. Édouard-Montpetit,
> Montréal, Qc, H3T 1J4
> [hidden email]
>
>
> On Tue, 2009-12-15 at 16:28 -0600, Larry Nolan wrote:
>
>> I'm creating a macro to process a directory of forest canopy images.
>> Here's what I've got so far after wrapping a recorded macro for one
>> image file:
>>
>>    dir = getDirectory("Choose a Directory ");
>>    list = getFileList(dir);
>>    setOption("display labels", true);
>>    setBatchMode(true);
>>
>>    for (i=0; i<list.length; i++) {
>>        path = dir+list[i];
>>        showProgress(i, list.length);
>>
>>        open(path);
>>
>>        run("8-bit");
>>        setAutoThreshold();
>>        //run("Threshold...");
>>        setThreshold(0, 128);
>>        run("Convert to Mask");
>>        run("Measure");
>>
>>        close();
>>    }
>>
>> My question is that I want each image to get it's own threshold set
>> automatically but I'm not sure how to do that to replace the
>> setThreshold(0,128) call.  What I want is to open each image, convert
>> to greyscale, do an autothreshold, then convert to Binary and do the
>> Measure function to calculate the percentage of black pixel which
>> represent the canopy.  I think I'm close but would appreciate a  
>> review
>> of what I've done so far.
>>
>>  thanks,
>>
>> Larry
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Larry Nolan
In reply to this post by jmutterer
Jerome,
  one thing I don't understand in the fragment you proposed; what's  
the variable 'nResults' coming from?

thanks,
Larry

On Dec 15, 2009, at 4:58 PM, Jerome Mutterer wrote:

> Larry Nolan <[hidden email]> wrote:
> setAutoThreshold();
> setThreshold(0, 128);
>
>
> Larry,
> In addition to Gabriels' answers, you might also be wanting to  
> record the
> actual threshold values used for your measurements. In that case,  
> you could
> add them to your results table by adding the following lines to your  
> code:
>
> ...
> setAutoThreshold();
> getThreshold(lower, upper);
> run("Convert to Mask");
> run("Measure");
> setResult("Lower",nResults-1,lower);
> setResult("Upper",nResults-1,upper);
> updateResults();
> close();
> ...
>
> Sincerely,
> Jerome
>
>
>
> On Tue, Dec 15, 2009 at 11:28 PM, Larry Nolan <[hidden email]>  
> wrote:
>
>> I'm creating a macro to process a directory of forest canopy images.
>> Here's what I've got so far after wrapping a recorded macro for one  
>> image
>> file:
>>
>>  dir = getDirectory("Choose a Directory ");
>>  list = getFileList(dir);
>>  setOption("display labels", true);
>>  setBatchMode(true);
>>
>>  for (i=0; i<list.length; i++) {
>>      path = dir+list[i];
>>      showProgress(i, list.length);
>>
>>      open(path);
>>
>>      run("8-bit");
>>      setAutoThreshold();
>>      //run("Threshold...");
>>      setThreshold(0, 128);
>>      run("Convert to Mask");
>>      run("Measure");
>>
>>      close();
>>  }
>>
>> My question is that I want each image to get it's own threshold set
>> automatically but I'm not sure how to do that to replace the
>> setThreshold(0,128) call.  What I want is to open each image,  
>> convert to
>> greyscale, do an autothreshold, then convert to Binary and do the  
>> Measure
>> function to calculate the percentage of black pixel which represent  
>> the
>> canopy.  I think I'm close but would appreciate a review of what  
>> I've done
>> so far.
>>
>> thanks,
>>
>> Larry
>>
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

jmutterer
>
> On Wed, Dec 16, 2009 at 1:03 AM, Larry Nolan <[hidden email]> wrote:
>
>  one thing I don't understand in the fragment you proposed; what's the
> variable 'nResults' coming from?
>

Larry,
nResults returns the current number of lines in the results table. You need
to know this to write to the correct row using the setResult("column", row,
value) macro function. A better explanation is available from the macro
functions page at:
http://rsbweb.nih.gov/ij/developer/macro/functions.html#setResult
Sincerely,

Jerome
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Larry Nolan
Thanks once again Jerome; very clear now.  I'll make the documentation  
my friend.

Larry
On Dec 15, 2009, at 6:14 PM, Jerome Mutterer wrote:

>>
>> On Wed, Dec 16, 2009 at 1:03 AM, Larry Nolan <[hidden email]>  
>> wrote:
>>
>> one thing I don't understand in the fragment you proposed; what's the
>> variable 'nResults' coming from?
>>
>
> Larry,
> nResults returns the current number of lines in the results table.  
> You need
> to know this to write to the correct row using the  
> setResult("column", row,
> value) macro function. A better explanation is available from the  
> macro
> functions page at:
> http://rsbweb.nih.gov/ij/developer/macro/functions.html#setResult
> Sincerely,
>
> Jerome
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Gabriel Landini
In reply to this post by Larry Nolan
On Tuesday 15 Dec 2009  09:36:52 you wrote:
> Thank you - to both Gabriels.  I was confused by the two Threshold
> functions.

Something else you may want to try is various thresholding method to find out
which one segments your images best.

Cheers
G
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Larry Nolan
Is there a document that describes the various thresholding methods  
provided in ImageJ?  I looked through the docs and didn't find anything.

thanks,

Larry
On Dec 16, 2009, at 3:37 AM, Gabriel Landini wrote:

> On Tuesday 15 Dec 2009  09:36:52 you wrote:
>> Thank you - to both Gabriels.  I was confused by the two Threshold
>> functions.
>
> Something else you may want to try is various thresholding method to  
> find out
> which one segments your images best.
>
> Cheers
> G
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Gabriel Landini
On Wednesday 16 December 2009 21:24:05 you wrote:
> Is there a document that describes the various thresholding methods
> provided in ImageJ?  I looked through the docs and didn't find anything.

You need to look at the documentation in more detail.
For example here:
http://rsbweb.nih.gov/ij/docs/menus/image.html
under the section called Threshold...

G.
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Larry Nolan
My macro is to process a set of forest canopy images and calculate the %
of canopy area:

   dir = getDirectory("Choose a Directory ");
   list = getFileList(dir);
   setOption("display labels", true);
   setBatchMode(true);
   for (i=0; i<list.length; i++) {
       path = dir+list[i];
       showProgress(i, list.length);
       open(path);
       run("8-bit");
       setAutoThreshold();
       getThreshold(lower,upper);
       run("Convert to Mask");
       run("Invert");
       run("Measure");
       setResult("LowerThresh",nResults-1,lower);
       setResult("UpperThresh",nResults-1,upper);
       updateResults();
       close();
   }

The problem is that I get the incorrect results for the inverted image
for the first and second file but not the third; if I remove the  
'run("Invert");'
statement then the first two files' results are ok  but now the third  
file
measurement is wrong (it's for an inverted image).  The files are
in the same folder.  I'm on Windows XP.  I've got 2000 files to analyze.
What am I missing?

Label
Area
Mean
Min
Max
%Area
LowerThresh
UpperThresh
CC2009P193S1C.jpg
3145728
50.46
0
255
19.79
0
133
CC2009P193S2C.jpg
3145728
48.32
0
255
18.95
0
124
CC2009P193S3C.jpg
3145728
195.38
0
255
76.62
0
91

CC2009P193S1C.jpg
2523228
255
255
255
80.21
0
133
CC2009P193S2C.jpg
2549663
255
255
255
81.05
0
124
CC2009P193S3C.jpg
735464
255
255
255
23.38
0
91

With just two files I get a similar behavior between first and second  
file.

Label                              %Area      LowerThresh      
UpperThresh
C3P1931C.jpg                  22.45       119                  255  
(incorrect %Area)
CC2009P193S1C.jpg        80.21        0                     133  
(correct %Area)

C3P1931C.jpg                 77.55        119                  255  
with 'run("Invert");' removed (correct %Area)
CC2009P193S1C.jpg        19.79          0                   133  with  
'run("Invert");' removed (incorrect %Area)
Reply | Threaded
Open this post in threaded view
|

Re: macro help please - bad behavior

Larry Nolan
In reply to this post by Gabriel Landini
(resent this because I don't thing my tables were formated so they can  
be read)

My macro is to process a set of forest canopy images and calculate the %
of canopy area:

   dir = getDirectory("Choose a Directory ");
   list = getFileList(dir);
   setOption("display labels", true);
   setBatchMode(true);
   for (i=0; i<list.length; i++) {
       path = dir+list[i];
       showProgress(i, list.length);
       open(path);
       run("8-bit");
       setAutoThreshold();
       getThreshold(lower,upper);
       run("Convert to Mask");
       run("Invert");
       run("Measure");
       setResult("LowerThresh",nResults-1,lower);
       setResult("UpperThresh",nResults-1,upper);
       updateResults();
       close();
   }

The problem is that I get the incorrect results for the inverted image
for the first and second file but not the third; if I remove the  
'run("Invert");'
statement then the first two files' results are ok  but now the third  
file
measurement is wrong (it's for an inverted image).  The files are
in the same folder.  I'm on Windows XP.  I've got 2000 files to analyze.
What am I missing?

file1 %area: 19.79 (incorrect)
file2 %area: 18.95 (incorrect)
file3 %area: 76.62

after run("Invert"); removed from macro

file1 %area 80.21
file2 %area 81.05
file3 %area 23.38 (incorrect)

With just two other files I get a similar behavior between first and  
second file.

file1 %area 22.45 (incorrect)
file2 %area 80.21

after run("Invert") removed from macro

file1 %area 77.55
file2 %area 19.79 (incorrect)
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Gabriel Landini
In reply to this post by Larry Nolan
On Tuesday 29 December 2009, you wrote:
> My macro is to process a set of forest canopy images and calculate the %
> of canopy area:

Not sure if this will solve it, but you could try.
If you just want to compute the % of area thresholded, you do *not* need to do
this:
>        run("Convert to Mask");
>        run("Invert");

Try the macro without those. If you want to threshold the other-than-default
phase with the default method use:

setAutoThreshold("Default dark");

There seems to be no way to record this with the macro recorder.
And by the way, are you sure that your third image hasn't got an inverted LUT?

Cheers
G.
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Larry Nolan
G.
  thanks very much for the suggestion; I will try out what you  
suggest.  I do want the canopy pixels to be black and the sky area to  
be white.

All the pictures were taken with the same camera.  How would I tell if  
there is an inverted LUT with a particular image?

best wishes,

Larry
On Dec 30, 2009, at 5:46 AM, Gabriel Landini wrote:

> On Tuesday 29 December 2009, you wrote:
>> My macro is to process a set of forest canopy images and calculate  
>> the %
>> of canopy area:
>
> Not sure if this will solve it, but you could try.
> If you just want to compute the % of area thresholded, you do *not*  
> need to do
> this:
>>       run("Convert to Mask");
>>       run("Invert");
>
> Try the macro without those. If you want to threshold the other-than-
> default
> phase with the default method use:
>
> setAutoThreshold("Default dark");
>
> There seems to be no way to record this with the macro recorder.
> And by the way, are you sure that your third image hasn't got an  
> inverted LUT?
>
> Cheers
> G.
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Larry Nolan
In reply to this post by Gabriel Landini
G.,

removing those two statements works well with my 3 test images.  I'll  
try it with the full set of 1000 images later.

Larry

On Dec 30, 2009, at 5:46 AM, Gabriel Landini wrote:

> On Tuesday 29 December 2009, you wrote:
>> My macro is to process a set of forest canopy images and calculate  
>> the %
>> of canopy area:
>
> Not sure if this will solve it, but you could try.
> If you just want to compute the % of area thresholded, you do *not*  
> need to do
> this:
>>       run("Convert to Mask");
>>       run("Invert");
>
> Try the macro without those. If you want to threshold the other-than-
> default
> phase with the default method use:
>
> setAutoThreshold("Default dark");
>
> There seems to be no way to record this with the macro recorder.
> And by the way, are you sure that your third image hasn't got an  
> inverted LUT?
>
> Cheers
> G.
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Gabriel Landini
On Wednesday 30 December 2009, you wrote:
> removing those two statements works well with my 3 test images.  I'll
> try it with the full set of 1000 images later.

Good, I wonder if this is a problem of using batchMode.

>  How would I tell if  there is an inverted LUT with a particular image?

That is explained in:
http://rsb.info.nih.gov/ij/developer/macro/functions.html

is("Inverting LUT")
 Returns true if the current image is using an inverting lookup table.

but it might be unlikely since you say that all the images are taken with the
same camera and they have not been edited.

Cheers,
G.
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Larry Nolan
The inverted LUT is of interest since I have a set of 1000 images from  
ten years ago that are only 320x240 pixels Jpeg and when I use the  
macro with the changes they are all process as if they are inverted  
and so I put back the run("Invert") statement for that batch and they  
come out OK.  Strange.  I'll give a try modifying the macro to if-test  
using is("Inverting LUT") to decide whether to run("Invert").

Larry

On Dec 30, 2009, at 11:43 AM, Gabriel Landini wrote:

> On Wednesday 30 December 2009, you wrote:
>> removing those two statements works well with my 3 test images.  I'll
>> try it with the full set of 1000 images later.
>
> Good, I wonder if this is a problem of using batchMode.
>
>> How would I tell if  there is an inverted LUT with a particular  
>> image?
>
> That is explained in:
> http://rsb.info.nih.gov/ij/developer/macro/functions.html
>
> is("Inverting LUT")
> Returns true if the current image is using an inverting lookup table.
>
> but it might be unlikely since you say that all the images are taken  
> with the
> same camera and they have not been edited.
>
> Cheers,
> G.
Reply | Threaded
Open this post in threaded view
|

Re: macro help please

Larry Nolan
Working with a set of 1000 images from ten years ago now; I've  
succesfully processed images from this summer with the macro I  
completed.

Each old Jpeg image is 320x240.  All were taken with the same camera.

I'm worried that there is something different in some of the files  
that is causing my macro not to process the images correctly.  I've  
randomly pulled three images and used this macro to analyze them to  
find the canopy cover (leaves and branches).

Here's the macro; I open the file twice so I can compare the original  
with the thresholded result:

   dir = getDirectory("Choose a Directory ");
   list = getFileList(dir);
   setOption("display labels", true);

   for (i=0; i<list.length; i++) {
       path = dir+list[i];
       showProgress(i, list.length);
       open(path); open(path);
       
       run("8-bit");
       setAutoThreshold();
       run("Measure");
   }

After running the macro on a folder with the three files (attached in  
order below):

File 11.jpg      has the sky selected as red, not the foliage; area  
results wrong
File 61.jpg      appears to be OK with the foliage selected as red and  
the analysis result looking reasonable
File 1933.jpg  has the sky selected as red, not the foliage; area  
results wrong

i don't understand what's going on.  Is there something possibly  
different with file 11.jpg and 1933.jpg vs. 61.jpg?  How would I  
figure out what it is?

I don't want to have to manually process all 1000 images to get valid  
analysis results.

Larry


11.jpg (30K) Download Attachment
61.jpg (32K) Download Attachment
1933.jpg (11K) Download Attachment
12