Aunque durante el apilado los métodos de rechazo suelen filtrar las imágenes de peor calidad, siempre realizo una inspección visual para descartar aquellas que no deben ser procesadas.
Siril dispone de un script que permite hacerlo de una forma gráfica y sin tener que registrar las imágenes previamente.
También comento al final del post otro método más 'manual' que incluye un pequeño script escrito por mí.
Blink/browse/filter/sort
Esta herramienta la encontraremos dentro del apartado de scripts, en utilidades:
Dependiendo del número de imágenes, el proceso puede tardar un tiempo, al final del cual nos mostrará el total de elementos analizados
Podemos desplazarnos por las diferentes imágenes usando los botones Next/Prev y marcar/desmarcar las imágenes usando los botones Toggle Include/Select All, Unselect All e Invert selection.
El único problema que veo es que la imagen no se le hace el debayer
Otra opción muy interesante es la posibilidad de filtrar de forma automática en función de ciertos parámetros. Para ello, si desplegamos el menú Image Filtering:
En este ejemplo selecciono filtrar únicamente aquellas imágenes cuyo FWHM es inferior a 0.5 y cuyas estrellas tengan una redondez superior a 0.910 en valores absolutos
Si pulsamos el botón Create sequence nos generará una secuencia con las imágenes filtradas lista para que Siril pueda procesarlas
Además, nos ha creado también una carpeta rejected con las imágenes que no han pasado el filtro
Manual
Este proceso es más manual, pero realiza un debayer de la imagen, por lo que visualmente es más sencillo decidir la calidad.
Requiere el uso de un script hecho por mí el cual os dejo al final del post.
Creamos una carpeta process y la seleccionamos como carpeta de trabajo en Siril.
En la pestaña de conversión añadimos las imágenes Light de nuestra sesión, ponemos nombre a la secuencia, marcamos a casilla Debayer y pulsamos en Convertir.
Una vez finalizado el proceso, aparecerá la primera imágen de las capturadas y por defecto estará en modo lineal con los canales de color enlazados. Normalmente. en este modo solo veremos las estrellas más brillantes y el color será tintado a verde.
Para poder analizar las imágenes con detalle seleccionaremos el modo de pantalla AutoExtender y desmarcaremos el enlace de colores
A continuación pulsaremos en el botón de la esquina inferior derecha para abrir la lista de imágenes
Desde aquí podemos navegar fácilmente por cada imagen y revisar en la vista principal si debemos mantenerla o descartarla.
Por defecto aparecen todas marcadas y podemos marcar/desmarcar individualmente o agrupando o seleccionar/desmarcar todas.
Así por ejemplo, la segunda imagen aparece algo que cada vez es más común, como son satélites artificiales o, como es el caso, aviones. En este caso la desmarcamos para que no sea tenida en cuenta durante el procesado apilado
Debe indicarse, no obstante que existen herramientas que permiten eliminar estas trazas y que algunos métodos de apilado permiten minimizar el impacto de estos artefactos en la imagen final
Una vez hemos desmarcado aquellas que no nos interesan y desde Scripts > Python Scripts > Scripts, seleccionamos mi script unselected_file_discard el cual dejo al final
Pulsamos en Browse y seleccionamos la secuencia que habíamos creado, y seguidamente hacemos clic en el botón Process unselected subs.
Si no marcamos la casilla Remove unselected... el script creará una subcarpeta denominada discarded y moverá los archivos no seleccionado allí, dejando la carpeta Lights solo con los archivos seleccionados.
Si marcamos esa casilla, directamente los borrará -no hay opción de deshacer-
Si vamos a utilizar scripts para el apilado de imágenes, podemos borrar la carpeta process creada al principio
El script es este:
import osimport reimport sysfrom PyQt6.QtWidgets import (QApplication,QMainWindow,QWidget,QVBoxLayout,QHBoxLayout,QLabel,QPushButton,QLineEdit,QTextEdit,QFileDialog,QMessageBox,QCheckBox,)from PyQt6.QtCore import Qtclass SirilCleaner(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("Discard Unselected Siril Subs")self.setMinimumSize(600, 440)central_widget = QWidget()self.setCentralWidget(central_widget)layout = QVBoxLayout(central_widget)# Seq file inputseq_layout = QHBoxLayout()seq_label = QLabel("Siril Sequence File (.seq):")self.seq_edit = QLineEdit()self.seq_browse_button = QPushButton("Browse...")self.seq_browse_button.clicked.connect(self.browse_seq_file)seq_layout.addWidget(seq_label)seq_layout.addWidget(self.seq_edit)seq_layout.addWidget(self.seq_browse_button)layout.addLayout(seq_layout)# Move instead of delete checkboxself.move_checkbox = QCheckBox("Remove unselected frames to 'discarded' folder instead of deleting")layout.addWidget(self.move_checkbox)# Remove buttonself.remove_button = QPushButton("Process unselected subs")self.remove_button.clicked.connect(self.remove_unselected)self.remove_button.setStyleSheet("background-color: red; color: white; font-weight: bold;")layout.addWidget(self.remove_button)# Log windowself.log_text = QTextEdit()self.log_text.setReadOnly(True)self.log_text.setStyleSheet("background-color: black; color: white; font-family: Consolas; font-size: 10pt;")layout.addWidget(self.log_text)def log_message(self, message):self.log_text.append(message)self.log_text.ensureCursorVisible()def browse_seq_file(self):seq_path, _ = QFileDialog.getOpenFileName(self, "Select Siril Sequence File (.seq)", "", "Siril Sequence Files (*.seq)")if seq_path:self.seq_edit.setText(seq_path)self.log_message(f"Selected sequence file: {seq_path}")def remove_unselected(self):seq_path = self.seq_edit.text().strip()if not seq_path or not os.path.isfile(seq_path):QMessageBox.critical(self, "Error", "Please select a valid sequence (.seq) file.")self.log_message("Error: Invalid or missing sequence file path.")returnbase_dir = os.path.dirname(seq_path) # e.g. M_74/processseq_name = os.path.basename(seq_path) # e.g. m74.seqseq_name_base = seq_name[:-4] # remove .seq extensionconversion_name = f"{seq_name_base}conversion.txt"conversion_path = os.path.join(base_dir, conversion_name)if not os.path.isfile(conversion_path):QMessageBox.critical(self, "Error", f"Conversion file not found:\n{conversion_path}")self.log_message(f"Error: Conversion file not found: {conversion_path}")returnconv_map = {}lights_dir = Nonetry:with open(conversion_path, 'r') as f:for line in f:m = re.match(r"'(.*?)'\s*->\s*'(.*?)'", line.strip())if m:orig_path, conv_name = m.groups()conv_map[conv_name] = orig_pathif lights_dir is None:lights_dir = os.path.dirname(orig_path)except Exception as e:QMessageBox.critical(self, "Error", f"Failed reading conversion file:\n{e}")self.log_message(f"Error reading conversion file: {e}")returnself.log_message(f"Inferred lights folder: {lights_dir}")if not lights_dir or not os.path.isdir(lights_dir):QMessageBox.critical(self, "Error", f"Lights folder not found:\n{lights_dir}")self.log_message(f"Error: Lights folder not found: {lights_dir}")return# Setup discarded folder path one level above lights folder (M_74/discarded)discarded_dir = os.path.join(os.path.dirname(lights_dir), "discarded")if not self.move_checkbox.isChecked() and not os.path.exists(discarded_dir):try:os.makedirs(discarded_dir)self.log_message(f"Created discarded folder: {discarded_dir}")except Exception as e:QMessageBox.critical(self, "Error", f"Failed to create discarded folder:\n{e}")self.log_message(f"Error creating discarded folder: {e}")returnidx_enabled = {}try:with open(seq_path, 'r') as f:for line in f:if line.startswith("I "):parts = line.strip().split()if len(parts) >= 3:idx = int(parts[1])enabled = parts[2] == "1"idx_enabled[idx] = enabledexcept Exception as e:QMessageBox.critical(self, "Error", f"Failed reading sequence file:\n{e}")self.log_message(f"Error reading sequence file: {e}")returnto_process = []pattern = re.escape(seq_name_base) + r"(\d+)"for conv_name, orig_file in conv_map.items():m_idx = re.search(pattern, conv_name)if m_idx:idx = int(m_idx.group(1))if idx_enabled.get(idx, True) is False:to_process.append(orig_file)else:self.log_message(f"Warning: Could not find index in file {conv_name}")if not to_process:QMessageBox.information(self, "No files to process", "No unselected frames found to move or delete.")self.log_message("No unselected frames detected in sequence.")returnprocessed_count = 0for f in to_process:if os.path.exists(f):try:if not self.move_checkbox.isChecked():# Move file to discarded folderbasename = os.path.basename(f)target_path = os.path.join(discarded_dir, basename)os.rename(f, target_path)self.log_message(f"Moved to discarded: {target_path}")else:# Delete fileos.remove(f)self.log_message(f"Deleted: {f}")processed_count += 1except Exception as e:self.log_message(f"Failed to process {f}: {e}")else:self.log_message(f"File not found, skipping: {f}")action = "moved to 'discarded'" if not self.move_checkbox.isChecked() else "deleted"QMessageBox.information(self, "Done", f"{processed_count} unselected light frames {action}.")self.log_message(f"Operation complete. {processed_count} files {action}.")if __name__ == "__main__":app = QApplication(sys.argv)window = SirilCleaner()window.show()sys.exit(app.exec())
En la carpeta que tengáis de scripts de siril, crear un archivo llamado unselected_file_discard.py y con un editor pegáis el código de arriba. Guardáis y cerráis.
Para que Siril lo reconozca, la primera vez deberéis ir a Scripts > Obtener scripts aseguraros de que la carpeta donde habéis guardado el archivo está en la lista de Directorio de almacenamiento de scripts y pulsar el botón de refrescar
No hay comentarios:
Publicar un comentario