Author Topic: PixelMath Equation for a Consistent Histogram Stretch over Multiple Images?  (Read 6227 times)

Offline twade

  • PTeam Member
  • PixInsight Old Hand
  • ****
  • Posts: 445
    • http://www.northwest-landscapes.com
To all,

Is there a PixelMath equation that I can use to get a consistent histogram stretch from one image to the next.  I envision using a couple of neutral background previews from each image.  I have 169 images I need to stretch similarly that will be used in a video. 

Thanks,

Wade

Offline Nocturnal

  • PixInsight Jedi Council Member
  • *******
  • Posts: 2727
    • http://www.carpephoton.com
Hi Wade,

if the stretch is the same for each image then you could use an imagecontainer and apply the same stretch to each image. If the stretch parameters are different for each image you could try to use the automatic histogram stretch. If that doesn't work then I suspect your options are limited to writing a PSJR script that calculates the parameters for each image before stretching them.
Best,

    Sander
---
Edge HD 1100
QHY-8 for imaging, IMG0H mono for guiding, video cameras for occulations
ASI224, QHY5L-IIc
HyperStar3
WO-M110ED+FR-III/TRF-2008
Takahashi EM-400
PIxInsight, DeepSkyStacker, PHD, Nebulosity

Offline Jack Harvey

  • PTeam Member
  • PixInsight Padawan
  • ****
  • Posts: 975
    • PegasusAstronomy.com & Starshadows.com
You might want to read the bug report I just posted which says you cannot do the STF Histogram stretch on greyscale.  works for RGB but not greyscale in my hands
Jack Harvey, PTeam Member
Team Leader, SSRO/PROMPT Imaging Team, CTIO

Offline twade

  • PTeam Member
  • PixInsight Old Hand
  • ****
  • Posts: 445
    • http://www.northwest-landscapes.com
Jack,

Quote
you cannot do the STF Histogram stretch on greyscale

These will be color images. 

However, I'm looking for an equation that can keep the stretch consistent from image to image.  That is, the histogram stretch will vary from image to image, but I will end up with consistent backgrounds.   I have no doubt I will need an equation that looks at both images and compares their backgrounds and then adjusts the stretch accordingly.

Wade

Offline georg.viehoever

  • PTeam Member
  • PixInsight Jedi Master
  • ******
  • Posts: 2132
...
Is there a PixelMath equation that I can use to get a consistent histogram stretch from one image to the next.  I envision using a couple of neutral background previews from each image.  I have 169 images I need to stretch similarly that will be used in a video. 
...

I think thats just what some of the normalization options of ImageIntegration would do for you. Unfortunately, ImageRegistration does not write the resulting normalized image (it only creates a "sum"). I wonder if an ImageNormalization Module in PI (or a suitable option in Image Integration) would be a good idea

Georg
Georg (6 inch Newton, unmodified Canon EOS40D+80D, unguided EQ5 mount)

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Hi Wade and all,

This tool was planned for 1.6.1, but unfortunately I've had no time to finish it properly and the release of 1.6.1 is imminent, so it won't be available until 1.6.2 in September. Chances are that I'll finish it during August, but I'll only have access to a Linux development machine. Since it will be open-source however, anybody able to compile modules on Windows will be able to produce a Windows version. As soon as I have the source code available I'll post it here.

This tool (I still haven't decided the name) will perform just the same task that the frame adaptation routine does in StarAlignment. The algorithm is a robust linear fit. Instead of the usual linear regression, which is unreliable due to its poor resistance to outliers, I have implemented a clever algorithm based on minimizing absolute deviation. The algorithm is described for example on Numerical Recipes in C 2nd Ed., section 15.7 page 703. It is a simple, robust and elegant algorithm (although its mathematical foundation isn't trivial).

In case it may help somebody, here is an excerpt taken directly from StarAlignment's source code:

Code: [Select]
template <class T>
inline T SameSign( const T& a, const T& b )
{
   return (b >= 0) ? (a >= 0 ? a : -a) : (a >= 0 ? -a : a);
}

class LinearFit
{
public:

   double a, b; // y = a + b*x
   double adev; // mean absolute deviation

