Threshold as a percentage of image histogram?

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

Threshold as a percentage of image histogram?

Roger Chang-3
Dear ImageJ Listserv members,
ImageJ's threshold function (Image>>Adjust>>Threshold) displays an image
histogram of the number of pixels with certain pixel intensities (0-255). I
was curious if there's maybe some function out there that I could use in a
macro/plugin where a user could input a desired percentage (area fraction)
and the output would be the threshold number that would correspond to that
percentage of the total area underneath the image histogram curve. Any
programming ideas to implement this capability would be appreciated as well!  

Hopefully my explanation makes sense. Please reply to this post if further
elaboration is needed. I searched the list archives before posting this
message and did not come up with a previous post related to this topic. I
apologize in advance if there was a previous post already out there related
to my topic.

Yours truly,
Roger Chang

Washington University in St. Louis BME Department: Efimov Lab
Reply | Threaded
Open this post in threaded view
|

Re: Threshold as a percentage of image histogram?

Ben Tupper
On Jul 2, 2008, at 2:54 PM, Roger Chang wrote:

> Dear ImageJ Listserv members,
> ImageJ's threshold function (Image>>Adjust>>Threshold) displays an  
> image
> histogram of the number of pixels with certain pixel intensities  
> (0-255). I
> was curious if there's maybe some function out there that I could  
> use in a
> macro/plugin where a user could input a desired percentage (area  
> fraction)
> and the output would be the threshold number that would correspond  
> to that
> percentage of the total area underneath the image histogram curve. Any
> programming ideas to implement this capability would be appreciated  
> as well!
>
> Hopefully my explanation makes sense. Please reply to this post if  
> further
> elaboration is needed. I searched the list archives before posting  
> this
> message and did not come up with a previous post related to this  
> topic. I
> apologize in advance if there was a previous post already out there  
> related
> to my topic.
>
> Yours truly,
> Roger Chang
>

Hello,

I think that you can calculate the cumulative histogram and then  
normalize it.  The values of the normalized cumulative histogram are  
really the % of pixels at or below that gray value.  The macro below  
does the trick.

Cheers,
Ben


//BEGINNNG OF MACRO
run("AuPbSn 40 (56K)");
h = getHeight();
w = getWidth();
n = w*h;
nBins = 256;
histMin = 0;
histMax = 255;
getHistogram(values, counts, nBins);
cum = newArray(nBins);
cum[0] = counts[0];
cdf = newArray(nBins);
cdf[0] = cum[0]/n;
print("Bin, Cum, %Cum");
print(values[0]+ ": "+ cum[0]+  ", " + cdf[0]*100);
for (i = (histMin + 1); i < (histMax + 1); i++){
        cum[i] = counts[i] + cum[i-1];
        cdf[i] = cum[i]/n;
        print(values[i]+ ": "+ cum[i]+  ", " + cdf[i]*100);
}
//END OF MACRO




Ben Tupper
[hidden email]

I GoodSearch for Ashwood Waldorf School.

Raise money for your favorite charity or school just by searching the  
Internet with GoodSearch - www.goodsearch.com - powered by Yahoo!
Reply | Threaded
Open this post in threaded view
|

Re: Threshold as a percentage of image histogram?

Roger Chang-3
In reply to this post by Roger Chang-3
Ben,
Thanks for your suggestion and corresponding code. I did not realize that
there was the macro function getHistogram(counts, values, nBins, ...). I
adopted your macro to instead calculate a threshold as a function of a
percentage of the total area under an image histogram. It calculates the
total number of pixel values in the image histogram. Then it makes a new
cumulative array of the count array, such that the tissueValue (equals total
number of pixel values * the tissueThreshPercentage) can be found within the
cumulative array and a threshold can be outputted:

// Input a tissue threshold percentae 0-100
tissueThreshPrec = 80;
nBins = 256;
getHistogram(values, count, nBins);
size = count.length;
// find culmulative sum
cumSum = 0;
for (i = 0; i<count.length; i++)
{
cumSum += count[i];
}
tissueValue = cumSum * tissueThreshPerc / 100;
print(tissueValue);
// cumulative sum of before
cumSumValues = count;
for (i = 1; i<count.length; i++)
{
cumSumValues[i] += cumSumValues[i-1];
}

// find tissueValue
for (i = 1; i<cumSumValues.length; i++)
{
if (cumSumValues[i-1] <= tissueValue && tissueValue <= cumSumValues[i])
// output tissue threshold:
print(i);
}

Hopefully my macro makes sense.
-Roger C.
Reply | Threaded
Open this post in threaded view
|

Re: Threshold as a percentage of image histogram?

Ben Tupper
On Jul 3, 2008, at 3:03 AM, Roger Chang wrote:

> Ben,
> Thanks for your suggestion and corresponding code. I did not  
> realize that
> there was the macro function getHistogram(counts, values,  
> nBins, ...). I
> adopted your macro to instead calculate a threshold as a function of a
> percentage of the total area under an image histogram. It  
> calculates the
> total number of pixel values in the image histogram. Then it makes  
> a new
> cumulative array of the count array, such that the tissueValue  
> (equals total
> number of pixel values * the tissueThreshPercentage) can be found  
> within the
> cumulative array and a threshold can be outputted:
>
> // Input a tissue threshold percentae 0-100
> tissueThreshPrec = 80;
> nBins = 256;
> getHistogram(values, count, nBins);
> size = count.length;
> // find culmulative sum
> cumSum = 0;
> for (i = 0; i<count.length; i++)
> {
> cumSum += count[i];
> }

Hi Roger,

The only suggestion I have for you is to consider that for 8-bit and  
RGB images the total "area" under the histogram is the number of  
pixels in the image.  This is a design implementation specific to  
ImageJ.  Thus you can skip the "cumSum" loop above to calculate the  
total number of pixels and go directly to ....

totalNumberOfPixels = getWidth() * getHeight();


Cheers,
Ben




> tissueValue = cumSum * tissueThreshPerc / 100;
> print(tissueValue);
> // cumulative sum of before
> cumSumValues = count;
> for (i = 1; i<count.length; i++)
> {
> cumSumValues[i] += cumSumValues[i-1];
> }
>
> // find tissueValue
> for (i = 1; i<cumSumValues.length; i++)
> {
> if (cumSumValues[i-1] <= tissueValue && tissueValue <= cumSumValues
> [i])
> // output tissue threshold:
> print(i);
> }
>
> Hopefully my macro makes sense.
> -Roger C.

Ben Tupper
[hidden email]

I GoodSearch for Ashwood Waldorf School.

Raise money for your favorite charity or school just by searching the  
Internet with GoodSearch - www.goodsearch.com - powered by Yahoo!