Author Topic: ¿Cómo puedo hacer un simple Cut&Paste con PI?  (Read 7772 times)

Offline bosch

  • PixInsight Addict
  • ***
  • Posts: 123
¿Cómo puedo hacer un simple Cut&Paste con PI?
« on: 2009 January 17 03:31:44 »
Pues eso quiero sustituir un trozo de una imagen con el de otra imagen colocado aproximadamente en el mismo lugar.

Me explico:

Tengo dos Track&Stack de un cometa.

Una de las imágenes está centrada en el cometa por lo que las estrellas están movidas y el cometa es puntual (Imagen A). Luego tengo la imagen inversa con las estrellas puntuales y el cometa con su correspondiente deriva.(Imagen B)

Quiero sustituir en B ese comenta "corrido" por su correspondente imagen puntual encontrada en A.

Obviamente las escasa estrellas que estaban muy cerca del cometa puntual saldrán igualmente corridas puesto que no las puedo eliminar de esa imagen sin cargarme parte de la coma del cometa pero este precio no es problema.

¿porqué hago esto? pues simplemente porqué de la imagen A puedo sacar la astrometría del comenta pero no la fotometría la cual debo sacar de una imagen más acorde a B.

Con otros programas esto es tan sencillo como hacer un "Cut" de una de las imágenes seleccionando un cuadro de selección rectangular, esférico o poligonal e irse a la segunda imagen y darle al "Paste as new selection". Pero esto tan sencillo, ¿cómo se hace con PI?

Offline OriolLehmkuhl

  • PixInsight Addict
  • ***
  • Posts: 177
    • http://www.astrosurf.com/brego-sky
¿Cómo puedo hacer un simple Cut&Paste con PI?
« Reply #1 on: 2009 January 17 04:59:52 »
Hola Daniel,

creo que seria fácil a través de un script :)
Lo que pasa es que ahora nos vamos al campo a "afotar", si no tienes prisa, en un par de días te montamos algo ;)

Un saludo,

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
¿Cómo puedo hacer un simple Cut&Paste con PI?
« Reply #2 on: 2009 January 17 05:06:30 »
Hola Daniel

Hay dos formas. Básicamente si puedes registrar las imágenes con DynamicAlignment ya tienes el problema resuelto. Sin embargo, asumo que no es así porque una imagen tiene las estrellas desplazadas. Pasamos entonces al "plan B" :)

- Primero recortas la imagen que quieres pegar con DynamicCrop. Llamaremos a esta imagen B y a la imagen grande A (les podemos cambiar sus identificadores en PI).

- Ahora abres PixelMath y desactivas la opción "Use a single RGB/K expression". Después copias la siguiente expresión en cada canal R/K, G y B:

Code: [Select]
Max( $T, pixel( B, x()+dx, y()+dy ) )

y lo siguiente en el campo "Symbols":

Code: [Select]
dx=-1070, dy=-1375

Los números que he puesto arriba son sólo un ejemplo, por supuesto. Tendrás que especificar los desplazamientos necesarios para hacer coincidir la imagen B sobre la imagen A. Deberías poder averiguar unos valores muy aproximados fácilmente, con tan sólo pasar el cursor sobre A. Ten en cuenta que puedes usar valores reales (con decimales de píxel) para dx y dy, si es necesario.

Los valores que tienes que usar son las coordenadas del vértice superior izquierdo de B con respecto al vértice superior izquierdo de A (cualquier vértice te sirve, por supuesto). Mediante prueba/error, y usando previews definidos sobre A para acelerar el proceso (porque PixelMath es totalmente previsualizable), es cuestión de un par de minutos (acabo de hacer una prueba y te puedo corroborar lo sencillo que es). Se trata de ir aproximando los valores de dx y dy hasta que la superposición obtenida sea la mejor posible.

Como ves, PixelMath es una herramienta mucho más poderosa de lo que parece a primera vista :)