   LinearFit( const Array<float>& x, const Array<float>& y ) : a( 0 ), b( 0 ), adev( 0 )
   {
      size_type n = x.Length();
      double sx = 0, sy = 0, sxy = 0, sxx = 0;
      for ( size_type j = 0; j < n; ++j )
      {
         sx += x[j];
         sy += y[j];
         sxy += x[j]*y[j];
         sxx += x[j]*x[j];
      }

      double del = n*sxx - sx*sx;
      a = (sxx*sy - sx*sxy)/del;
      b = (n*sxy - sx*sy)/del;

      double chisq = 0;
      for ( size_type j = 0; j < n; ++j )
      {
         double t = y[j] - (a + b*x[j]);
         chisq += t*t;
      }

      double sigb = Sqrt( chisq/del );
      if ( sigb > 0 )
      {
         double f1 = rofunc( b, x, y );
         double b2 = b + SameSign( 3*sigb, f1 );
         if ( b2 == b )
         {
            adev /= n;
            return;
         }

         double f2 = rofunc( b2, x, y );
         double b1 = b;
         while ( f1*f2 > 0 )
         {
            b = b2 + 1.6*(b2 - b1);
            b1 = b2;
            f1 = f2;
            b2 = b;
            f2 = rofunc( b2, x, y );
         }

         sigb *= 0.01;
         while ( Abs( b2 - b1 ) > sigb )
         {
            b = b1 + (b2 - b1)/2;
            if ( b == b1 || b == b2 )
               break;
            double f = rofunc( b, x, y );
            if ( f*f1 >= 0 )
            {
               f1 = f;
               b1 = b;
            }
            else
            {
               f2 = f;
               b2 = b;
            }
         }
      }
      adev /= n;
   }

   double rofunc( double b, const Array<float>& x, const Array<float>& y )
   {
      const double eps = 2.5e-16;

      size_type n = x.Length();
      {
         Array<float> f( n );
         for ( size_type j = 0; j < n; ++j )
            f[j] = y[j] - b*x[j];
         size_type n2 = n >> 1;
         if ( n & 1 )
            a = *pcl::Select( f.Begin(), f.End(), n2 );
         else
         {
            f.Sort();
            a = (f[n2] + f[n2-1])/2;
         }
      }
      double sum = 0;
      adev = 0;
      for ( size_type j = 0; j < n; ++j )
      {
         double d = y[j] - (b*x[j] + a);
         adev += Abs( d );
         if ( y[j] != 0 )
            d /= Abs( y[j] );
         if ( Abs( d ) > eps )
            sum += (d >= 0) ? x[j] : -x[j];
      }
      return sum;
   }
};

This is an adaptation from Numerical Recipes. The LinearFit class fits a straight line y = a + b*x to two sets of numbers x and y passed as arrays. If you fill x and y with all the pixels from image A and image B, respectively, then you'll get a linear function that can be easily applied with PixelMath to match image B to image A in terms of mean background levels and signal strength. The code above is C++ but it can be easily implemented as JavaScript (it would be a bit slow but usable). Anyone?

Sorry for not being able to offer something more useful right now.
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
After thinking a bit more on the subject, you have the excellent AutoHistogram tool, written by Carlos Milovic. It can do what you want quite well —not as well as the frame adaptation routine, but it will do a fine job I think.

On AutoHistogram:

- Disable Histogram clipping.
- Enable Target Median Values.
- Enter the desired values for each channel. The default value of 0.12 is quite appropriate.

and apply it with an ImageContainer. After AutoHistogram, all of your images will have identical mean backgrounds, set to the target median values that you specified.

Let me know if this does what you want.
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline Nocturnal

  • PixInsight Jedi Council Member
  • *******
  • Posts: 2727
    • http://www.carpephoton.com
Hey! I was the first to suggest the automatic histogram transform! :)
Best,

    Sander
---
Edge HD 1100
QHY-8 for imaging, IMG0H mono for guiding, video cameras for occulations
ASI224, QHY5L-IIc
HyperStar3
WO-M110ED+FR-III/TRF-2008
Takahashi EM-400
PIxInsight, DeepSkyStacker, PHD, Nebulosity

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Hi Sander,

That's true. Sorry I overlooked your reply!  :-[
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline Nocturnal

  • PixInsight Jedi Council Member
  • *******
  • Posts: 2727
    • http://www.carpephoton.com
No problem Juan, I'm glad you had the same suggestion :) Now just waiting to see if Wade reports it works or not.
Best,

    Sander
---
Edge HD 1100
QHY-8 for imaging, IMG0H mono for guiding, video cameras for occulations
ASI224, QHY5L-IIc
HyperStar3
WO-M110ED+FR-III/TRF-2008
Takahashi EM-400
PIxInsight, DeepSkyStacker, PHD, Nebulosity

Offline twade

  • PTeam Member
  • PixInsight Old Hand
  • ****
  • Posts: 445
    • http://www.northwest-landscapes.com
To all,

Thanks for your suggestions.  I'll give AutoHistogram a try.

Wade

Offline FunTomas

  • PixInsight Addict
  • ***
  • Posts: 135
    • Astrofoto.sk
" After AutoHistogram, all of your images will have identical mean backgrounds, set to the target median values that you specified."
I am looking for tool/script/function to equalize background of images. Images for mosaic are too diferent in luminance. Is this proces - autohistogram... - the right tool? What differences are in median on pure star field and on image where 80% is galaxy core? Thank you for any hint.

Offline pfile

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 4729
maybe linearfit?