Re: Stretching an image [message #41950] |
Fri, 10 December 2004 10:41  |
Liam Gumley
Messages: 473 Registered: November 1994
|
Senior Member |
|
|
David Fanning wrote:
> Liam Gumley writes:
>
>
>> I believe ENVI uses what is known as histogram clipping, as a way to
>> remove outlier values from the stretch range. I describe an
>> implementation of histogram clipping in Chapter 7 of my book. Here is
>> the code from the book (imclip.pro):
>>
>> ;---start of imclip.pro---
>> FUNCTION IMCLIP, IMAGE, PERCENT=PERCENT
>>
>> ;- Check arguments
>> if (n_params() ne 1) then $
>> message, 'Usage: RESULT = IMCLIP(IMAGE)'
>> if (n_elements(image) eq 0) then $
>> message, 'Argument IMAGE is undefined'
>>
>> ;- Check keywords
>> if (n_elements(percent) eq 0) then percent = 2.0
>>
>> ;- Get image minimum and maximum
>> min_value = min(image, max=max_value)
>>
>> ;- Compute histogram
>> nbins = 100
>> binsize = float(max_value - min_value) / float(nbins)
>> hist = histogram(float(image), binsize=binsize)
>> bins = lindgen(nbins + 1) * binsize + min_value
>
>
> Liam, why 100 bins? I would have thought the minimum
> number would be 256, to correspond with a possible byte
> image. Or is 100 just a nice round number that gives
> reasonable results?
>
> Cheers,
>
> David
A nice round number that gives reasonable results.
|
|
|
Re: Stretching an image [message #41952 is a reply to message #41950] |
Fri, 10 December 2004 08:33   |
David Fanning
Messages: 11724 Registered: August 2001
|
Senior Member |
|
|
Liam Gumley writes:
> I believe ENVI uses what is known as histogram clipping, as a way to
> remove outlier values from the stretch range. I describe an
> implementation of histogram clipping in Chapter 7 of my book. Here is
> the code from the book (imclip.pro):
>
> ;---start of imclip.pro---
> FUNCTION IMCLIP, IMAGE, PERCENT=PERCENT
>
> ;- Check arguments
> if (n_params() ne 1) then $
> message, 'Usage: RESULT = IMCLIP(IMAGE)'
> if (n_elements(image) eq 0) then $
> message, 'Argument IMAGE is undefined'
>
> ;- Check keywords
> if (n_elements(percent) eq 0) then percent = 2.0
>
> ;- Get image minimum and maximum
> min_value = min(image, max=max_value)
>
> ;- Compute histogram
> nbins = 100
> binsize = float(max_value - min_value) / float(nbins)
> hist = histogram(float(image), binsize=binsize)
> bins = lindgen(nbins + 1) * binsize + min_value
Liam, why 100 bins? I would have thought the minimum
number would be 256, to correspond with a possible byte
image. Or is 100 just a nice round number that gives
reasonable results?
Cheers,
David
--
David Fanning, Ph.D.
Fanning Software Consulting, Inc.
Coyote's Guide to IDL Programming: http://www.dfanning.com/
|
|
|
Re: Stretching an image [message #41956 is a reply to message #41952] |
Fri, 10 December 2004 07:14   |
Liam Gumley
Messages: 473 Registered: November 1994
|
Senior Member |
|
|
Julio wrote:
> Hello there!
>
> I'd like to know how to apply a stretch in an image using 2% of
> saturation. That's what ENVI does when I open any image.
>
> How can I do that using an IDL code?
>
> Any comments wellcome,
>
> Thanks,
> Julio
I believe ENVI uses what is known as histogram clipping, as a way to
remove outlier values from the stretch range. I describe an
implementation of histogram clipping in Chapter 7 of my book. Here is
the code from the book (imclip.pro):
;---start of imclip.pro---
FUNCTION IMCLIP, IMAGE, PERCENT=PERCENT
;- Check arguments
if (n_params() ne 1) then $
message, 'Usage: RESULT = IMCLIP(IMAGE)'
if (n_elements(image) eq 0) then $
message, 'Argument IMAGE is undefined'
;- Check keywords
if (n_elements(percent) eq 0) then percent = 2.0
;- Get image minimum and maximum
min_value = min(image, max=max_value)
;- Compute histogram
nbins = 100
binsize = float(max_value - min_value) / float(nbins)
hist = histogram(float(image), binsize=binsize)
bins = lindgen(nbins + 1) * binsize + min_value
;- Compute normalized cumulative sum
sum = fltarr(n_elements(hist))
sum[0] = hist[0]
for i = 1L, n_elements(hist) - 1L do $
sum[i] = sum[i - 1] + hist[i]
sum = 100.0 * (sum / float(n_elements(image)))
;- Find and return the range
range = [min_value, max_value]
index = where((sum ge percent) and $
(sum le (100.0 - percent)), count)
if (count ge 2) then $
range = [bins[index[0]], bins[index[count - 1]]]
return, range
END
;---end of imclip.pro---
NOTE: The TOTAL function with the /CUMULATIVE keyword may be used in IDL
5.3 and higher to compute the cumulative sum.
To use this function, assuming you have an image array named IMAGE:
IDL> range = imclip(image)
IDL> tv, bytscl(image, min=range[0], max=range[1])
If you use IMCLIP in conjunction with my IMDISP program (see my
website), you can just do this:
IDL> imdisp, image, range=imclip(image)
Cheers,
Liam.
Practical IDL Programming
http://www.gumley.com/
|
|
|
|
|
|
Re: Stretching an image [message #41973 is a reply to message #41972] |
Thu, 09 December 2004 11:01   |
David Fanning
Messages: 11724 Registered: August 2001
|
Senior Member |
|
|
Julio writes:
> I'd like to know how to apply a stretch in an image using 2% of
> saturation. That's what ENVI does when I open any image.
>
> How can I do that using an IDL code?
I have no idea how ENVI does this, or even what
"2% of saturation" means, but I'm feeling reckless.
Here is how I would do it:
minImage = Min(image, Max=maxImage)
range = Float(maxImage) - Min(image)
onePercent = range * 0.01
low = minImage + onePercent
high = maxImage - onePercent
stretchedImage = BytScl(image, Min=low, Max=high)
TV, stretchedImage
Cheers,
David
--
David Fanning, Ph.D.
Fanning Software Consulting, Inc.
Coyote's Guide to IDL Programming: http://www.dfanning.com/
|
|
|
Re: Stretching an image [message #42043 is a reply to message #41966] |
Fri, 10 December 2004 13:15  |
KM
Messages: 29 Registered: October 2004
|
Junior Member |
|
|
On Thu, 9 Dec 2004, David Fanning wrote:
> Ken Mankoff writes:
>> On Thu, 9 Dec 2004, Julio wrote:
>>> I'd like to know how to apply a stretch in an image using 2% of
>>> saturation. That's what ENVI does when I open any image.
>>
>> hist_equal() ?
>
> I don't think of that so much as a stretch as I do a squash. :-)
OK, then how about 1/hist_equal()? :)
|
|
|