Comme je n'ai plus de monture, cela me laisse plus de temps pour d'autres choses...

Par exemple, réfléchir sur des traitements d'images "à la main"...

Afin de les rendre répétitif en fonction de la cible.
Càd ?
"Pousser" les curseurs dans Photoshop n'est qu'appliquer des formules mathématiques sur des valeurs...
Et je reviens donc pour ma part à l'essentiel : le code et les maths...
En gros : je réinvente la roue

, car les "pros" ont déjà tout cela sous la main dans des tas de librairies...

Mais "comprendre" est tout aussi amusant que d'observer...

Et comme il faut bien démarrer quelque part, je m'attaque aux galaxies...

Pour commencer, j'examine les meilleures méthodes pour traiter les types d'images généralement
produites par les outils "standards"(type DSS, Syril, etc...).
Si cela intéresse quelqu'un, voici quelques infos et un exemple...
Traitement de base : sur base
images TIFF DSSL'image TIFF (Autosave) générée par DSS présente quelques particularités, surtout au niveau des "tags"
utilisés pour la coder.
Par ex : avant la version 2.10, cela générait un message d'erreur dans GIMP...
REm : perso, je fais tout en Python...
Et j'ai testé les différentes librairies pour "lire" les images TIFF (PIL, pytiff, etc...).
En finale : j'ai choisi OpenCV car le support 16 bits est assuré et très souvent, selon les fonctions et librairies,
on observe une conversion (non désirée) vers 8 bits...

Voici un code "exemple" pour traiter une image DSS et tester les accentuations "ultra simplifiées".
Input : je pars de l'image fournie par Arnaud_P dans un post récent...
https://www.astronamur.net/t6130-le-triplet-du-lionL'image "brute" (en 32 bits) est la suivante, avec l'identification des galaxies
Un simple "équilibrage" (par niveaux) sans réflexion fourni directement ceci...

