Los colores de las imágenes astronómicas
07 Sep 2020La astronomía es sinónimo de imágenes asombrosas y siderales, literalmente fuera de este mundo. Composiciones a todo color que nos recuerdan que el universo está lleno de estructuras increibles, y conduce a la reflexión sobre nuestra realidad así como también del lugar que nos corresponde en el universo conocido. El correcto análisis de estas imágenes nos permite extraer información crítica desde la luz que emiten esos puntitos brillantes que habitan el cielo. A través de la física y sus artilugios matemáticos somos capaces de leer la luz entre lineas, para así comprender los secretos de quienes producen esta radiación: estrellas, galaxias, sus grupos...además de burbujas y marañas de gas y polvo, como las piedras que las orbitan.
La estética de la astronomía explica a sus multitudinarios y curiosos seguidores, despertando una de las dudas más comunes: ¿los colores de las imágenes son reales? ¿o son parte del malvado fotochop de la NASA con el fin de controlar nuestra vida?. Colorear imágenes es un proceso bien conocido, teniendo bases en el proceso biológico de cómo los humanos percibimos el color y cómo se entiende esta información de forma digital. Desde esta premisa, en las siguiente líneas haré el esfuerzo de unir todos estos cabos, cómo (des)componer una imagen y mostrales la forma de colorear una imagen astronómica.
El ojito humano y el color RGB.
El ojo humano es el resultado de millones de años de evolución en los cuales su sistema óptico se adaptó a la luz del Sol, nuestra bola de gas favorita. Este sistema óptico recibe y canaliza la luz hasta unas celulas especializadas fotosensibles, llamadas conos y bastones. Según wikipedia Los bastones se activan en condiciones de baja luminosidad. Los conos, por su lado, se ven estimulados en entornos con mayor iluminación y nuestros ojos están poblados por tres variedades diferentes: conos rojos, verdes y azules; sensibles a la luz visible con la cual se apellidan.
Esta sensibilidad particular a ciertos colores no es (taan) antojadiza, pasa que el sol emite muchos tipos de luz, pero la radiación que alcanza la tierra con mayor intensidad contiene estos colores, y a esto se le llama *espectro visible*, luz visible, o simplemente luz. Pero hay muchas otras variedades de luz las cuales son representadas en el rango electromagnético, que va desde las ondas de radio a los rayos gamma. Pasó que el sol emite mucha luz en el rango visible, el ojo humano se adaptó a esta radiación lo largo de su existencia y por eso vemos los colores del arcoiris. Esta es una idea muy poderosa, que nos lleva a pensar cómo se desarrollarían los detectores de radiacion (a.k.a. ojos) de seres que podrían habitan planetas con estrellas que emiten diferente luz, o también como la inexistencia de luz hace que no se desarrollen tales detectores. La siguente imágen muestra el rango electromagénico y su comparación de la luz que existe versus la luz que podemos observar, la luz visible.
Cuando la luz de una fuente luminosa incide sobre un objeto, absorbe ciertos colores y refleja otros. Es esa luz que hace rebotar un cierto objeto la que alcanza nuestros ojos y activa los diferentes conos en proporciones establecidas por los nervios ópticos, lo que nuestro cerebro interpreta como "un color". Simplificando todo, nuestro cerebro tiene 3 colores básicos y todas sus posibles proporciones para colorear nuestra realidad: rojo, verde, azul y sus conocidos mundialmente como RGB (del acrónimo inglés Red, Green, Blue). Estos colores clásicamente se conocen como colores primarios, ya que a partir de esta triada es posible obtener por completo el rango de colores del arcoiris.
Y ya que estamos aquí, es interesante señalar que de hecho vemos aún más colores que los que viven en la luz visible. El color Magenta es un claro ejemplo de esto, ya que no existe luz de este color con una longuitud de onda asociada en el mundo real. Esto significa que este color existe solo en nuestros cerebros, y es la interpretación de la superposición de dos diferentes longuitudes de onda de luz incidente. El siguiente video retrata de mejor manera lo que acabo de explicar:
from IPython.lib.display import YouTubeVideo
from datetime import timedelta
start=int(timedelta(hours=0, minutes=1, seconds=9).total_seconds())
YouTubeVideo("s4I6zosOqpo", start=start, autoplay=0, theme="light", color="red")
Un mundo lleno de imágenes
Las imágenes son importantisimas en el día a día y ya son de uso cotidiano, al punto que ya no es necesario cuestionarse qué son en realidad y cómo pueden llegar a usarse para determinar misterios. Tan exitoso ha sido la integración de las imágenes a nuestro vertiginoso estilo de vida que muchas personas ignoran el hecho que son sólo un gran arreglo de números interpratados para que se parezcan lo más posible a lo que nosotros vemos: un instante congelado en el tiempo.
Las primeras imágenes se remontan al año 1839 gracias al daguerrotipo, el cual consistía en placas de cobre con películas de plata, que las convierte una superficie fotosensible, colectora de luz. Antes de esto había que ser buen dibujante para registrar los relieves y cráteres de la luna como hizo Galileo. Los métodos fotosensibles fueron perfecionandose a lo largo del tiempo, pasando por muchos formatos a lo largo de las décadas, como La placa fotográfica y cintas magnéticas. Hasta 1969, año en el que se desarrollaron los detectores electrónicos fotosensibles CCDs que cada uno de nosotros tiene en su teléfono, y que el 2009 (¡luego de 40 años!) les dio el novel de física a sus creadores Willard Boyle y George E. Smith.. Fue aquí donde se introdujo y popularizó el pixel como la undad básica de una imagen digital. Cada imagen, fotografía o contenido gráfico digital está hecho de pixeles, y de forma similar a los conos de nuestros ojos, cada uno de estos pixeles contiene 3 canales de color: rojo, verde y azul (o RGB). Combinando las intensidades de estos diferentes colores cada pixel puede motrar toda la gama de colores posibles, emulando así la lógica del ojo humano y creando la transición análogo/digital de la imagen.
En términos computacionales, podremos entender una imagen como un cubo de datos de (Pixeles$_{alto}\times$ Pixeles$_{largo}\times 3$). Para entrar un poco más en detalle y hagamos una biopsia a una imagen, usaremos el lenguaje de programación Python en su versión 3, que ya estamos usando pero no te diste ni cuenta. Para que funcione como corresponde, es necesario importar las funcionalidades básicas y librerías con las cuales visualizaremos todo:
#importamos librerias y cositas utiles
%matplotlib inline
import numpy as np
from matplotlib.pyplot import imread
from scipy.misc import *
from scipy import ndimage
import matplotlib.pyplot as plt
from PIL import Image
#definimos algunos parametros:
Dh = (6,4.5)
fz=12
Con todo esto ya funcionando, leeremos una imagen de la estructura de una nube; imagen que fue capturada mientras el sol se estaba poniendo, dándole su color rojizo:
plt.figure(figsize=Dh)
Nubes = imread('IMG_9164.JPG')
#Miramos las dimensiones de la imagen:
dimensiones = Nubes.shape
print("Dimensiones de la imagen:")
print("(alto, largo, canales) =",dimensiones)
plt.imshow(Nubes)
plt.xlabel('pixeles',size=12)
plt.ylabel('pixeles',size=12)
plt.show()
La información de las dimensiones arriba desplegada nos dice que la imagen tiene 2848 pixeles de alto, 4248 pixeles de largo y que está compuesta por tres arreglos de datos, que son los canales de color; cada uno de estos canales posee las mismas dimensiones antes estipuladas.
Es así que la imagen desplegada, para cada valor Nubes[x,y]
existen 3 valores de rojo, verde, y azul, los cuales en conjunto muestran el color. En el caso anterior supongo que el color rojo domina dadas las virtudes del arrebol de la tarde. Pero no nos quedemos en supuestos y veamos la contribución de cada canal en el color de nuestra nubecita roja. Seleccionaremos todas las filas de pixeles, y 900 columnas en la parte central de la imagen, así nuestra nueva imagen Nubecita[x,y]
tendrá 2848x900 pixeles y sus 3 canales RGB. Seleccionaremos cada canal de color por separado para así visualizar la contribución de cada uno de estos colores ejerce en la imagen "Original":
#Separamos cada canal 0,1 y 2 de forma individual desde subImagen
Nubecita = Nubes[:,2000:2900]
dimensiones = Nubecita.shape
print("Dimensiones de la imagen:")
print("(alto, largo, canales) =",dimensiones)
r = Nubecita[:,:,0] #Canal rojo
g = Nubecita[:,:,1] #Canal verde
b = Nubecita[:,:,2] #Canal azul
f,ejes = plt.subplots(1,4,figsize=Dh,sharey=True)
ejes[0].imshow(Nubecita)
ejes[0].set_title("Nubecita")
ejes[1].imshow(r)
ejes[1].set_title("canal rojo R")
ejes[2].imshow(g)
ejes[2].set_title("canal verde G")
ejes[3].imshow(b)
ejes[3].set_title("canal azul B")
plt.tight_layout()
plt.savefig("Ver_canales.png", dpi=300)
plt.show()
En el esquema anterior, las imágenes de cada canal están "coloreadas falsamente", esto quiere decir que sus colores representan un código y una escala para que podamos distinguir sus contribuciones (en este caso sería en las partes...¿amarillas, verdes?, lo más brillante), o donde no la hay (las partes azules y oscuras). Normalmente estas imágenes se les representa en escala de grises, pero bueno, ese era el color por defecto, ná que hacerle ¯\_(ツ)_/¯.
Ahora, podemos ver cuánto aporta a la imagen cada canal RGB de forma individual. Es fácil darse cuenta que la contribución del canal rojo R está en todas partes, domina las estructuras y los valores de la imagen Nubecita
. Por otro lado, el canal azul mayoritariamente no aporta, y solo está presente en la parte central, donde casi no hay nubes y el cielo está de fondo. Desde aquí debo destacar dos aspectos:
- Desde la correcta suma de las imágenes
R+G+B
es posible obtener la imagenNubecita
de vuelta. - Las imágenes de canal son ejemplos perfectos de una imagen producida por un "filtro optico", que muestra la contribución de luz en un rango definido.
- Hacer listas es mi pasión.
Una propiedad fundamental que se desprenden de los filtros es que ven cosas diferentes al observar la misma fuente de luz. Por ejemplo si quisieramos describir la forma de la nube imagen nubecita
, sería mejor estudiar el canal rojo, ya que es más sensible a la luz que se emite desde las nubes. Por otro lado, podríamos usar el filtro azul para saber dónde no hay nube, por decir algo jajaja, el filtro malo.
Es por eso que una fuente luminosa se estudia en muchos filtos, ya que la cantidad y tipo de luz de cada filtro se pueden usar para resaltar distintos elementos de un mismo fenómeno.
¡Ya tenemos nuestras primeras herramientas! ¿Para qué podrían llegar a servir? Bueno, la manipulación de imágenes es una práctica recurrente en el día de hoy y muchas son sus aplicaciones, no solo para hacer memes. Lo importante aquí en mi humilde opinión, es darse cuenta que las imagenes sólo son números en un arreglo de datos dispuestos a ser ordenados como bloques, cual Legos. Entenderlos apropiadamente nos da muchas posibilidades, por ejemplo veamos una imagen de la luna que hice hace un tiempo cuando habia una conjunción con el planeta Júpiter, que se nota como un pequeño punto brillante al lado contrario de la luna y le haremos un corte (o un "Zoom digital" que le llaman a veces) al satélite natural:
plt.figure(figsize=Dh)
Luna = imread('IMG_9206.JPG')
plt.imshow(Luna)
plt.title("Imagen original",size=12)
plt.xlabel('pixeles',size=12)
plt.ylabel('pixeles',size=12)
plt.show()
subImagen = Luna[500:1050,650:1200]
dimensiones = subImagen.shape
print("Dimensiones de la imagen recortada:")
print("(alto, largo, canales) =",dimensiones)
plt.figure(figsize=(6.5,6.5))
plt.imshow(subImagen)
plt.title("Imagen recortada",size=12)
plt.xlabel('pixeles',size=12)
plt.ylabel('pixeles',size=12)
plt.show()
O podríamos también crear nuevas imágenes a partir de otras. En gran parte de los casos esto será posible sólo si las imágenes a combinar poseen las mismas dimensiones. Si la condición anterios se cumple, podemos llegar y sumar las imágenes diréctamente. Por ejemplo, y sólo por capricho, agregaré otra imagen de la luna en fase menguante, además de rotar la imagen 1 en 180 grados, y sumaremos todo en una gran imagen. No se diga más.
#Leemos la nueva imagen de la luna para componer:
creciente = imread('IMG_7793.JPG')
plt.figure(figsize=Dh)
plt.imshow(creciente)
plt.title("Luna creciente",size=15)
plt.xlabel('pixeles',size=12)
plt.ylabel('pixeles',size=12)
plt.show()
#Rotamos la imagen original de la luna
Luna_rotada180 = Image.fromarray(np.rot90(Luna, 2))
#Sumamos todas las imágenes y componemos:
plt.figure(figsize=Dh)
plt.imshow(Luna+Luna_rotada180+creciente)
plt.title("Luna creciente + Luna1 + Luna1 rotada",size=15)
plt.xlabel('pixeles',size=12)
plt.ylabel('pixeles',size=12)
plt.show()
Bueno, hay algunos detalles de los cuales mejorar en esta composición; como esos puntos blancos sobre la luna creciente que posiblemente están sobre-expuesta dada la combinación de las 3 imagenes. Pero en realidad da igual, programas de edicion de datos como Photoshop o Gimp se especializa en esto y sin tener que saber tanto sobre la composicion, estructura de imágenes, ni de filtros gaussianos, etc.
Pero yo les prometí imágenes astronómicas, además en astronomía/astrofísica, a casi a nadie le importa la luna. Es más, nos cuidamos de su prescensia y apuntamos los telescopios cuando no está para que su terrible luz no opaque los escasos fotones que provienen de nuestras fuentes astronómicas favoritas. Esto es todo lo que tengo que decir con respecto a la luna.
El color de las imágenes astronómicas
Por si no lo sabían, la cantidad de información astronómica disponible en este momento es brutal, onda en el orden de Petabytes de información (1.000.000.000.000.000 bytes) se producen a diario, y en el futuro cercano esta tasa irá al alza, o bueno esa era la proyección antes de la pandemia y la desolación mundial del 2020. Mucha de estas imágenes hecha por telescopios en Tierra y el espacio, como la información que ha sido obtenido a lo largo de su análisis ya es de libre acceso, y algunos sets de datos están especialmente orientados a la divulgación científica, como las históricas imágenes de la Nebulosa del Aguila.
YouTubeVideo("4DoxwB5kWT4", autoplay=0, theme="light", color="red")
Hechas con la cámara WFPC2 montada en el telescopio espacial Hubble, las imágenes alojadas en la página de la NASA muestran los llamados "Pilares de la creación", las cuales componen parte de la nebulosa del Aguila, y son columnas de polvo desde donde la gravedad hace lo suyo y ensambla nuevas estrellas. Ya el hecho de que tenga nombre propio habla de la popularidad e impacto que tuvo esta imágen alrededor del mundo. Formalmente a este tipo de estructuras se les conoce como "pilares moleculares fríos", como también "*trompas de elefante*".
Estas imágenes están hechas usando filtros de banda estrecha (narrow filters), los cuales se encargan de medir la luz emitida por un elemento en particular, el cual emite radiación en una longuitud de onda específica del rango electromagnético. Las imágenes disponibles están en formato FITS, que es el formato por defecto en la astronomía actualmente.
Entonces, las imágenes disponibles para componer los pilares de la creación son:
- Filtro estrecho de Oxígeno doblemente ionizado (OIII), medido a 502 nanómetros.
- Filtro estrecho de Hidrógeno Alfa (H$_\alpha$), la cual posee $\lambda=656$ nanómetros, por supuesto.
- Y por ultimo, filtro estrecho de Azufre ionizado (SII), medido a 673 nanómetros
Los elementos anteriores se encuentran presentes en el medio estelar, y son emitidos por la composición e interacción de nebulosas como la que nos interesa. Entonces, descargaremos las imágenes, las leeremos de la misma forma como lo hicimos hace unos momentos más arriba, y luego usaremos la funcion sqrt
disponible en astrobetter para ayudar en la visualización de las imágenes:
#Vamos a leer imágenes fits, así que nos preparamos
from astropy.io import fits
OxigenoIII = fits.getdata("502nmos.fits")
H_alpha = fits.getdata("656nmos.fits")
AzufreII = fits.getdata("673nmos.fits")
grados = 270
fz=(6.5,5.8)
plt.figure(figsize=fz)
rotated_img = ndimage.rotate(AzufreII, grados)
plt.title("banda de Azufre II")
plt.imshow(rotated_img, cmap='gray', vmin=0, vmax=120)
cbar = plt.colorbar()
cbar.set_label('cuentas',size=12)
plt.ylabel('pixeles',size=12)
plt.show()
plt.figure(figsize=fz)
rotated_img = ndimage.rotate(H_alpha, grados)
plt.title(r'banda de Hidrogeno $\alpha$')
plt.imshow(rotated_img, cmap='gray', vmin=20, vmax=800)
plt.ylabel('pixeles',size=12)
cbar = plt.colorbar()
cbar.set_label('cuentas',size=12)
plt.show()
plt.figure(figsize=fz)
rotated_img = ndimage.rotate(OxigenoIII, grados)
plt.title("banda de Oxigeno III")
plt.imshow(rotated_img, cmap='gray', vmin=0, vmax=20)
plt.ylabel('pixeles',size=12)
plt.xlabel('pixeles',size=12)
cbar = plt.colorbar()
cbar.set_label('cuentas',size=12)
plt.show()
Es posible ver las diferencias, sin dudas (¿verdad?). Por un lado la imagen de AzufreII remarca mucho más los bordes de las nubes, dado que este elemento se encuentra cuando gases a grandes velocidades colisionan. Por otro lado el OxigenoIII y H$_\alpha$ son elementos que se emiten y mapean la materia que está en nuestra querida nebulosa. El OxigenoIII también se ve difuso y marca mucho la absorción de dos de los tres pilares.
Ahora ¿Podemos crear una imágen con estas tres imágenes? Por supuesto, pero será una IMAGEN DE COLOR FALSO. Lo que quiere decir que imágenes realizadas con filtros que no tienen que ver con un color en sí, serán asignados al canal de color para que nuestros ojos puedan entender sus caracteristicas y complejas composiciones fuera de nuestro rango de visión.
Con esto en mente, usaremos python para crear un cubo de datos, y asignaremos cada imagen de filtro estrecho a un canal de color RGB: rojo al mapeo del AzufreII, verde para la emisión de Hidrógeno alfa y el canal azul será para la luz del Oxígeno doblemente ionizado. Con esto, podemos obtener la siguiente imagen.
#Creamos el cubo de datos a la fuerza
img = np.zeros((AzufreII.shape[0], AzufreII.shape[1], 3), dtype=float)
#Asignamos cada filtro a un canal:
#Silicio al rojo:
img[:,:,0] = sqrt(AzufreII, scale_min=0, scale_max=180)
#Hidrógeno al verde:
img[:,:,1] = sqrt(H_alpha, scale_min=0, scale_max=1200)
#Oxígeno al azul:
img[:,:,2] = sqrt(OxigenoIII, scale_min=0, scale_max=120)
plt.figure(figsize=fz)
rotated_img = ndimage.rotate(img, grados)
plt.imshow(rotated_img)
plt.title(r'{rojo$\rightarrow$SII, verde$\rightarrow$H$_\alpha$, Azul$\rightarrow$OIII}')
plt.ylabel('pixeles',size=12)
plt.xlabel('pixeles',size=12)
plt.show()
Exito!! Estoy contento porque esta es la primera imángen de color falso que compongo :'). Se ve un poco más opaca que la oficial, habría que espejarla con respecto al eje y también, pero estoy conforme. Ahora sabemos cómo los diferentes elementos químicos presentes en los medios interestelares son representados a través de los colores, dándonos las hermosas y abstractas composiciones que el universo tiene para presentarnos.
Ahora, en esos canales de colores es posible poner cualquier imagen hecha con un filtro o escala de grises. Si esto de las bandas aún es un poco confuso, Javiera de Startres lo explica mucho mejor que yo. En su ejemplo, nuestra imagen compuesta correspondería a una imagen realzada.
start=int(timedelta(hours=0, minutes=3, seconds=4).total_seconds())
YouTubeVideo("YZDJ-K6FiuI", start=start, autoplay=0, theme="light", color="red")
Todo un universo por componer
Cada una de las imágenes a color que muestra la astronomía nos detalla diferentes aspectos de la realidad, muestra elementos complejos que afloran en el centro de las estrellas y emiten los destellos de procesos físicos que pueden llegar a ocurrir en estos ambientes. Cada color puede ser usado para mapear estos efectos, para colorear escalas útiles con el fin de cuantificar interacciones en el medio interestelar; o en general destacar un aspecto diferente de alguna fuente de información en dos dimensiones. Por ejemplo, la siguiente imagen muestra los pilares de la creación (izquierda) compuesta de forma muy similar a cómo nosotros lo hicimos, y a la derecha está compuesta con imágenes de luz infrarroja.
La diferencia es innegable. Ambas conservan la emisión en los bordes de las estructuras, pero la imagen infrarroja muestra incontables estrellas (los puntos brillantes) ¿Por qué? El polvo y las nubes de gas en bajas concentraciones son prácticamente invisibles para la luz infrarroja, por lo que las imágenes hechas en estas bandas nos muestran la luz de estrellas y estructuras escondidas detrás del polvo interestelar, demostrando uno de los grandes problemas de la astronomía: La extinción de la luz.
En mi caso, yo uso imágenes en el rango infrarrojo para así estudiar estrellas detrás de las nubes de polvo que existen en nuestra galaxia: La vía Láctea. El telescopio VISTA vive en el observatorio Paranal, en Antofagasta, y va por la vida recolectando luz infrarroja, invisible para nosotros pero no para la física. Para esto, tomaremos tres imágenes hechas con diferentes filtros desde la base de datos VVV para componer una imagen de color falsa de parte de la nebulosa NGC 6334, también conocida como pata de gato, por las estructuras esferoides que construyeron los vientos de las estrellas brillantes de sus centros.
YouTubeVideo("ni5LdzvLY7o", start=start, autoplay=0, theme="light", color="red")
Pero esas son cosas que uno puede ver en las bandas visibles! El infrarrojo nos ofrece todo lo que está detrás de la patita del gato. Los filtros escogidos para esta tarea son el filtro J, el H, y el Ks. Entonces leeremos las imágenes, las miraremos individualmente y le asignaremos colores raros a cada una de ellas para reforzar que estos colores son sólo un código útil.
from astropy.io import fits
#Acomodamos las dimensiones porque siempre falta o sobran píxeles:
J1 = fits.getdata("J.fits")
J = J1[1:,1:]
H1 = fits.getdata("H.fits")
H = H1[1:,:]
KS = fits.getdata("Ks.fits")
Ks = KS[:,2:]
#Separamos cada canal 0,1 y 2 de forma individual
f,ejes = plt.subplots(1,3,figsize=(7,7),sharey=True)
#Esta la pintamos en escala de grises.
ejes[0].imshow(J, cmap='gray', vmin=850, vmax=1000)
ejes[0].set_title("Filtro J")
ejes[0].set_ylabel("número de pixeles", size=14)
#Esta la pintamos con el color por defecto.
ejes[1].imshow(H, vmin=2900, vmax=3100)
ejes[1].set_title("Filtro H")
ejes[1].set_xlabel("número de pixeles", size=18)
#Y esta imagen, la pintamos de rojo.
ejes[2].imshow(Ks, cmap="Reds", vmin=4200, vmax=4500)
ejes[2].set_title("Filtro Ks")
plt.tight_layout()
plt.show()
Podemos ver algunas estructuras, como así también algunas nubes de polvo y gas que han sido calentadas por las estrellas cercanas a tal materia. Entonces, creamos la imagen de falso color creando el cubo de datos con las tres imágenes anteriores:
img = np.zeros((J.shape[0], J.shape[1], 3), dtype=float)
img[:,:,0] = sqrt(Ks,scale_min=4200, scale_max=4500)
img[:,:,1] = sqrt(H, scale_min=2900, scale_max=3200)
img[:,:,2] = sqrt(J, scale_min=850, scale_max=1000)
plt.figure(figsize=(6,12))
plt.imshow(img, aspect='equal')
plt.title('NGC 6334',size=20)
plt.xlabel('pixeles',size=16)
plt.ylabel('pixeles',size=16)
plt.tight_layout()
plt.show()
Cada uno de los puntitos que vemos es una estrella distinta, y hay incontable número de ellas en una pequeña región del cielo, impactante. Donde está oscuro se localiza las llamadas Nubes oscuras infrarrojas, donde el polvo esta tan concentrado que ni la luz infrarroja puede pasar. Son negras porque no dejan pasar las estrellas que están de fondo, como en todo su alrededor. Las fuentes rojizas representan estrellas que están en su proceso de formación, con unos tiernos cientos de miles de años de vida, y por último, la emisión morado/azulada son nubes que han sido calentadas por sus estrellas calientes a sus alrededores.
Gracias por leerme!