Hi Georg,
Thanks for an interesting experiment. Try with this modification of your script:
#include <pjsr/StdIcon.jsh>
#include <pjsr/StdButton.jsh>
#include <pjsr/SampleType.jsh>
#include <pjsr/UndoFlag.jsh>
#include <pjsr/Interpolation.jsh>
#define TITLE "TestScript"
/*
* Routine copied from NoiseEvaluation script v1.1
*/
function NoiseEvaluation( img )
{
var a, n = 4, m = 0.01*img.bounds.area;
for ( ;; )
{
a = img.noiseMRS( n );
if ( a[1] >= m )
break;
if ( --n == 1 )
{
console.writeln( "<end><cbr>** Warning: No convergence in MRS noise evaluation routine - using k-sigma noise estimate." );
a = img.noiseKSigma();
break;
}
}
this.sigma = a[0]; // estimated stddev of Gaussian noise
this.count = a[1]; // number of pixels in the noise pixels set
this.layers = n; // number of layers used for noise evaluation
}
function show(image)
{
var wtmp = new ImageWindow( 1000, 1000, image.numberOfChannels,
image.bitsPerSample, image.sampleType == SampleType_Real, image.isColor,"RotImage" );
var v = wtmp.mainView;
v.beginProcess( UndoFlag_NoSwapFile );
v.image.assign( image );
v.endProcess();
wtmp.bringToFront();
}
function doit(targetView)
{
var image = targetView.image;
for ( var i = 0; i < 25; ++i )
{
var angle = 5.0*i;
var newImage = Image.newFloatImage( 64 );
newImage.assign( image );
newImage.interpolation = Interpolation_BicubicSpline; // best detail preserving interpolation
//newImage.interpolation = Interpolation_Bilinear; // second best
//newImage.interpolation = Interpolation_BicubicBSpline; // smoothing interpolation
//newImage.interpolation = Interpolation_MitchellNetravaliFilter; // smoothing interpolation
// newImage.interpolation = Interpolation_NearestNeighbor; // noise distribution preserved, no subpixel accuracy
if ( i != 0 )
newImage.rotate( Math.rad( angle ), newImage.width/2, newImage.height/2 );
newImage.selectedRect = new Rect( newImage.width*0.25, newImage.height*0.25,
newImage.width*0.75, newImage.height*0.75 );
newImage.crop();
// show(newImage);
var noise = new NoiseEvaluation( newImage );
newImage.free();
Console.writeln( format( "%.0f %.4e", angle, noise.sigma ) );
processEvents();
}
Console.writeln("done");
}
function main ()
{
var window = ImageWindow.activeWindow;
if ( window.isNull ){
var msg = new MessageBox(
"<p>No active window. Terminating script.</p>",
TITLE, StdIcon_Warning, StdButton_Ok);
msg.execute();
throw new Error( "No active window" );
}
if ( window.currentView.isNull ){ // ### This cannot happen - but testing doesn't hurt ;)
var msg = new MessageBox(
"<p>No active image. Terminating script.</p>",
TITLE, StdIcon_Warning, StdButton_Ok);
msg.execute();
throw new Error("No active image");
}
var targetView=window.currentView;
doit(targetView);
}
main();
Your original script had two problems: Image.noiseMRS() returns an array (whose elements are noise sigma and number of noise pixels), and black canvas regions generated by rotation prevent MRS convergence. To fix the latter problem, I simply crop the center of the image after rotation and before noise evaluation.
As you can see, noise distribution variations are independent on rotation angle. The amount of change in the standard deviation of the noise is only a function of the applied pixel interpolation algorithm. This validates noise evaluation as a plausible image weighting criterion (the best criterion in my opinion) for image integration. The best algorithm for small-scale detail preservation is bicubic spline. Bilinear is the second best, and filter-based interpolations are too smooth. Nearest neighbor preserves the noise distribution, but lacks subpixel accuracy. This is an interesting experiment that shows --I don't hesitate to say this-- that PixInsight's pixel interpolations are very good.