OK, c'est pas beau du tout, mais cela montre que chaque galaxie mérite "son" traitement individuel...
Pour atteindre un niveau satisfaisant pour la NGC, il faut "cramer" les deux autres...
Peut-on faire mieux, en traitant galaxie par galaxie ?
Certes, et on est parti avec des "masques", "layer" et autres calques...
Mais ici, on va revenir au "traitement par pixel"...
Logique utilisée : - on extrait d'une image globale les galaxies
- on examine les valeurs moyenne par plan couleur
- si un pixel dépasse la moyenne, on l'augmente d'un proportion définie dans une liste de valeur
Cela fait quoi ? A ce stade, cela ne fait que "déterminer" le contour de l'objet, en le renforçant
par saturation.
Ex: si la moyenne des R =0.02, B=0.02, G=0.03 (soit très proche), si on découvre par couleur
un pixel supérieur à cette valeur (ex : 0.05 partout), le résultat sera "accentué" d'un valeur fixe
Soit 0.05 + 0.1 = 0.15, soit 3x l'intensité de départ...
Si on applique cela sur tous les points, on obtient rapidement une forme "blanche" générale +
pixels caractéristiques accentués = un "détour" de l'objet et de son environnement.
C'est très simpliste, mais permet déjà d'analyser la zone "avec signal" dans l'image...
Après, il ne restera qu'à faire évoluer la fonction d'évaluation et de modification (bref, il y a du boulot et de la lecture...)
Code Python : - Code:
-
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 2 20:00:26 2020
Pre-processing of galaxies in DSS stacked image
@author: TTF
"""
import cv2
import matplotlib.pyplot as plt
#Read DSS stacked image in 16 bits value
#>>> in this case, the Lion's Triplet galaxy group
image = cv2.imread('F:\$Photos_Astro\TripletLion\Autosave.tif', -1)
print("Image type : ",image.dtype)
print("Image size :",image.shape)
#CV2 convert original values to float value (range [0..1], 1 = original 65535)
print("Image values range : from ",image.min()," to ",image.max())
print("Image mean value : ",image.mean())
# for debugging, show complete image, imshow also uses float values (convert to RGB)
#imgplot = plt.imshow(image)
#plt.show()
# identify galaxies on image coordinates
galaxy_name = ["M66","NGC3628"]
galaxy_list = [0,1]
galaxy_x = [1958,2061,1893,2429]
galaxy_y = [3157,3393,1832,2494]
# extract galaxies from image
galaxy = []
color_code=["B","G","R"]
# at each extraction, evaluate min, max, mean pixel value (by color plane)
for g in galaxy_list:
print("Galaxie = ",g,galaxy_name[g],galaxy_x[g*2],galaxy_x[g*2+1],galaxy_y[g*2],galaxy_y[g*2+1])
galaxy_region = image[galaxy_x[g*2]:galaxy_x[g*2+1],galaxy_y[g*2]:galaxy_y[g*2+1]]
galaxy.append(galaxy_region)
# show global extracted area values
for p in range(0,3):
print("Color ",color_code[p]," min:",galaxy_region[:,:,0].min()," max:",
galaxy_region[:,:,p].max()," mean: ",
galaxy_region[:,:,p].mean())
#a function to determine a trigger level for pixel enhancement
#>>>in this case : mean(color plane pixel values)
def pixel_evaluate(region,x,y,p):
if (region[x,y,p] > region[:,:,p].mean()):
return True
else:
return False
#a function to execute pixel enhancement
#>>>in this case : simply add a value to pixel
def pixel_update(value_in,value_mod):
value_out = value_in + value_mod
if (value_out > 1):
value_out=1
return value_out
#enhance all pixels when trigger (pixel_evaluate) is reached
#define a list of value to test on image (if "evaluate" is true, apply it to "update" function)
values = [0.1,0.15,0.2]
for g in galaxy_list:
# show original image
imgplot = plt.imshow(galaxy[g])
plt.title(galaxy_name[g])
plt.show()
# for each tested enhancement values
for v in values:
nb_pix = 0
galaxy_work = galaxy[g]
# for each pixel in image
for x in range(0,galaxy_work.shape[0]) :
for y in range(0,galaxy_work.shape[1]):
#in each color plane
for p in range(0,3):
#evaluate trigger value for concerned pixel, if true : update pixel
if (pixel_evaluate(galaxy_work,x,y,p)):
galaxy_work[x,y,p] = pixel_update(galaxy_work[x,y,p],v)
nb_pix += 1
#show enhanced result
print("Computed for :",v, "updated pixels :",nb_pix)
imgplot = plt.imshow(galaxy_work)
plt.title(galaxy_name[g] + " - " + str(v))
plt.show()
A l'exécution :
Image type : float32
Image size : (3353, 5164, 3)
Image values range : from 6.833779e-06 to 0.99609375
Image mean value : 0.018040543
Galaxie = 0 M66 1958 2061 3157 3393
Color B min: 0.016355991 max: 0.28375491 mean: 0.026078194
Color G min: 0.016355991 max: 0.26298663 mean: 0.02345788
Color R min: 0.016355991 max: 0.27330488 mean: 0.023381593
Galaxie = 1 NGC3628 1893 2429 1832 2494
Color B min: 0.01416597 max: 0.9799306 mean: 0.01825534
Color G min: 0.01416597 max: 0.9730561 mean: 0.018156482
Color R min: 0.01416597 max: 0.94475085 mean: 0.018262794
Computed for : 0.1 updated pixels : 8831
Computed for : 0.15 updated pixels : 8831
Computed for : 0.2 updated pixels : 8831
Computed for : 0.1 updated pixels : 42465
Computed for : 0.15 updated pixels : 42465
Computed for : 0.2 updated pixels : 42465
On peut voir que sur la première galaxie, seulement 8831 pixels dépassent la moyenne du ciel (dans sa couleur)
et pour la deuxième, c'est 42K pixels.
On a déjà clairement la confirmation que si on applique un traitement global sur tous les pixels, on ne les équilibrera jamais...
Ensuite, que
- la moyenne de l'image totale avoisine 0.018
- les maximum (incluant les étoiles) = proche de la saturation dès le départ...
Et cela donne :








Dans les deux cas, il y a des "extensions" clairement visibles, qu'il faudra analyser et traiter de manière adaptées...
Ok, ce n'est qu'un début...

Mais pour ceux qui veulent se lancer dans le domaine...

Voici un exemple de code


Y a plus qu'à...
Et maintenant....
En regardant ce que j'ai tapé, je me rends compte qu'il y a une (toute petite) erreur dans le code...
(Evidemment, je viens de la corriger dans mon programme, mais pas ici...

)
Saurez-vous détecter laquelle ?

Que le Python soit avec vous...