Dicho esto, por supuesto que vamos a tener un completísimo juego de herramientas para edición de imágenes en PI, incluyendo un sistema de capas que podrá hacer todo lo que hace PixelMath de forma interactiva.
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline bosch

  • PixInsight Addict
  • ***
  • Posts: 123
¿Cómo puedo hacer un simple Cut&Paste con PI?
« Reply #3 on: 2009 January 17 10:09:48 »
Gracias por tan pronta respuesta de hecho me he pasdo la mañana investigando y haciendo provaturas y al final he hecho lo que seguidamente describo (he hecho un curta y pega de lo que he colgado en el foro de fotografiaastronómica)

"Bueno al final lo he conseguido aunque es algo complicado:

1- Abrir cmo no las dos imágenes a combinar en PI que en mi caso son de idéntico tamaño puesto que esto es imprescindible para poder usar este método.
2- Ir a Image/New Image (Ctrl+n) donde escogeremos "Set As Actuve Image"

Con ello creamos una imagen nueva del mismo tamaño que cualesquiera de las dos previas
Esta imagen es la que usaremos para crear una máscara. Recordad que cualquier imagen en B/N puede usarse como máscara sin más limitación que tengo el mismo tamaño que el lienzo sobre el que la pondremos

La máscara que quiero crear es simplemente toda negra con un cuadrado blanco que actuará a modo de ventana a través de la cual fusionaré las dos fotos originales.

3 -Luego cojo esa imagen nueva que es toda negra y la guardo bajo el nombre de "Mascara"

4 -Tomo una de las imágenes y apunto en un papel las coordenadas de las dos esquinas del rectángulo de la "Ventana" que deberé crear en la Mascara.

5- Abro la máscara con Gimp y hago una selección rectangular tomando como referencia las mismas coordenadas de esas dos esquinas que apunté. Una vez tengo ese rectángulo hecho, simplemente lo pinto de riguroso blanco y lo guardo.

6- Vuelvo a abrir esa máscara con PI y la uso encima de la imagen con las estrellas puntuales.

7- binarizo esa imagen con la máscara puesta poniendo los deslizadores a la izquierda del todo quedándome un rectángulo completamente blanco allí donde la imagen queda desprotegina por la máscara.

8- Aplico sobre esta imagen manteniendo la máscara aún puesta la fórmula Min(a,b) siendo a y b los identificadores de las dos imágenes originales. Esta operación debe hacerse SIN reescalar.

9- Se guarda con formato FITS a 32-bit IEEE 754 floating poir

Esta imagen ya se pude resolver con Astrométrica para crear el log necesario para la fotometría del cometa a través de Focas. Anotar que la astrometría se echa directamente a la basura puesto que por más esmero que hayamos tenido siempre hay un desplazamiento entre las dos tomas en la posición del cometa, pero es imprescindible pasarlo primero por Astrométrica para poder crear ese apreciado log para que Focas pueda trabajar. (cosas de la vida)

No dudo que debe haber algún sistema mejor pero de momento éste es el que he encontrado."

Por cierto esto lo he podido hacer con la ultimísima versión de PI puesto que con la anterior "nasti de plasti"

Juan tu última frase hace del todo innecesario pues la petición que he hecho antes en el subforo de peticiones. Me alegro enormemente.

PD: estoy pasando una época en la que me he negado tener instalado en ningún PC de mi propiedad ningún programa del que no tenga licencia. Es por eso que me niego a hacer esto con el PS puesto que no lo tengo instalado. Otra cosa sería que la licencia de PS fuera digamos que racional pero mientras se suban a la parra...

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
¿Cómo puedo hacer un simple Cut&Paste con PI?
« Reply #4 on: 2009 January 17 12:15:39 »
Hola Daniel

Sí, es un poco demasiado complicado :)

Creo que se puede simplificar con PixelMath. En cualquier caso, hay un paso que no necesitas:

Quote
5- Abro la máscara con Gimp y hago una selección rectangular tomando como referencia las mismas coordenadas de esas dos esquinas que apunté. Una vez tengo ese rectángulo hecho, simplemente lo pinto de riguroso blanco y lo guardo.


