Tabla de contenido:
2025 Autor: John Day | [email protected]. Última modificación: 2025-01-23 14:39
En este instructivo, les mostraré cómo escribí un generador de planetario 3D automático, usando Python y Electron
El video de arriba muestra uno de los planetarios aleatorios que generó el programa.
** Nota: este programa no es perfecto de ninguna manera y, en algunos lugares, no es muy pitónico. El discriminador de red neuronal tiene una precisión de solo ~ 89%, por lo que algunas imágenes extrañas llegarán al planetario **
Detalles específicos
El planetario consulta una API de la NASA en busca de imágenes relacionadas con el espacio y utiliza una red neuronal convolucional para determinar si la imagen es adecuada para su procesamiento. Luego, el programa usa OpenCV para eliminar el fondo de la imagen y, finalmente, las imágenes se unen en una imagen equirrectangular grande. Luego, esta imagen se guarda y una aplicación Electron Node.js abre la imagen y usa el paquete PhotoSphere.js para ver la imagen en un formato 3D estilo planetario.
Dependencias
Pitón:
- Keras
- Almohada
- cv2
- Numpy
- Peticiones
- urllib
- Aleatorio
- tiempo
- io
Electrón:
Fotosfera
Paso 1: Configuración de su entorno
Instalación de Electron y Python
Primero, asegúrese de tener node.js y npm instalados (si no, puede descargar aquí)
A continuación, debe instalar Electron. Abra un símbolo del sistema e ingrese el siguiente comando:
npm instalar electron -g
A continuación, necesita Python, que se puede descargar aquí.
Configurar un entorno virtual
Abra un símbolo del sistema, luego ingrese los siguientes comandos para configurar su entorno virtual:
pip instalar virtualenv
espacio virtualenv
espacio de cd
scripts / activar
Instalación de dependencias de Python
Ejecute estos comandos en el símbolo del sistema para instalar sus dependencias de Python:
pip instalar keras
pip instalar almohada
pip instalar numpy
solicitudes de instalación de pip
pip instalar opencv-pythonSi desea entrenar la red usted mismo, asegúrese de configurar la aceleración de GPU para Keras
Paso 2: consultar la API de búsqueda de la NASA
Visión general
La NASA tiene muchas API realmente útiles que puede usar con sus proyectos. Para este proyecto, utilizaremos la API de búsqueda, que nos permite buscar en la base de datos de imágenes de la NASA imágenes relacionadas con el espacio.
El código
Primero, necesitamos definir una función de Python para aceptar un argumento que actuará como término de búsqueda:
def get_image_search (frase):
aprobar
A continuación, convertiremos el término de búsqueda a formato de URL, luego usaremos la biblioteca de solicitudes para consultar la API:
def get_image_search (frase):
params = {"q": urllib.parse.quote (arg), "media_type": "imagen"} resultados = solicitudes.get ("https://images-api.nasa.gov/search", params = params)
Finalmente, decodificaremos la colección + cadena JSON que nos devolvió la API, y extraeremos una lista de enlaces a imágenes relacionadas con el término de búsqueda:
def get_image_search (frase):
params = {"q": urllib.parse.quote (arg), "media_type": "imagen"} resultados = solicitudes.get ("https://images-api.nasa.gov/search", params = params) data = [result ['href'] para el resultado en results.json () ["colección"] ["elementos"]
¡Aquí vamos! Ahora tenemos un fragmento de código que puede consultar la API de búsqueda de imágenes de la NASA y devolver una lista de enlaces a imágenes relacionadas con nuestro término de búsqueda.
Paso 3: la red neuronal convolucional
Visión general
El trabajo de la red neuronal es clasificar si una imagen es de algo en el espacio o no. Para hacer esto, usaremos una red neuronal convolucional, o CNN, para realizar una serie de operaciones matriciales en la imagen y determinar qué tan espacial es. No explicaré todo esto, porque hay mucha teoría detrás de esto, pero si quieres aprender sobre las redes neuronales, te sugiero "Dominio del aprendizaje automático".
El código
Primero, necesitamos importar nuestras dependencias:
importar sistema operativo
#Corregir el problema durante el tren stepn oN GPU os.environ ['CUDA_VISIBLE_DEVICES'] = '' import tensorflow as tf if tf.test.gpu_device_name (): print ('GPU found') else: print ("No GPU found") de keras.preprocessing.image importar ImageDataGenerator de keras.preprocessing importar imagen de keras.models importar secuencial de keras.layers importar Conv2D, MaxPooling2D de keras.layers importar Activación, Abandono, Aplanar, Denso de keras importar backend como K de PIL importar imagen importar numpy como np
A continuación, necesitamos definir nuestro modelo:
img_width, img_height = 1000, 500
train_data_dir = 'v_data / train' validation_data_dir = 'v_data / test' nb_train_samples = 203 nb_validation_samples = 203 epochs = 10 batch_size = 8 if K.image_data_format () == 'channels_first': input_shepe = (3, img_sight_hape) = (img_width, img_height, 3) model = Sequential () model.add (Conv2D (32, (2, 2), input_shape = input_shape)) model.add (Activación ('relu')) model.add (MaxPooling2D (pool_size = (2, 2))) model.add (Conv2D (32, (2, 2))) model.add (Activación ('relu')) model.add (MaxPooling2D (pool_size = (2, 2))) model.add (Conv2D (64, (2, 2))) model.add (Activación ('relu')) model.add (MaxPooling2D (pool_size = (2, 2))) model.add (Flatten ()) model. add (Dense (64)) model.add (Activación ('relu')) model.add (Dropout (0.5)) model.add (Dense (1)) model.add (Activación ('sigmoide')) model.compile (pérdida = 'binary_crossentropy', optimizer = 'rmsprop', metrics = ['precisión'])
He entrenado el modelo para usted, pero si desea entrenar el modelo usted mismo, en su propio conjunto de datos, adjunto el código de entrenamiento. De lo contrario, puede descargar el archivo HDF5 del modelo entrenado. Debido a las restricciones del archivo Instructables, tuve que renombrarlo con una extensión ".txt". Para usarlo, cambie el nombre del archivo a una extensión ".h5" y cárguelo con este código:
model.load_weights ("model_saved.h5")
Para usar la red para predecir qué tan espacial es una imagen, definiremos esta función:
def predecir (ruta_imagen):
img = image.load_img (image_path, target_size = (1000, 500)) img = np.expand_dims (img, axis = 0) result = model.predict_classes (img) return result [0] [0]
Paso 4: procesamiento de la imagen
Visión general
Para el procesamiento de imágenes, estoy usando la biblioteca OpenCV (cv2). Primero, desenfocaremos los bordes de la imagen y luego eliminaremos el fondo creando una máscara y cambiando los valores alfa de los colores más oscuros.
El código
Esta es la parte de la función que difumina los bordes:
def processImage (img):
RADIUS = 20 # Abrir una imagen im = Image.open ("pilbuffer.png") # Pegar imagen sobre fondo blanco diam = 2 * RADIUS back = Image.new ('RGB', (im.size [0] + diam, im.size [1] + diam), (0, 0, 0)) back.paste (im, (RADIUS, RADIUS)) # Crear máscara de máscara de desenfoque = Image.new ('L', (im.size [0] + diam, im.size [1] + diam), 255) blck = Image.new ('L', (im.size [0] - diam, im.size [1] - diam), 0) mask. paste (blck, (diam, diam)) # Desenfocar la imagen y pegar el borde difuminado de acuerdo con la máscara blur = back.filter (ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (blur, mask = mask) back.save (" transición-p.webp
A continuación, configuraremos los colores más oscuros en transparentes y guardaremos la imagen temporalmente:
#Crear máscara y filtro reemplazar negro con alfa
image = cv2.imread ("transición.png") hMin = 0 sMin = 0 vMin = 20 hMax = 180 sMax = 255 vMax = 255 inferior = np.array ([hMin, sMin, vMin]) superior = np.array ([hMax, sMax, vMax]) hsv = cv2.cvtColor (imagen, cv2. COLOR_BGR2HSV) máscara = cv2.inRange (hsv, inferior, superior) salida = cv2.bitwise_and (imagen, imagen, máscara = máscara) * _, alfa = cv2.split (salida) dst = cv2.merge ((salida, alfa)) salida = dst con open ("buffer.png", "w +") como archivo: pass cv2.imwrite ("buffer.png", salida)
Paso 5: Unir imágenes en una proyección equirectangular
Visión general
Esta función toma varias imágenes y las une en un formato que puede ser interpretado por el paquete PhotoSphere.js, utilizando la biblioteca PIL (almohada).
El código
Primero, necesitamos crear una imagen que pueda actuar como anfitrión para las otras imágenes:
nuevo = Imagen.nuevo ("RGBA", (8000, 4000), color = (0, 0, 0))
A continuación, debemos recorrer la matriz de imágenes (que se han redimensionado a 1000x500) y colocarlas en la imagen:
h = 0
w = 0 i = 0 para img en img_arr: new.paste (img, (w, h), img) w + = 1000 si w == 8000: h + = 500 w = 0 i + = 1
Ahora acabamos de resumir esto en una función que toma una matriz de imágenes como argumento y devuelve la nueva imagen:
def puntada_beta (img_arr):
nuevo = Imagen.nuevo ("RGBA", (8000, 4000), color = (0, 0, 0)) h = 0 w = 0 i = 0 para img en img_arr: new.paste (img, (w, h), img) w + = 1000 si w == 8000: h + = 500 w = 0 i + = 1 devuelve nuevo
Paso 6: el script de Python completo
Este es el script completo de la red neuronal de Python, que se guarda como net.py y se importa al script principal:
# importar bibliotecas
import os #Fix for issue during train stepn on GPU os.environ ['CUDA_VISIBLE_DEVICES'] = '' import tensorflow as tf if tf.test.gpu_device_name (): print ('GPU found') else: print ("No GPU found ") de ImageDataGenerator importación keras.preprocessing.image de la imagen de importación keras.preprocessing de keras.models importar secuencial desde el keras.layers importar Conv2D, MaxPooling2D de keras.layers importar activación, Dropout, Aplanar, denso de backend importación Keras como K de PIL import Image import numpy as np img_width, img_height = 1000, 500 train_data_dir = 'v_data / train' validation_data_dir = 'v_data / test' nb_train_samples = 203 nb_validation_samples = 203 epochs = 10 batch_size = 8 if 'K.image_data_format_formato: input_shape = (3, img_width, img_height) más: input_shape = (img_width, img_height, 3) modelo = Sequential () model.add (Conv2D (32, (2, 2), input_shape = input_shape)) model.add (activación ('relu')) model.add (MaxPooling2D (pool_size = (2, 2))) model.add (Conv2D (32, (2, 2))) modelo. add (Activación ('relu')) model.add (MaxPooling2D (pool_size = (2, 2))) model.add (Conv2D (64, (2, 2))) model.add (Activación ('relu')) model.add (MaxPooling2D (pool_size = (2, 2))) model.add (Flatten ()) model.add (Dense (64)) model.add (Activación ('relu')) model.add (Dropout (0.5))) model.add (Dense (1)) model.add (Activación ('sigmoide')) model.compile (loss = 'binary_crossentropy', optimizer = 'rmsprop', metrics = ['precision']) model.load_weights ("model_saved.h5") def predict (image_path): img = image.load_img (image_path, target_size = (1000, 500)) img = np.expand_dims (img, axis = 0) result = model.predict_classes (img) return result [0] [0]
Este es el archivo principal de Python, api.py:
solicitudes de importación, sys, random, urllib.parse, cv2
de PIL import Image, ImageFilter de io import BytesIO import numpy as np import net def get_image_search (núm, frase): count = 0 img_arr = para arg en la frase: print (arg) print (f "Recuento de imágenes actual: {count } ") i = 0 params = {" q ": urllib.parse.quote (arg)," media_type ":" image "} results = orders.get (" https://images-api.nasa.gov/search ", params = params) data = [result ['href'] for result in results.json () [" colección "] [" elementos "] print (len (datos)) if num> len (data): num = len (datos) mientras cuenta
Paso 7: la aplicación Electron
Visión general
Crearemos una aplicación de electrones simple que simplemente posiciona y carga el elemento PhotoSphere. Los archivos main.js y package.json provienen directamente del sitio web de Electron, y el HTML es una versión ligeramente modificada del HTML proporcionado en el sitio web de PhotoSphere. Incluí los archivos, pero renombré todos a.txt, ya que Instructables no permite estos tipos de archivos. Para usar los archivos, cámbieles el nombre con la extensión adecuada.
El código
main.js
const {app, BrowserWindow} = require ('electron')
function createWindow () {const win = new BrowserWindow ({width: 800, height: 600, webPreferences: {nodeIntegration: true}}) win.loadFile ('index.html')} app.whenReady (). luego (createWindow) app.on ('ventana-cerrada', () => {if (process.platform! == 'darwin') {app.quit ()}}) app.on ('activar', () => {if (BrowserWindow.getAllWindows (). length === 0) {createWindow ()}})
package.json
{
"nombre": "espacio", "versión": "0.1.0", "main": "main.js", "scripts": {"start": "electron". }}
index.html
Paso 8: ejecución
Creando la imagen equirrectangular
Para crear la imagen, ejecute el script api.py en el símbolo del sistema, con su entorno virtual activado:
api.py
Una vez que los scripts hayan terminado de ejecutarse, ejecute la aplicación electron usando:
inicio npm¡Voila! ¡Tu planetario está activo! Gracias por leer:)
Recomendado:
Impresionante sintetizador / órgano analógico que utiliza solo componentes discretos: 10 pasos (con imágenes)
Increíble sintetizador / órgano analógico que utiliza solo componentes discretos: los sintetizadores analógicos son geniales, pero también bastante difíciles de hacer, así que quería hacer uno lo más simple posible, para que su funcionamiento sea fácilmente comprensible. Necesito algunos subcircuitos básicos: Un oscilador simple con resis
Máquina de pinball de sobremesa que utiliza Evive: plataforma integrada basada en Arduino: 18 pasos (con imágenes)
Máquina de pinball de sobremesa que usa Evive: plataforma integrada basada en Arduino: ¡Otro fin de semana, otro juego emocionante! Y esta vez, no es otro que el juego de arcade favorito de todos: ¡Pinball! Este proyecto le mostrará cómo hacer su propia máquina de Pinball fácilmente en casa. Todo lo que necesita son componentes de evive
Coche Bluetooth RC Arduino con tracción en las 4 ruedas que utiliza UNO R3, HC-05 y L293D Motorshield con codificación y aplicación de Android: 8 pasos
Arduino 4 Wheel Drive Bluetooth RC Car usando UNO R3, HC-05 y L293D Motorshield con codificación y aplicación de Android: Hoy les voy a contar cómo hacer un automóvil arduino 4x4 bluetooth RC con HC 05, L293 motor shield, Motor 4 DC, con codificación y aplicación para android para controlar el coche. Componente utilizado: -1-Arduino UNO R32-Bluetooth HC-053-Motorshield L293
¿Eso es una mano? (Cámara Raspberry Pi + Red neuronal) Parte 1/2: 16 pasos (con imágenes)
¿Eso es una mano? (Cámara Raspberry Pi + Red neuronal) Parte 1/2: Hace unos días, me lesioné la muñeca derecha en el gimnasio. Después, cada vez que usaba el mouse de mi computadora, me causaba mucho dolor debido al ángulo pronunciado de la muñeca. Fue entonces cuando me di cuenta: "¿no sería genial si pudiéramos convertir cualquier superficie en un trackp?"
Robot de red neuronal Arduino: 21 pasos (con imágenes)
Robot de red neuronal Arduino: este instructivo se basa en una serie de 3 partes que hice para el canal Make YouTube, que le muestra exactamente cómo prototipar, diseñar, ensamblar y programar su propio robot de red neuronal Arduino. Después de ver la serie completa, deberías tener una mejor