I like to use ScreenTransferFunction. It's much much faster. So please teach me how to assign STF to parts of Dialog window.
A STF is just a histogram transformation. You can implement this feature in several ways:
- Read the current STF of a view with the View.stf property:
Array View.stfThis property is an array with 4 elements. Array elements correspond to red/gray, green, blue and luminance, respectively.
Each array item has the following layout:
[ m, c0, c1, r0, r1 ]
where:
m is the midtones balance
c0 is the shadows clipping point
c1 is the highlights clipping point
r0 is the shadows range extension (normally not used, you can ignore it)
r1 is the highlights range extension (normally not used, you can ignore t)
m, c0 and c1 are in the [0,1] range and c0 is guaranteed to be c0 <= c1. r0 is in the range [-10,0] and r1 in [+1,+10].
- Define your own STF parameters within your script. This would require three NumericControl controls to define the corresponding parameters m, c0 and c1.
- Implement an automatic stretch feature in your script. This is actually much easier than what may seem at first glance. You have the following data:
Number Image.median()
Number Image.avgDev()These are the median and average deviation of an image, respectively, in the [0,1] range. The median can be interpreted as the position of the main histogram peak of the image over the horizontal axis of the histogram. The average deviation is a robust estimator of dispersion, which you can visualize as the width of the histogram peak. From these values, you can define an automatic shadows clipping point as a multiple of the average deviation toward the left of the peak. You can use also:
Number Image.stdDev()which is the standard deviation, but average deviation is more robust (= immune to outliers, that is very high and very low pixel values in this case).
Instead of those Image methods, you can use the ImageStatistics object if you prefer it. If you have to calculate several statistical moments then ImageStatistics is more efficient because you get all of them in a single call.
To compute an automatic midtones balance, you should use this method:
Number Math.mtf( Number m, Number x )
which returns the resulting value after applying a midtones balance m to an input pixel value x. Using this method, you can find the value of m required to force a particular median value in the image. This is an efficient routine that performs a binary search for m:
function findMidtonesBalance( v0, v1, eps )
{
if ( !eps )
eps = 1.0e-5;
else
eps = Math.max( 1.0e-10, eps );
var m0, m1;
if ( v1 < v0 )
{
m0 = 0;
m1 = 0.5;
}
else
{
m0 = 0.5;
m1 = 1;
}
for ( ;; )
{
var m = 0.5*(m0 + m1);
var v = Math.mtf( m, v1 );
if ( Math.abs( v - v0 ) < eps )
return m;
if ( v < v0 )
m1 = m;
else
m0 = m;
}
}
This routine returns the required value m such that a call to:
Math.mtf( m, v1 )
will return v0 to within +/-eps tolerance. If you set v1 = median_of_image and v0 = desired_position_of_histogram_peak, then you can know the midtones balance m that achieves your automatic adjustment.
Once you know c0, m and c1=1, your histogram transformation is:
for all pixels
if old_pixel < c0
new_pixel := 0
else
new_pixel := mtf( m, (old_pixel - c0)/(1 - c0) )
endif
endfor