Taula de continguts:
- Pas 1: configuració del vostre entorn
- Pas 2: consulta de l'API de cerca de la NASA
- Pas 3: la xarxa neuronal convolucional
- Pas 4: processament de la imatge
- Pas 5: unir les imatges en una projecció equirectangular
- Pas 6: l'script complet de Python
- Pas 7: l'aplicació Electron
- Pas 8: execució
Vídeo: Planetari amb xarxa neuronal que utilitza Python, Electron i Keras: 8 passos
2024 Autora: John Day | [email protected]. Última modificació: 2024-01-30 08:12
En aquest instructiu, us mostraré com vaig escriure un generador automàtic de planetari 3D, utilitzant Python i Electron
El vídeo anterior mostra un dels planetaris aleatoris que ha generat el programa.
** Nota: aquest programa no és en cap cas perfecte i, en alguns llocs, no és gaire pitònic. El discriminador de xarxes neuronals només té un ~ 89% de precisió, de manera que algunes imatges estranyes arribaran al planetari **
Especificitats
El planetari consulta una API de la NASA per obtenir imatges relacionades amb l’espai i utilitza una xarxa neuronal convolucional per determinar si la imatge és adequada per al processament. A continuació, el programa utilitza OpenCV per eliminar el fons de la imatge i, finalment, les imatges s’uneixen en una gran imatge equirectangular. Aquesta imatge es desa i una aplicació Electron Node.js obre la imatge i utilitza el paquet PhotoSphere.js per veure la imatge en un format 3D d’estil planetari.
Dependències
Python:
- Keras
- Coixí
- cv2
- Gronxador
- Sol·licituds
- urllib
- Aleatori
- temps
- io
Electró:
PhotoSphere
Pas 1: configuració del vostre entorn
Instal·lació d’Electron i Python
Primer, assegureu-vos que teniu instal·lats node.js i npm (si no, podeu descarregar-lo aquí)
A continuació, heu d’instal·lar Electron. Obriu un indicador d’ordres i introduïu l’ordre següent:
npm instal·lar electron -g
A continuació, necessiteu python, que es pot descarregar aquí
Configuració d’un entorn virtual
Obriu un indicador d’ordres i, a continuació, introduïu les ordres següents per configurar l’entorn virtual:
pip instal·lar virtualenv
espai virtualenv
espai cd
scripts / activate
Instal·lació de dependències de Python
Executeu aquestes ordres a l'indicador d'ordres per instal·lar les vostres dependències de python:
pip instal·lar keras
pip instal·lar coixí
pip instal·lar numpy
peticions d'instal·lació de pip
instal·lar pip opencv-pythonSi voleu entrenar la xarxa vosaltres mateixos, assegureu-vos de configurar l’acceleració de la GPU per a Keras
Pas 2: consulta de l'API de cerca de la NASA
Visió general
La NASA té moltes API realment útils que podeu utilitzar amb els vostres projectes. Per a aquest projecte, utilitzarem l'API de cerca, que ens permet buscar imatges relacionades amb l'espai a la base de dades d'imatges de la NASA.
El codi
En primer lloc, hem de definir una funció python per acceptar un argument que actuï com a terme de cerca:
def get_image_search (frase):
passar
A continuació, convertirem el terme de cerca al format d'URL i, a continuació, utilitzarem la biblioteca de sol·licituds per consultar l'API:
def get_image_search (frase):
params = {"q": urllib.parse.quote (arg), "media_type": "imatge"} resultats = requests.get ("https://images-api.nasa.gov/search", params = params)
Finalment, descodificarem la col·lecció + cadena JSON que ens ha retornat l'API i extreurem una llista d'enllaços a imatges relacionades amb el terme de cerca:
def get_image_search (frase):
params = {"q": urllib.parse.quote (arg), "media_type": "imatge"} resultats = requests.get ("https://images-api.nasa.gov/search", params = params) dades = [resultat ['href'] per al resultat result.json () ["col·lecció"] ["elements"]
Allà anem! Ara tenim un fragment de codi que pot consultar l'API de cerca d'imatges de la NASA i retornar una llista d'enllaços a imatges relacionades amb el nostre terme de cerca.
Pas 3: la xarxa neuronal convolucional
Visió general
La feina de la xarxa neuronal és classificar si una imatge és d’alguna cosa a l’espai o si no. Per fer-ho, utilitzarem una xarxa neuronal convolucional, o CNN, per realitzar una sèrie d'operacions matricials a la imatge i determinar com és l'espai-y. No ho explicaré tot, perquè hi ha molta teoria al darrere, però si voleu conèixer les xarxes neuronals, us suggereixo "Domini d'aprenentatge automàtic".
El codi
En primer lloc, hem d’importar les nostres dependències:
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 s'ha trobat cap GPU") d'importació keras.preprocessing.image ImageDataGenerator d'importació d'imatges keras.preprocessing d'importació keras.models Seqüencial d'importació keras.layers Conv2D, MaxPooling2D d'importació keras.layers Activació, abandonament, aplanament, densitat del backend d'importació keras com a K d'importació PIL importar numpy com a np
A continuació, hem de definir el nostre model:
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 èpoques = 10 batch_size = 8 if K.image_data_format () == 'channels_first': input_shape =: input_shape =: input_shape = = (img_width, img_height, 3) model = Sequential () model.add (Conv2D (32, (2, 2), input_shape = input_shape)) model.add (Activation ('relu'))) model.add (MaxPooling2D (pool_size) = (2, 2))) model.add (Conv2D (32, (2, 2)))) model.add (Activació ('relu')) model.add (MaxPooling2D (pool_size = (2, 2)))) model.add (Conv2D (64, (2, 2)))) model.add (Activation ('relu')) model.add (MaxPooling2D (pool_size = (2, 2)))) model.add (Flatten ()) model. add (Dense (64)) model.add (Activation ('relu')) model.add (Dropout (0.5)) model.add (Dense (1)) model.add (Activation ('sigmoid')) model.compile (pèrdua = 'binary_crossentropy', optimitzador = 'rmsprop', mètriques = ['precisió'])
He format el model per a vosaltres, però si voleu formar-lo vosaltres mateixos amb el vostre propi conjunt de dades, he adjuntat el codi de formació. En cas contrari, podeu descarregar el fitxer HDF5 del model format. A causa de les restriccions dels fitxers Instructables, he hagut de canviar-lo amb una extensió ".txt". Per utilitzar-lo, canvieu el nom del fitxer per una extensió ".h5" i carregueu-lo amb aquest codi:
model.load_weights ("model_saved.h5")
Per utilitzar la xarxa per predir com és l'espai d'una imatge, definirem aquesta funció:
predir def (ruta_imatge):
img = image.load_img (image_path, target_size = (1000, 500)) img = np.expand_dims (img, axis = 0) result = model.predict_classes (img) resultat de retorn [0] [0]
Pas 4: processament de la imatge
Visió general
Per al processament d’imatges, estic fent servir la biblioteca OpenCV (cv2). Primer, desdibuixarem les vores de la imatge i, a continuació, eliminarem el fons creant una màscara i canviant els valors alfa dels colors més foscos.
El codi
Aquesta és la part de la funció que difumina les vores:
def processImage (img):
RADIUS = 20 # Obre una imatge im = Image.open ("pilbuffer.png") # Enganxa imatge sobre fons blanc diam = 2 * RADIUS back = Image.new ('RGB', (im.size [0] + diam, im.size [1] + diam), (0, 0, 0)) back.paste (im, (RADIUS, RADIUS)) # Crea màscara de desenfocament = Image.new ('L', (im.size [0] + diam, mida im [1] + diam), 255) blck = Image.new ('L', (mida im [0] - diam, mida im [1] - diam), 0) màscara. enganxar (blck, (diam, diam)) # # Desenfocar la imatge i enganxar la vora borrosa segons la màscara desenfocar = tornar.filtre (ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (desenfocar, màscara = màscara) back.save (" transition-p.webp
A continuació, establirem els colors més foscos a transparents i desarem la imatge temporalment:
#Crear màscara i filtre substituir el negre per alfa
image = cv2.imread ("transition.png") hMin = 0 sMin = 0 vMin = 20 hMax = 180 sMax = 255 vMax = 255 inferior = np.array ([hMin, sMin, vMin]) upper = np.array ([hMax, sMax, vMax]) hsv = cv2.cvtColor (imatge, cv2. COLOR_BGR2HSV) màscara = cv2.inRang (hsv, inferior, superior) sortida = cv2.bitwise_and (imatge, imatge, màscara = màscara) * _, alfa = cv2.split (sortida) dst = cv2.merge ((sortida, alfa)) sortida = dst amb obert ("buffer.png", "w +") com a fitxer: passa cv2.imwrite ("buffer.png", sortida)
Pas 5: unir les imatges en una projecció equirectangular
Visió general
Aquesta funció pren diverses imatges i les ajusta en un format que pot ser interpretat pel paquet PhotoSphere.js, mitjançant la biblioteca PIL (coixí)
El codi
En primer lloc, hem de crear una imatge que pugui actuar com a amfitrió de les altres imatges:
new = Image.new ("RGBA", (8000, 4000), color = (0, 0, 0))
A continuació, hem de recórrer la matriu d'imatges (que s'han redimensionat totes a 1000x500) i col·locar-les a la imatge:
h = 0
w = 0 i = 0 per a img a img_arr: new.paste (img, (w, h), img) w + = 1000 si w == 8000: h + = 500 w = 0 i + = 1
Ara acabem d’acabar-ho amb una funció que pren com a argument una sèrie d’imatges i retorna la nova imatge:
def stitch_beta (img_arr):
new = Image.new ("RGBA", (8000, 4000), color = (0, 0, 0)) h = 0 w = 0 i = 0 per a img a img_arr: new.paste (img, (w, h), img) w + = 1000 si w == 8000: h + = 500 w = 0 i + = 1 torna nou
Pas 6: l'script complet de Python
Aquest és l'script complet de xarxa neuronal de Python, que es desa com a net.py i s'importa a l'script principal:
# importació de biblioteques
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 s'ha trobat cap GPU ") d'importació keras.preprocessing.image ImageDataGenerator d'importació d'imatges keras.preprocessing d'importació keras.models Seqüencial d'importació keras.layers Conv2D, MaxPooling2D d'importació keras.layers Activació, abandonament, aplanament, densitat de backend d'importació de keras com K de PIL importa la importació d'imatges numpy com 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_d =: input_shape = (3, img_width, img_height) else: input_shape = (img_width, img_height, 3) model = Sequential () model.add (Conv2D (32, (2, 2), input_shape = input_shape)) model.add (Activació ('relu')) model.add (model MaxPooling2D (pool_size = (2, 2)))) model.add (Conv2D (32, (2, 2)))). add (Activation ('relu')) model.add (MaxPooling2D (pool_size = (2, 2))) model.add (Conv2D (64, (2, 2))) model.add (Activation ('relu')) model.add (MaxPooling2D (pool_size = (2, 2)))) model.add (Flatten ()) model.add (Dense (64)) model.add (Activació ('relu')) model.add (Dropout (0.5))) model.add (Dense (1)) model.add (Activació ('sigmoid')) 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) resultat de retorn [0] [0]
Aquest és el fitxer principal de python, api.py:
sol·licituds d’importació, sys, random, urllib.parse, cv2
des de la importació PIL Image, ImageFilter from io import BytesIO import numpy as np import net def get_image_search (num, phrase): count = 0 img_arr = for arg in phrase: print (arg) print (f "Recompte d'imatges actuals: {count } ") i = 0 params = {" q ": urllib.parse.quote (arg)," media_type ":" image "} results = requests.get (" https://images-api.nasa.gov/search ", params = params) data = [result ['href'] for result in results.json () [" collection "] [" items "] print (len (data)) if num> len (data): num = len (dades) mentre es compta
Pas 7: l'aplicació Electron
Visió general
Crearem una aplicació electrònica senzilla que només posiciona i carrega l’element PhotoSphere. Els fitxers main.js i package.json provenen directament del lloc web Electron i l'HTML és una versió lleugerament modificada de l'HTML proporcionat al lloc web de PhotoSphere. He inclòs els fitxers, però he canviat el nom de tots a.txt, ja que Instructables no permet aquests tipus de fitxers. Per utilitzar els fitxers, canvieu-los amb l'extensió adequada.
El codi
main.js
const {app, BrowserWindow} = require ('electron')
funció createWindow () {const win = new BrowserWindow ({width: 800, height: 600, webPreferences: {nodeIntegration: true}}) win.loadFile ('index.html')} app.whenReady (). then (createWindow) app.on ('window-all-closed', () => {if (process.platform! == 'darwin') {app.quit ()}}) app.on ('activate', () => {if (BrowserWindow.getAllWindows (). length === 0) {createWindow ()}})
package.json
{
"name": "space", "version": "0.1.0", "main": "main.js", "scripts": {"start": "electron". }}
index.html
Pas 8: execució
Creació de la imatge equirectangular
Per crear la imatge, executeu l'script api.py a l'indicador d'ordres, amb el seu entorn virtual activat:
api.py
Un cop finalitzats els scripts, executeu l'aplicació electron mitjançant:
npm d'iniciVoila! El vostre planetari està actiu. Gràcies per llegir:)
Recomanat:
Observador d’humitat i temperatura que utilitza Raspberry Pi amb SHT25 a Python: 6 passos
Observador d’humitat i temperatura que utilitza Raspberry Pi amb SHT25 a Python: sent un entusiasta de Raspberry Pi, hem pensat en alguns experiments més espectaculars amb aquesta campanya, farem un observador d’humitat i temperatura que mesuri la humitat i la temperatura relativa amb Raspberry Pi i SHT25, Humidi
Comandament a distància sense fils que utilitza el mòdul NRF24L01 de 2,4 Ghz amb Arduino - Nrf24l01 Receptor transmissor de 4 canals / 6 canals per quadcòpter - Helicòpter Rc - Avió Rc amb Arduino: 5 passos (amb imatges)
Comandament sense fils que utilitza un mòdul NRF24L01 de 2,4 Ghz amb Arduino | Nrf24l01 Receptor transmissor de 4 canals / 6 canals per quadcòpter | Helicòpter Rc | Avió Rc amb Arduino: per fer funcionar un cotxe Rc | Quadcopter | Drone | Avió RC | Vaixell RC, sempre necessitem un receptor i un transmissor, suposem que per RC QUADCOPTER necessitem un transmissor i un receptor de 6 canals i aquest tipus de TX i RX és massa costós, així que en farem un al nostre
Inversor lligat a la xarxa (no alimenta la xarxa) Alternativa UPS: 7 passos (amb imatges)
Inversor lligat a la quadrícula de bricolatge (no alimenta la xarxa) Alternativa de SAI: aquest és un missatge de seguiment de la meva altra instrucció sobre com fer un inversor de connexió a la xarxa que no es retroalimenta, ja que ara sempre és possible fer-ho en certes àrees com a projecte de bricolatge i en alguns llocs no es permet alimentar-s’hi
És això una mà? (Càmera Raspberry Pi + xarxa neuronal) Part 1/2: 16 passos (amb imatges)
És això una mà? (Càmera Raspberry Pi + Xarxa Neural) Part 1/2: Fa uns dies, em vaig ferir el canell a la mà dreta al gimnàs. Després, cada vegada que feia servir el ratolí de l’ordinador, causava molt dolor a causa de l’angle fort del canell. Va ser llavors quan em va tocar "no seria fantàstic que poguéssim convertir qualsevol superfície en un trackp
Robot de xarxa neuronal Arduino: 21 passos (amb imatges)
Robot de xarxa neuronal Arduino: aquest instructiu es basa en una sèrie de 3 parts que he fet per al canal Make YouTube que us mostra exactament com prototipar, dissenyar, muntar i programar el vostre propi robot de xarxa neuronal Arduino. Després de veure la sèrie completa, hauríeu de tenir un bet