Es mucho más fácil con esta expresión de PixelMath:

Quote
x() >= x0 && x() <= x1 && y() >= y0 && y() <= y1


y en Symbols, defines:

x0=<coordenada_horizontal_vértice_superior_izquierdo>,
y0=<coordenada_vertical_vértice_superior_izquierdo>,
x1=<coordenada_horizontal_vértice_inferior derecho>,
y1=<coordenada_vertical_vértice_inferior derecho>

Donde los elementos entre <> son los números que has obtenido en el paso 4. Eso te generará ese rectángulo blanco que necesitas; no hay necesidad de pintarlo manualmente.

De hecho, si seleccionas "Create new image" en PixelMath y especificas las dimensiones de la imagen, te puedes ahorrar los pasos 2 y 3, ya que PixelMath te generará la imagen de la máscara en la misma operación (ejecutándolo globalmente).

En cualquier caso, es un bonito ejercicio de PixelMath y del uso de máscaras :)

Quote
PD: estoy pasando una época en la que me he negado tener instalado en ningún PC de mi propiedad ningún programa del que no tenga licencia. Es por eso que me niego a hacer esto con el PS puesto que no lo tengo instalado. Otra cosa sería que la licencia de PS fuera digamos que racional pero mientras se suban a la parra...


Absolutamente fantástico :)

¿Sabes cuál es el principal competidor que tiene PixInsight, y la principal razón por la que es posible que todo nuestro proyecto se vaya al garete, por falta de la mínima rentabilidad necesaria? No es ningún programa de nuestra competencia directa; a esos no tenemos nada que temerles. No, nuestro problema es Photoshop. Pero no porque Photoshop sea mejor que PixInsight. Eso tampoco lo tememos. El problema es que Photoshop es gratis. Es muy difícil competir contra Adobe cuando sus productos cuestan cero euros. Por supuesto, esto Adobe lo sabe y lo controla perfectamente... lo triste es que la gente que usa copias piratas no sea solidaria con los que nos rompemos todos los días 12 o 16 horas tratando de hacer un trabajo digno. Y es aún más triste cuando hablamos de un "nicho comercial" como la astrofotografía.

Por eso me alegra tanto comprobar que hay gente honrada como tú, que es capaz de hacer verdaderos esfuerzos por no contribuir a este problema. Enhorabuena, y muchas gracias.
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline bosch

  • PixInsight Addict
  • ***
  • Posts: 123
¿Cómo puedo hacer un simple Cut&Paste con PI?
« Reply #5 on: 2009 January 17 15:17:48 »
Gracias a tí Juan.

Provaré esa formulita que me propones.

Offline bosch

  • PixInsight Addict
  • ***
  • Posts: 123
¿Cómo puedo hacer un simple Cut&Paste con PI?
« Reply #6 on: 2009 January 17 15:23:53 »
Bueno la fórmuloa ya la he provado y va de fábula. De hecho no tengo ni que hacer una new image puesto que simplemente hago un duplicado y sobre ella aplico la fórmula obteniendo la máscara perfecta.

Ciertamente pixel math es un gran invento miestras sepas de lenguaje metemático (que por desgracia no es mi caso)

Gracias una vez más.

Estaré ansioso por la implementación de esos iconos de edición.

Offline OriolLehmkuhl

  • PixInsight Addict
  • ***
  • Posts: 177
    • http://www.astrosurf.com/brego-sky
¿Cómo puedo hacer un simple Cut&Paste con PI?
« Reply #7 on: 2009 January 17 16:25:51 »
Hola,

