Don't worry at all about critics!!! We wellcome them. Also, your "demands" here tell us which are your current needs, and how to manage our priorities.
Thank You for all your feedback and enthusiasm!
Hi Bud
You are aware you can apply the stf to all open images through the image menu at the top :D
Harry
Actually you can just put all the images in the same workspace, maximize them at the same zoom level and use the keyboard shortcut to cycle through them.
Hi Bud
I must admit I still use AA4 to check the files before I bring them to pixinsight :'(
I have CCD stack , but do not use it anymore as I can get better stacking results with pixinsight and being able to stack hundreds of images is also easier in PI ( I am Not saying CCD stack is bad because its not )
Harry
How to move a ImageWindow via script
or how to enable move it by user when JS Dialog is open?
Nikolay, this is absolutely fantastic! What a nice piece of code. Congratulations, and thank you for sharing it.:-[
Can I include this script with the next PI release?Yes, of course.
However, you really don't need to create and use a new image window. A much better solution would be, IMO, an integrated view such as the one that has been implemented in the StarHaloReducer script by Juan M. Gómez, for example.Yes, you a right... but I don't like to use HistogramTransformation. I hope you understand why...
I like to use ScreenTransferFunction. It's much much faster. So please teach me how to assign STF to parts of Dialog window.
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;
}
}
A STF is just a histogram transformation.Maybe, but STF I can apply one time per window. HT I must apply to every image.
Can you control the speed of the blink?Of course, I will try to add all what you want and maybe more. I just start learn PJSR, so be patient. I hope in near future the script will work like in MaximDL.
Can you add two buttons?......next and previous?
What a great group of folks.....ask for something and it is done.
Can you control the speed of the blink?Of course, I will try to add all what you want and maybe more. I just start learn PJSR, so be patient. I hope in near future the script will work like in MaximDL.
Can you add two buttons?......next and previous?
The only thing I dont like is that the new created view cannot be moved and you cannot control other processes like I cannot close STF when the new image is behind the STF panel ;)I absolutely agree with you. It's very inconvenient. But Juan promised to solve the problem in next version of PI. See this post: http://pixinsight.com/forum/index.php?topic=1895.msg11741#msg11741
I think there is a bug. A I have problems selecting images. If I click a image in a directory it opens it.It's not bug. It's PixInsight limitation:
I am not able to use windows standards : Select/ arrows, click Control, Control A
QuoteHow to move a ImageWindow via script
You can't, right now. A future version of PJSR will include a Workspace object, which will provide management of windows, icons and workspaces.Quoteor how to enable move it by user when JS Dialog is open?
Impossible, since dialogs are modal windows. This means that they capture the keyboard and mouse blocking the rest of PixInsight's GUI.
How do you control display appearance ....STF?See Instruction (long Version) http://pixinsight.com/forum/index.php?topic=1895.msg11738#msg11738
Why do you need a preview?
for(var i=0;i<11;++i) {
FinalView.zoomIn();
}
FinalView.fitWindow();
FinalView.show();
FinalView.zoomToOptimalFit();
Implement an automatic stretch feature in your script. This is actually much easier than what may seem at first glance.I got the code.
No. You may create an array of statistics objects, and apply them with a "for" loop (0 to numberOfChannels, or numberOfNominalChannels).Thanks. Done:
#define shadowsClipping -1.25
#define targetBackground 0.25
function AutoSTF (img,rgbLinked)
{
var n = img.image.numberOfChannels;
if (rgbLinked || n == 1)
{
for ( var c = c0 = m = 0; c < n ; c++ )
{
img.image.selectedChannel = c;
var s = new ImageStatistics (img.image);
c0 += s.median + shadowsClipping*s.avgDev;
m += s.median;
}
c0 /= n;
m = Math.mtf(targetBackground , m/n - c0 );
var STF =[[m,1,c0,0,1],[m,1,c0,0,1],[m,1,c0,0,1],[0.5,0, 1,0,1]];
}
else
{
var STF = new Array();
for ( var c = 0; c < n ; c++ )
{
img.image.selectedChannel = c;
s = new ImageStatistics (img.image);
c0 = s.median + shadowsClipping*s.avgDev;
m = Math.mtf(targetBackground , s.median - c0 );
STF.push([m, 1, c0, 0, 1]);
}
STF.push([0.5,0,1,0,1]);
}
img.stf = STF ;
}
var img = ImageWindow.activeWindow.mainView;
//var rgbLinked = true;
var rgbLinked = false;
AutoSTF(img,rgbLinked);
Actually, I just copied part of code from ScreenTransferFunctionInterface.cpp Are the midtones input values close to 0.5? One way to interpret the MTF value is this: the number tells which pixel value should become middle gray. For just a inspection, I would pick something close to the image's median as MTF value.I use ImageContainer to compare results.
I like being able to expand the window 'vertically' (to be able to see more of the list entries), but it would also be nice to expand 'horizontally' to see more of the filenames (mine tend to be rather long, and the numeric ID tends to be at the far right!!)Yes, I will modify.
I also wondered about being able to use the mousewheel to 'scroll' through the listed images. At the moment, the mousewheel affects the zoom. I don't know which function is more suited to wheel actions, zoom or image-select?Niall, just move mouse cursor to FileList and use mousewheel ;)
just move mouse cursor to FileList and use mousewheel
Juan, I think this deserves inclusion with v1.6.1
I like being able to expand the window 'vertically' (to be able to see more of the list entries), but it would also be nice to expand 'horizontally' to see more of the filenames (mine tend to be rather long, and the numeric ID tends to be at the far right!!)Like that?
#feature-id Utilities > Animation
#feature-info This script animate set of images.
#include <pjsr/NumericControl.jsh>
#include <pjsr/FrameStyle.jsh>
#include <pjsr/SampleType.jsh>
#include <pjsr/UndoFlag.jsh>
#include <pjsr/StdButton.jsh>
#include <pjsr/StdIcon.jsh>
#include <pjsr/StdCursor.jsh>
#include <pjsr/Sizer.jsh>
#include <pjsr/TextAlign.jsh>
#define shadowsClipping -1.25
#define targetBackground 0.25
function MyDialog()
{
this.__base__ = Dialog;
this.__base__();
this.abort = false;
this.busy = false;
this.go = false;
this.curentImage = 0;
this.wait = 0;
var rgbLinked = true;
// Open files ---------------------------------------------------------------------------------------
console.writeln("Prepare images");
var inputFileDialog=new OpenFileDialog();
inputFileDialog.caption="Select files for animation";
inputFileDialog.loadImageFilters();
inputFileDialog.multipleSelections=true;
if (!inputFileDialog.execute())return;
var inputFiles=inputFileDialog.fileNames;
var Images= new Array(inputFiles.length);
for (var i=0;i<inputFiles.length;++i)
{
var fileName=inputFiles[i];
var w= ImageWindow.open( inputFiles[i] );
if (w.length == 0)
{
console.writeln("Unable to process file ",fileName);
break;
}
if (w[0].bitsPerSample != 16) w[0].setSampleFormat(16,false);
Images[i]=w[0];
if (Images[i].mainView.image.isColor) rgbLinked = false;
}
var img =Images[0].mainView.image;
// prepare Animation window ---------------------------------------------------------------------------------------
var dest = new ImageWindow(1, 1, 1,img.bitsPerSample, img.sampleType == SampleType_Real, img.isColor,"Show" );
dest.mainView.beginProcess( UndoFlag_NoSwapFile );
dest.mainView.image.assign( img );
dest.mainView.endProcess();
AutoSTF ();
dest.zoomFactor=11;
dest.fitWindow();
dest.zoomFactor=-11;
dest.fitWindow();
dest.zoomFactor=1;
dest.show();
// prepare image for scroll window--------------------------------------------------------------
var result=new Image();
result.assign(dest.mainView.image);
HT(result);
console.hide();
//---------------------------------------------------------------------------------------
// Ensure unconditional job abortion upon dialog termination
this.onHide = function()
{
this.abort = true;
this.go = false;
dest.forceClose();
for (var i=0;i<inputFiles.length;++i) Images[i].forceClose();
}
//---------------------------------------------------------------------------------------
// AutoSTF
function AutoSTF ()
{
var img = dest.mainView;
var n = img.image.numberOfChannels;
if (rgbLinked || n == 1)
{
var c0 = 0;
var m = 0;
for ( var c = 0; c < n ; c++ )
{
img.image.selectedChannel = c;
var s = new ImageStatistics (img.image);
c0 += s.median + shadowsClipping*s.avgDev;
m += s.median;
}
c0 /= n;
m = Math.mtf(targetBackground , m/n - c0 );
var STF =[[m,1,c0,0,1],[m,1,c0,0,1],[m,1,c0,0,1],[0.5,0, 1,0,1]];
}
else
{
var STF = new Array();
for ( var c = 0; c < n ; c++ )
{
img.image.selectedChannel = c;
s = new ImageStatistics (img.image);
c0 = s.median + shadowsClipping*s.avgDev;
m = Math.mtf(targetBackground , s.median - c0 );
STF.push([m, 1, c0, 0, 1]);
}
STF.push([0.5,0,1,0,1]);
}
img.stf = STF ;
}
// ResetSTF
function ResetSTF ()
{
dest.mainView.stf=[ [0.5, 1, 0, 0, 1],
[0.5, 1, 0, 0, 1],
[0.5, 1, 0, 0, 1],
[0.5, 1, 0, 0, 1],];
}
// HT
function HT (img)
{
var wtmp = new ImageWindow( 1, 1, 1,img.bitsPerSample, img.sampleType == SampleType_Real, img.isColor );
var v = wtmp.mainView;
v.beginProcess( UndoFlag_NoSwapFile );
v.image.assign( img );
v.endProcess();
var stf = dest.mainView.stf;
var HT = new HistogramTransformation;
if (img.isColor)
{
HT.H = [[stf[0][1], stf[0][0], stf[0][2], stf[0][3], stf[0][4]],
[stf[1][1], stf[1][0], stf[1][2], stf[1][3], stf[1][4]],
[stf[2][1], stf[2][0], stf[2][2], stf[2][3], stf[2][4]],
[ 0, 0.5, 1, 0, 1]];
}
else
{
var low=(stf[0][1]+stf[1][1]+stf[2][1])/3;
var mtf=(stf[0][0]+stf[1][0]+stf[2][0])/3;
var hgh=(stf[0][2]+stf[1][2]+stf[2][2])/3;
HT.H =
[[ 0, 0.5, 1, 0, 1],
[ 0, 0.5, 1, 0, 1],
[ 0, 0.5, 1, 0, 1],
[low, mtf, hgh, 0, 1],
[ 0, 0.5, 1, 0, 1]];
}
HT.executeOn( v, false ); // no swap file
img.assign(v.image);
wtmp.forceClose();
return img;
}
//---------------------------------------------------------------------------------------
this.UpdateImage = function()
{
dest.mainView.beginProcess( UndoFlag_NoSwapFile );
dest.mainView.image.assign( Images[this.curentImage].mainView.image );
dest.mainView.endProcess();
this.infoLabel.text = Images[this.curentImage].mainView.id;
}
//---------------------------------------------------------------------------------------
this.Animation = function()
{
if (!this.go) return;
var lastCallTime = Date.now();
var w;
while (true)
{
for (;this.curentImage<inputFiles.length;++this.curentImage)
{
if ( this.files_TreeBox.child( this.curentImage ).checked )
{
if (this.wait > 0)
{
while ( (w = lastCallTime + this.wait - Date.now()) > 0 )
{
if (w > 50) sleep(0.02);
processEvents(); if (this.abort) return;
}
lastCallTime = Date.now();
}
else {processEvents(); if (this.abort) return;}
this.UpdateImage();
}
else {processEvents(); if (this.abort) return;}
}
this.curentImage=0;
}
}
//---------------------------------------------------------------------------------------
this.generate = function()
{
// If we are already generating data, request job abortion and return.
if ( this.busy ) return;
this.busy = true;
this.abort = false;
this.Animation();
this.busy = false;
};
//---------------------------------------------------------------------------------------
// thrumbal image for navigate
this.ScrollControl = new Control( this );
with ( this.ScrollControl )
{
var w = dest.mainView.image.width;
var h = dest.mainView.image.height;
var Size=200;
setFixedSize( Size, Size*h/w );
var k=1/w*Size;
cursor = new Cursor( StdCursor_CirclePlus );
onPaint = function()
{
// exstract viewing parts of image dest_(x0 x1 y0 y1)
var Zoom=dest.viewportWidth/w;
var Dx0=dest.viewportPosition.x/Zoom;
var Dy0=dest.viewportPosition.y/Zoom;
var Dx1=dest.visibleViewportRect.x1/Zoom;
var Dy1=dest.visibleViewportRect.y1/Zoom;
if (Dx1 > w) Dx1=w;
if (Dy1 > h) Dy1=h;
// calculate x0 x1 y0 y1 for Green rectangle
var x0=Dx0*k;
var y0=Dy0*k;
var x1=x0+Dx1*k;
var y1=y0+Dy1*k;
var G = new Graphics( this );
G.drawScaledBitmap( this.boundsRect, result.render() );
G.pen = new Pen( 0xFF00FF00 ); //Green
G.drawRect(x0,y0,x1,y1);
G.end();
gc();
}
onMousePress = function(x,y) { dest.setViewport( x*w/Size, y*w/Size ); repaint(); }
onMouseMove = function(x,y) { dest.setViewport( x*w/Size, y*w/Size ); repaint(); }
onMouseWheel = function(Dx,Dy, MouseWheel) { if (MouseWheel >0) dest.zoomOut(); else dest.zoomIn(); repaint(); }
}
//---------------------------------------------------------------------------------------
// info / curent image
this.infoLabel = new Label( this );
with ( this.infoLabel )
{
frameStyle = FrameStyle_Sunken;
margin = 2;
text = "Push Play button";
textAlignment = TextAlign_VertCenter;
}
//---------------------------------------------------------------------------------------
// Zoom
this.zoomFitView_Button = new ToolButton( this );
this.zoomFitView_Button.icon = new Bitmap( ":/images/image_window/fit_view_active.png" );
this.zoomFitView_Button.toolTip = "Fit View";
this.zoomFitView_Button.onClick = function() { dest.fitWindow(); this.dialog.ScrollControl.repaint(); }
this.zoomToFit_Button = new ToolButton( this );
this.zoomToFit_Button.icon = new Bitmap( ":/images/image_window/zoom_to_fit_active.png" );
this.zoomToFit_Button.toolTip = "Zoom To Fit";
this.zoomToFit_Button.onClick = function() { dest.zoomToFit(); this.dialog.ScrollControl.repaint(); }
this.zoomToOptimalFit_Button = new ToolButton( this );
this.zoomToOptimalFit_Button.icon = new Bitmap( ":/images/image_window/zoom_to_best_fit_active.png" );
this.zoomToOptimalFit_Button.toolTip = "Zoom To Optimal Fit";
this.zoomToOptimalFit_Button.onClick = function() { dest.zoomToOptimalFit(); this.dialog.ScrollControl.repaint(); }
this.zoom_1_1_Button = new ToolButton( this );
this.zoom_1_1_Button.icon = new Bitmap( ":/images/image_window/zoom_1_1_active.png" );
this.zoom_1_1_Button.toolTip = "Zoom 1:1";
this.zoom_1_1_Button.onClick = function() { dest.zoomFactor=1; this.dialog.ScrollControl.repaint(); }
//---------------------------------------------------------------------------------------
// STF
this.AutoSTF_Button = new ToolButton( this ); // STF
with ( this.AutoSTF_Button )
{
icon = new Bitmap( ":/images/stf.png" );
icon = new Bitmap( ":/images/copy_stf_to_window.png" );
toolTip = "Auto ScreenTransferFunction by current image";
onClick = function()
{
console.show();
this.dialog.cursor = new Cursor( StdCursor_ArrowWait );
AutoSTF ();
this.dialog.cursor = new Cursor( StdCursor_Arrow );
console.hide();
}
}
this.AutoHT_Button = new ToolButton( this ); // STF2
with ( this.AutoHT_Button )
{
icon = new Bitmap( ":/images/copy_stf_to_all_views.png" );
toolTip = "Auto HistogramTransformation to all image";
var v = true;
onClick = function()
{
enabled =false;
console.show();
this.dialog.cursor = new Cursor( StdCursor_ArrowWait );
if (v)
{
this.dialog.AutoSTF_Button.enabled = false;
console.writeln("Auto histogram for ",inputFiles.length, " images" );
var c=parent.curentImage; //save curent image
for (i =0; i < inputFiles.length; i++)
{
console.writeln("Generate statistics for ", Images[i].mainView.id);
parent.curentImage=i;
parent.UpdateImage();
AutoSTF ();
var img = Images[i].mainView;
img.beginProcess();
HT(img.image);
img.endProcess();
console.writeln();
}
parent.curentImage=c; //restore
ResetSTF ();
parent.UpdateImage();
icon = new Bitmap( ":images/reset_stf_to_all_views.png" );
toolTip = "Undo HistogramTransformation";
gc();
}
else //undo HistogramTransformation
{
console.writeln("Restoring ",inputFiles.length, " images" );
var i=parent.curentImage; //save curent image
for (i =0; i< inputFiles.length; i++) Images[i].undo();
console.writeln("Generate statistics for ", Images[parent.curentImage].mainView.id);
parent.UpdateImage();
AutoSTF();
icon = new Bitmap( ":/images/copy_stf_to_all_views.png" );
toolTip = "Auto HistogramTransformation to all image";
this.dialog.AutoSTF_Button.enabled = true;
}
v = !v;
this.dialog.cursor = new Cursor( StdCursor_Arrow );
console.hide();
enabled =true;
}
}
this.rgbLinked_CheckBox = new ToolButton( this ); // Link RGB
with ( this.rgbLinked_CheckBox )
{
icon = new Bitmap( ":/images/rgb.png" );
toolTip = "Link RGB Channels";
checkable = true;
checked = rgbLinked;
enabled = !rgbLinked;
onClick = function( value )
{
rgbLinked = value;
if (this.dialog.AutoSTF_Button.enabled) this.dialog.AutoSTF_Button.onClick();
}
}
this.ZoomSTF_Sizer = new HorizontalSizer;
with (this.ZoomSTF_Sizer)
{
add( this.zoomFitView_Button );
add( this.zoomToFit_Button );
add( this.zoomToOptimalFit_Button );
add( this.zoom_1_1_Button );
add( this.AutoSTF_Button );
add( this.AutoHT_Button);
add( this.rgbLinked_CheckBox );
addStretch();
}
//-------------------------------------------------------
// Action buttons
this.prevImage_Button = new ToolButton( this );
with ( this.prevImage_Button )
{
toolTip = "Prev";
icon = new Bitmap( ":/images/exit.png" );
onClick = function()
{
parent.Stop_Button.onClick();
if (parent.curentImage==0) parent.curentImage=inputFiles.length;
parent.curentImage--;
parent.UpdateImage();
}
}
this.nextImage_Button = new ToolButton( this );
with ( this.nextImage_Button )
{
toolTip = "Next";
icon = new Bitmap( ":/images/exit.png" ).mirroredHorizontally();
onClick = function()
{
parent.Stop_Button.onClick();
parent.curentImage++;
if (parent.curentImage==inputFiles.length) parent.curentImage=0;
parent.UpdateImage();
}
}
this.Stop_Button = new ToolButton( this );
this.Stop_Button.toolTip = "Stop";
this.Stop_Button.icon = new Bitmap( ":/images/view_explorer.png" );
this.Stop_Button.onClick = function() { this.dialog.abort = true; this.dialog.go = false; }
this.Play_Button = new ToolButton( this );
this.Play_Button.toolTip = "Play";
this.Play_Button.icon = new Bitmap( ":/images/processing_console.png")
this.Play_Button.onClick = function() { this.dialog.go = true; this.dialog.generate(); }
this.speed_ComboBox = new ComboBox( this );
with ( this.speed_ComboBox )
{
toolTip = "Delay";
var delay = new Array (0,100,200,500,1000,2000,5000);
var Text = new Array ("Unlimit","0.1 Sec","0.2 Sec","0.5 Sec","1 Sec","2 Sec","5 Sec");
for ( i=0 ; i<Text.length ; i++) addItem( Text[i] );
onItemSelected = function(i) { parent.wait = delay[i]; parent.ScrollControl.repaint(); }
}
// Expand File List ---------------------------------------
this.TreeBox_Button = new ToolButton( this );
with ( this.TreeBox_Button )
{
icon = new Bitmap( ":/images/expand.png" );
toolTip = "Show file list";
checkable = true;
onClick = function()
{
if (checked)
{
parent.files_TreeBox.show();
icon = new Bitmap( ":/images/contract.png" );
parent.adjustToContents();
}
else
{
parent.files_TreeBox.hide();
icon = new Bitmap( ":/images/expand.png" );
parent.adjustToContents();
}
}
}
this.PrevNextStopPlay_Sizer = new HorizontalSizer;
with (this.PrevNextStopPlay_Sizer)
{
add( this.prevImage_Button );
add( this.nextImage_Button );
add( this.Stop_Button );
add( this.Play_Button );
addStretch();
add( this.speed_ComboBox,1);
add( this.TreeBox_Button);
}
//----------------------------------------------------------
// File List
this.files_TreeBox = new TreeBox( this );
with ( this.files_TreeBox )
{
hide();
rootDecoration = false;
numberOfColumns = 1;
headerVisible = false;
onNodeDoubleClicked = function()
{
parent.curentImage = childIndex(currentNode);
parent.UpdateImage();
}
}
for ( var i = 0; i < inputFiles.length; ++i )
{
var node = new TreeBoxNode( this.files_TreeBox );
node.setText( 0, Images[i].mainView.id );
node.checked = true;
}
//---------------------------------------------------------------------------------------
// arange control element
this.sizer1 = new VerticalSizer;
with ( this.sizer1 )
{
margin = 2;
spacing = 2;
add( this.ScrollControl );
add( this.infoLabel );
add( this.ZoomSTF_Sizer );
add( this.PrevNextStopPlay_Sizer );
}
this.sizer = new HorizontalSizer;
with ( this.sizer )
{
margin = 2;
spacing = 2;
add( this.sizer1 );
add( this.files_TreeBox,1 );
}
this.windowTitle = "Animation";
this.adjustToContents();
this.setFixedHeight();
}
MyDialog.prototype = new Dialog;
function main()
{
console.show();
var dialog = new MyDialog;
if (!dialog.execute()) dialog.cancel();
gc();
}
main();
Something similar in the "Stack" routines of Maxim - basically allowing you to assess FHWM, roundness, intensity and contrast. First 2 particularly handy if you're talking about something similar.I will if StarStatistics module (http://pixinsight.com/forum/index.php?topic=1884) will provide whole image statistic. Now just wait or help Carlos Milovic to do it. ;)
Also, I don't have CCDInspector, so I want to see similar tools in PixInsight.
I will if StarStatistics module will provide whole image statistic. Now just wait or help Carlos Milovic to do it.
It grades images based on several parameters and assigns a score
//---------------------------------------------------------------------------------------
// Generat Statistics
this.StatGen = function()
{
if (Boolean(this.stat[this.curentImage])) return; // generate Statistics only 1 time
var sÑ = new Array();
for ( var c = 0; c < dest.mainView.image.numberOfChannels ; c++ )
{
dest.mainView.image.selectedChannel = c;
sÑ[c] = new ImageStatistics (dest.mainView.image);
}
this.stat[this.curentImage]=sÑ;
}
I am not sure what you originally used when you typed in the variable declaration for sÑ but something doesn't seem right. I am sure it 'works', but it doesn't 'read' easily. (Yes, I know this is just a 'triviality', but I thought I would mention it anyway)Hi, Niall. My mistyping. I write c in Russian keyboard layout, so I see it like sc.
I like being able to expand the window 'vertically' (to be able to see more of the list entries), but it would also be nice to expand 'horizontally' to see more of the filenames (mine tend to be rather long, and the numeric ID tends to be at the far right!!)Yes, I will modify.QuoteI also wondered about being able to use the mousewheel to 'scroll' through the listed images. At the moment, the mousewheel affects the zoom. I don't know which function is more suited to wheel actions, zoom or image-select?Niall, just move mouse cursor to FileList and use mousewheel ;)
using the <UP> and <DN> keyboard cursor keys will select the previous or next image 'in the file list'Done. Now you can use <UP> and <DN> to navigate thou ALL files. and you can use <Left> and <Right> to navigate throw only Checked files. So you can select 1 image as BlinkMaster and blink it with other one. :)
Similarly, the scroll-wheel 'scrolls' the file list up and down, without changing the highlighted file, and without changing the displayed image on the workspace.Done. scroll-wheel = <Left> and <Right> = Previous / Next buttons. ;)
to let the user understand that there may be some delay?Now better? MesageBox will later.
I would have preferred to see the data in [0.0, 65535.0] rangeNow you can edit the script:
var r=65536; // multiplier, write 1.0 if you like to see data in [0.0, 1,0]
var n=3; // digits after dot.
I will populate the control with other settings and controls in next version. Could there be a possibility of 'importing' the STF from 'outside' the PJSR? In other words, you pick one of the images, set up a non-auto STF to get the image looking the way you need it to look, and then use THAT set of STF parameters for all images appearing in the Blink routine?If the script will take STF from active window during start? OK?
And now, when the user has finally selected a 'good' subset of the original data, perhaps an option could be given to actually 'do something' with those images which remain IN the selection (and for those images that were eventually EXCLUDED from the selection).I see too much way to 'do something' with 'good' subset... IMHO power of PI in flexibility, implement all instruments in one tools it's utopia, so I think 'do something' much ease via HDD (copy or move or rename). But, if you want, I will try to send 'good' subset to other PI instruments (to Integrate/Calibrate/StarAligment/ImageContainer ???).
I have a problem that if I select statistics I cannot close the processing console down without closing down the script ;)Harry, to close console just push Play button. ;)
I would buy you 2 beers 8)I like beer, but right road to the beer goes through PCL. :footinmouth: I think PCL is much faster. I am right?
Basically, if I load 60 files, blink-animate these, and then decide I want to concentrate only on the first 10 (for example), it would be nice to 'deselect all' and 'select' the ten individual filesDone. Use KeyBoard Shift / Alt / Space / Ctrl-A / Up / Done and mouse to select/deselect/invert selection.
A-B-A-C-A-D-A-E-A-F-A-B-A-C-A-D-A-E-A-FDone. DoubleCkick to select BlinkMaster.
I wonder whether the 'statistics.txt' file should 'auto-increment' in filename (statistics-0001.txt, statistics-0002.txt, etc.) if the process is repeated on the same directory of information?Done.
And, the reason for this is based on my next request - and that is that 'statistics.txt' should be limited to 'only' those files still currently selected from the original list.Done.
So, please don't think that you are 'finished'Yes, you are right. The script will grow. :)
I am not entirely sure about all the keyboard and mouse-click combinationes yet - I am not saying that they are 'wrong' or that they are 'not intuitive', I just need some time to understand all the different combinations and permutations. But, I will also read the script program itself - to get an idea of how you have implemented it.Current keyboard and mouse-click combinations it is standard PI combinations ;) I only stamped 'current selection' into 'Check Mark'. I prefer manipulate via 'Checked/Unchecked images', it's provide more clear visualization and understanding "whats happened?"
3.) From (1) and (2), I think that a better 'open' for the script is needed. Perhaps you could present the 'normal' GUI that you are developing, but 'inhibit' some of the controls until such time as a valid file selection has been madeWhen I start writing the script, I considered on fastest way to start movie, so I not like to ask users to do one more mouse click for load files... But script is growing and I will try, but many current buttons depend from opened images, so I should hide many control elements... I think to solve it via <Tabs> (Files/STF/Animation/Analyses/Settings/...)
-0001, -0002, -0003, ..... sequenceFixed.
5.) Right now I am really struggling to understand the mode of operation of the four 'zoom' icons. I can see what they 'do', and I can make them all 'do something', and I can (eventually) get a view that I think I am after, but the interface is definitely NOT 'intuitive'. But, then again, it isn't 'intuitive' on the main PI image windows either.You are right, it's just copy of PI interface and it's NOT 'intuitive'. I can rearrange zoom buttons vertically and put on left side ScrollControl window ( it's will exactly PI interface). Also I can add more button (zoom 1:2, 2:1). Let me know if you have any idea how to improve it.
6.) I also need to just clarify, in my mind, how the STF application 'works'. I know it does, and quite well, but I just need some time to associate the behaviour with the icons and ToolTips)It's work like standard PI STF, I stole 'Auto Stretch' and 'Link RGB' code ;)
Some ToolTip change suggestions:-Fixed. But, "Delay" changed to "Minimum delay between images (sec)", because the "0.0 sec" is only our wish and real delay will little bit more. ;)
d) The 'Statistics' button - change from "Series Analysis report" to "Export Series Analysis text file to disc"I will if one of PI guru say:"I thinking and I will write Series Analysis tools. It's will like CCDInspector". But now I disagree with you. I want to grow the Analysis tools. Save to file (and show at console) is only simplest/fastest/temporary solution. I like to see not only 'numeric' report, because sometimes to understand which files is wrong don't need to ran other software (like Excel). Sometimes enough simplest Graphical report. But... but I write current 'Statistics' report only because button 'Auto Histogram Transformation to all images' share one engine with the 'Statistics' report. The AHT impossible without Statistics. So, why not... but I hope some of guru say me to kill my 'Statistics tools'.
var mode=true; // mode: sort by channel or not?
true Image1-r Image2-r Image3-r Image1-g Image2-g Image3-g Image1-b Image2-b Image3-b | ? | false Image1-r Image1-g Image1-b Image2-r Image2-g Image2-b Image3-r Image3-g Image3-b |
var st = new ScreenTransferFunction ();
st.launchInterface();
But how to kill or wait closing and collect result from?
2.) If the user clicks the 'red X' on the "Select files for Animation" dialogueNiall, try to clicks the 'red X' now :)
I like the decoration ;)The decoration working now.
Just a note to say that you're doing a terrific work.You too. ;)
Is there any chance that you can renumber your updates? It makes the new versions easier to download (without having to rename, delete, or overwrite the previous versions already in my machine).Thanks Niall. Noted.
Where is the last version of this script?
Max
I really like this script. I have a question: there is a way to see the images in their original aspect? (when open the image set automatically applies a similar -or equal- to STF, and sometimes I would like to examine them unchanged)OK, I can add button for you. Anything else?
Thanks for this great job!,
Best regards,
Enzo.
OK, I can add button for you. Anything else?
divide a flat and apply a bias calibrationYes. I will. But note: in your case dark=bias.
Yes I know more beer required :moneyinmouth:Thanks. No need more, Niall brought enough beer. (http://www.kolobok.us/smiles/artists/just_cuz/JC_burp.gif)
Ver 2.6A minor detail: using the MasterDark and reseting it, when you close the script the postfix "_c" images remains open (hidden)Fixed.
Cool. Perfect.Thanks.
function EvolutionEngine()
{
this.inputFiles = new Array;
this.bitsPerSample = 8;
this.floatSample = false;
this.xev = 0;
this.yev = 0;
this.processFiles = function()
{
var fileName = 'analysis';
fileName = File.appendToName( fileName, '_x' );
fileName = File.appendToName( fileName, Number.toString(this.xev));
fileName = File.appendToName( fileName, 'y');
fileName = File.appendToName( fileName, Number.toString(this.yev) );
//fileName = File.appendToName( fileName, '_x'+Number.toString(this.xev)+'y'+Number.toString(this.yev) );
var filenamePlot = File.appendToName( fileName, '_plot' );
var filenameEvo = File.appendToName( fileName, '_evolution' );
var wPlot = new ImageWindow(this.inputFiles.length, 1001, 1,8, false, false, 'plot');
var wEvo = new ImageWindow(this.inputFiles.length, 1, 1, 32, true, false, 'pixelEvolution');
var vPlot = wPlot.mainView;
vPlot.beginProcess (UndoFlag_NoSwapFile);
vPlot.image.apply(1);
var vEvo = wEvo.mainView;
vEvo.beginProcess (UndoFlag_NoSwapFile);
for ( var i = 0; i < this.inputFiles.length; ++i )
{
var w = ImageWindow.open( this.inputFiles[i] );
if ( w.length == 0 && i+1 < this.inputFiles.length )
{
var msg = new MessageBox( "<p>Unable to load input image file:</p>" +
"<p>" + this.inputFiles[i] + "</p>" +
"<p><b>Continue pixel evolution analysis ?</b></p>",
TITLE, StdIcon_Error, StdButton_Yes, StdButton_No );
if ( msg.execute() == StdButton_No )
break;
}
for ( var j = 0; j < w.length; ++j )
{
var view = w[j].mainView;
view.beginProcess (UndoFlag_NoSwapFile);
var f = view.image.sample(this.xev,this.yev,0);
vEvo.image.setSample( f,i,0);
var p = 1000-Math.round(1000*f);
for ( var k = p; k <= 1000; ++k )
vPlot.image.setSample( 0,i,k);
view.endProcess();
w[j].forceClose();
}
}
vPlot.endProcess();
vEvo.endProcess();
wPlot.show();
wEvo.show();
}
}
var engine = new EvolutionEngine;
As promised... hope this helps (and you takes the ball ;) )Thanks Carlos.
for ( var j = 0; j < w.length; ++j )
I not understand in which situation w.length > 1 ?I get a syntax error on line #1 on all the latest version of this script.Max, please show me report from Processing Console or Print Screen with the error.
Max
One question: Why you use:
Code:
for ( var j = 0; j < w.length; ++j )
I not understand in which situation w.length > 1 ?
I get a syntax error on line #1 on all the latest version of this script.Max, please show me report from Processing Console or Print Screen with the error.
Max
When I try " save selected" it only saves a single image.I think you select only one file.
Don't know if this has been implemented yet... Is there a way to blink using one reference frame (fixed) between the others?Double click at reference frame.
for (var c=0; c < dest.mainView.image.numberOfChannels ; c++)
{
var st = new Array();
st[0] = parent.Images[i].mainView.id;
if (dest.mainView.image.numberOfChannels==1) {st[1]=chanelName[3];Channel[3]=true;}
else {st[1]=chanelName[c]; Channel[c]=true;};
st[2] = String(parent.Images[i].exposure);
st[3] = Number(r*s[i][c].mean).toFixed(n);
st[4] = Number(r*s[i][c].median).toFixed(n);
st[5] = Number(r*s[i][c].avgDev).toFixed(n);
st[6] = Number(r*s[i][c].stdDev).toFixed(n);
st[7] = Number(r*s[i][c].minimum).toFixed(n);
st[8] = Number(r*s[i][c].maximum).toFixed(n);
j++;
stat[j]=st;
for (var k=0; k < st.length; k++)
{
if (hl[k] < String(st[k]).length) hl[k] = String(st[k]).length;
}
}
I did a quick inspection of the code, and the JS classes, but I can't find where the .exposure property came from!JS ImageWindow.Properties.exposure
/*!
Obtains a copy of the %FITS header keywords currently defined for the
image in this window. Returns true if this image has %FITS keywords.
\param[out] kwds Reference to a container that will receive a copy of
the %FITS keywords defined in this image.
\sa SetKeywords(), ResetKeywords()
*/
bool GetKeywords( FITSKeywordArray& kwds ) const;
// Start time: 2011/01/13 07:40:51 UTC
// Execution time: 1.280 s
var p = new FITSHeader;
with ( p )
{
keywords = [ // name, value, comment
["SIMPLE", "T", "file does conform to FITS standard"],
["BITPIX", "16", "number of bits per data pixel"],
["NAXIS", "2", "number of data axes"],
["NAXIS1", "2612", "length of data axis 1"],
["NAXIS2", "3896", "length of data axis 2"],
["EXTEND", "T", "FITS dataset may contain extensions"],
["COMMENT", "", "FITS (Flexible Image Transport System) format defined in Astronomy and"],
["COMMENT", "", "Astrophysics Supplement Series v44/p363, v44/p371, v73/p359, v73/p365."],
["COMMENT", "", "Contact the NASA Science Office of Standards and Technology for the"],
["COMMENT", "", "FITS Definition document #100 and other FITS information."], // row 10
["BZERO", "32768", "offset data range to that of unsigned short"],
["BSCALE", "1", "default scaling factor"],
["EXPOSURE", "600000", "Total Exposure Time[ms]"],
["GAIN", "'10 '", "Analog Gain"],
["OFFSET", "'126 '", "Analog Offset"],
["TIME", "'00:23:45'", "Begin captuer time"],
["DATE", "'07/01/2011'", "Capture Date"],
["CAMERA", "'QHY10 '", "Camera model"],
["Temperature", "'-30.4 '", "Begin capture temperature"],
["Presion Time", "'0-23-45-281'", "Begin capture Presion Time"] // row 20
];
}
Could you just use the same SFT settings as with the animation itself?You mean STF ? Done. See ver 2.93 in attachment :)
console.writeln("this.AutoSTF_Button dest.mainView.image.isColor ",dest.mainView.image.isColor);
preview.assign(dest.mainView.image); //asign courent image to preview image
console.writeln("this.AutoSTF_Button preview.isColor ",preview.isColor);
give strange result:this.AutoSTF_Button dest.mainView.image.isColor true
this.AutoSTF_Button preview.isColor false
this.AutoHT_Button dest.mainView.image.isColor true
this.AutoHT_Button preview.isColor true
...My final (for the moment) 'wish' would be to be able to 'graph' the summary information without having to resort to the likes of MS Excel - have you ever thought about this as a task Nikolai (or anyone else for that matter)?
If you want to join the project, you'll be highly wellcomeWhy not? I will happy improve your project (if i can) and my programing skill.
include other FITS header information in the Summary Details listing and file outputdone. :)
In fact, you have even provided the 'building blocks' for an 'automatic sequential renaming' scriptThis one much better: FITSKeyword sequential utility (http://pixinsight.com/forum/index.php?topic=2997) :)
//case "-268435454": //Ctrl PI ver 1.6.9
case "1879048194": //Ctrl PI ver 1.7.0