bueno hemos fracasado en el Montseny estrepitosamente :( (había humedad infinita...), para animarme he hecho una pequeña interface a la formulita de Juan, seguro que mañana se pueden meter mas funcionalidades al tema, por ejemplo no aplicar el maximo, etc...

Bueno, aquí esta el scriptillo:


Code: [Select]


#include <pjsr/Sizer.jsh>
#include <pjsr/FrameStyle.jsh>
#include <pjsr/TextAlign.jsh>
#include <pjsr/StdButton.jsh>
#include <pjsr/StdIcon.jsh>
#include <pjsr/UndoFlag.jsh>
#include <pjsr/ColorSpace.jsh>
#include <pjsr/NumericControl.jsh>

var window = ImageWindow.activeWindow;
if ( window.isNull )
   throw Error( "There is no active image window!" );

function CPData()
{
 
   this.targetView = window.currentView;
   this.refView =  window.currentView;
   this.dx = -1;
   this.dy = -1;
}

data = new CPData;

function doAll() {

view = data.targetView;

   pm = new PixelMath;

with (pm) {
expression   = "Max("+data.targetView.id+",pixel("+data.refView.id+", x()+"+data.dx+", y()+"+data.dy+"))";
expression1  = "Max("+data.targetView.id+",pixel("+data.refView.id+", x()+"+data.dx+", y()+"+data.dy+"))";
expression2  = "Max("+data.targetView.id+",pixel("+data.refView.id+", x()+"+data.dx+", y()+"+data.dy+"))";
useSingleExpression = false;
rescale = true;
truncate = true;
truncateLower = 0.0000000000;
truncateUpper = 1.0000000000;
createNewImage = false;
}
view.beginProcess(UndoFlag_NoSwapFile);
pm.executeOn(view);
view.endProcess();
}

function CPDialog()
{
   this.__base__ = Dialog;
   this.__base__();

   var emWidth = this.font.width( 'M' );
   var labelWidth1 = this.font.width( "Reference image :" );

   this.targetImage_Label = new Label( this );
   this.targetImage_Label.text = "Target image :";
   this.targetImage_Label.textAlignment = TextAlign_Right|TextAlign_VertCenter;
   this.targetImage_Label.minWidth = labelWidth1;

   this.targetImage_ViewList = new ViewList( this );
   this.targetImage_ViewList.minWidth = 300;
   this.targetImage_ViewList.getAll(); // include main views as well as previews
   this.targetImage_ViewList.currentView = data.targetView;
   this.targetImage_ViewList.toolTip = " ";
   this.targetImage_ViewList.onViewSelected = function( view )
   {
      data.targetView = view;
   };

   this.targetImage_Sizer = new HorizontalSizer;
   this.targetImage_Sizer.spacing = 4;
   this.targetImage_Sizer.add( this.targetImage_Label );
   this.targetImage_Sizer.add( this.targetImage_ViewList, 100 );
//////////////////

   this.previewId_Label = new Label( this );
   this.previewId_Label.text = "Reference Image :";
   this.previewId_Label.textAlignment = TextAlign_Right|TextAlign_VertCenter;
   this.previewId_Label.minWidth = labelWidth1;

   this.previewId_ViewList = new ViewList( this );
   this.previewId_ViewList.minWidth = 300;
   this.previewId_ViewList.getAll(); // include main views as well as previews
   this.previewId_ViewList.currentView = data.targetView;
   this.previewId_ViewList.toolTip = "";
   this.previewId_ViewList.onViewSelected = function( view )
   {
      data.refView = view;
   };
   this.previewId_Sizer = new HorizontalSizer;
   this.previewId_Sizer.spacing = 4;
   this.previewId_Sizer.add( this.previewId_Label );
   this.previewId_Sizer.add( this.previewId_ViewList, 100 );

//////
   this.dx_Label = new Label( this );
   this.dx_Label.minWidth = labelWidth1;
   this.dx_Label.text = "dx:";
   this.dx_Label.textAlignment = TextAlign_Right|TextAlign_VertCenter;


   this.dx_SpinBox = new SpinBox( this );
   this.dx_SpinBox.minValue = 1;
   this.dx_SpinBox.maxValue = 10000;
   this.dx_SpinBox.value = data.dx;
   this.dx_SpinBox.onValueUpdated = function( value )
   {
      data.dx = -value;
   };

   this.dx_Sizer = new HorizontalSizer;
   this.dx_Sizer.spacing = 4;
   this.dx_Sizer.add( this.dx_Label );
   this.dx_Sizer.add( this.dx_SpinBox);


   this.dy_Label = new Label( this );
   this.dy_Label.minWidth = labelWidth1;
   this.dy_Label.text = "dy:";
   this.dy_Label.textAlignment = TextAlign_Right|TextAlign_VertCenter;

   this.dy_SpinBox = new SpinBox( this );
   this.dy_SpinBox.text = "dy";
   this.dy_SpinBox.minValue = 1;
   this.dy_SpinBox.maxValue = 10000;
   this.dy_SpinBox.value = data.dx;
   this.dy_SpinBox.onValueUpdated = function( value )
   {
      data.dy = -value;
   };

   this.dy_Sizer = new HorizontalSizer;
   this.dy_Sizer.spacing = 4;
   this.dy_Sizer.add( this.dy_Label );
   this.dy_Sizer.add( this.dy_SpinBox);
   
///////

   this.ok_Button = new PushButton( this );
   this.ok_Button.text = " OK ";

   this.ok_Button.onClick = function()
   {
      this.dialog.ok();
   };

   this.cancel_Button = new PushButton( this );
   this.cancel_Button.text = " Cancel ";

   this.cancel_Button.onClick = function()
   {
      this.dialog.cancel();
   };

   this.buttons_Sizer = new HorizontalSizer;
   this.buttons_Sizer.spacing = 4;
   this.buttons_Sizer.addStretch();
   this.buttons_Sizer.add( this.ok_Button );
   this.buttons_Sizer.add( this.cancel_Button );

   this.sizer = new VerticalSizer;
   this.sizer.margin = 6;
   this.sizer.spacing = 6;
   this.sizer.add( this.targetImage_Sizer );
   this.sizer.add( this.previewId_Sizer );
   this.sizer.add( this.dx_Sizer);
   this.sizer.add( this.dy_Sizer);
   this.sizer.add( this.buttons_Sizer );

   this.windowTitle = "Cut&Paste Script";
   this.adjustToContents();
   this.setFixedSize();
}

CPDialog.prototype = new Dialog;

function main() {
    var dialog = new CPDialog();
    var view = window.mainView;
    if ( dialog.execute() ) {
        doAll();
    }
}


main();





La verdad es que esta útil la cosa, yo  el otro dia tenia que juntar un par de imagenes en el trabajo y tube que usar el Gimp  :evil: eso se terminó ;)

Oriol

Offline bosch

  • PixInsight Addict
  • ***
  • Posts: 123
¿Cómo puedo hacer un simple Cut&Paste con PI?
« Reply #8 on: 2009 January 18 05:13:15 »
Carai Oriol!. Eres una máquina escribiendo en este para mí incomprensible lenuaje.

Gracias.

Offline OriolLehmkuhl

  • PixInsight Addict
  • ***
  • Posts: 177
    • http://www.astrosurf.com/brego-sky
¿Cómo puedo hacer un simple Cut&Paste con PI?
« Reply #9 on: 2009 January 18 09:35:44 »
Gracias Daniel, pero el tema no tiene mucho mérito..., a ver si terminamos un pequeño tutorial que teníamos del tema y veras que con muy poco ya se pueden hacer muchas cositas ;)

Dejo una nueva versión:

http://pteam.pixinsight.com/oriol.lehmkuhl/CutPaste/CutPaste.js

ahora se pueden hacer ademas del máximo, el mínimo y el average, seguro que hay más operaciones que serian interesantes, a ver si en otro ratito se ponen :)

Un saludo,

Offline C. Sonnenstein

  • PixInsight Addict
  • ***
  • Posts: 262
    • http://astrosurf.com/astro35mm
¿Cómo puedo hacer un simple Cut&Paste con PI?
« Reply #10 on: 2009 January 18 14:20:44 »
Pues es fantástico, lo he visto funcionando también en Mac :D
Carlos Sonnenstein