Sommario:
- Passaggio 1: configurazione dell'ambiente
- Passaggio 2: interrogazione dell'API di ricerca della NASA
- Passaggio 3: la rete neurale convoluzionale
- Passaggio 4: elaborazione dell'immagine
- Passaggio 5: unire le immagini in una proiezione equirettangolare
- Passaggio 6: lo script completo di Python
- Passaggio 7: l'app Electron
- Passaggio 8: esecuzione
Video: Planetario alimentato da rete neurale che utilizza Python, Electron e Keras: 8 passaggi
2024 Autore: John Day | [email protected]. Ultima modifica: 2024-01-30 10:01
In questo tutorial, ti mostrerò come ho scritto un generatore automatico di planetari 3D, usando Python ed Electron
Il video sopra mostra uno dei planetari casuali generati dal programma.
**Nota: questo programma non è in alcun modo perfetto e in alcuni punti non è molto pitonico. Il discriminatore della rete neurale è preciso solo all'89% circa, quindi alcune immagini strane arriveranno nel planetario**
Specifiche
Il planetario interroga un'API della NASA per immagini relative allo spazio e utilizza una rete neurale convoluzionale per determinare se l'immagine è adatta per l'elaborazione. Il programma utilizza quindi OpenCV per rimuovere lo sfondo dall'immagine e infine le immagini vengono unite in un'unica grande immagine equirettangolare. Questa immagine viene quindi salvata e un'applicazione Electron Node.js apre l'immagine e utilizza il pacchetto PhotoSphere.js per visualizzare l'immagine in un formato 3D in stile planetario.
dipendenze
Pitone:
- Keras
- Cuscino
- cv2
- Numpy
- Richieste
- urllib
- A caso
- tempo
- io
Elettrone:
Fotosfera
Passaggio 1: configurazione dell'ambiente
Installazione di Electron e Python
Innanzitutto, assicurati di aver installato node.js e npm (in caso contrario, puoi scaricarlo qui)
Successivamente, è necessario installare Electron. Apri un prompt dei comandi e inserisci il seguente comando:
npm installa elettrone -g
Successivamente, hai bisogno di Python, che può essere scaricato qui
Configurazione di un ambiente virtuale
Apri un prompt dei comandi, quindi inserisci i seguenti comandi per configurare il tuo ambiente virtuale:
pip install virtualenv
spazio virtualenv
spazio cd
script\activate
Installazione delle dipendenze Python
Esegui questi comandi nel prompt dei comandi per installare le tue dipendenze Python:
pip install keras
pip installa il cuscino
pip install numpy
pip richieste di installazione
pip install opencv-pythonSe vuoi addestrare tu stesso la rete, assicurati di impostare l'accelerazione GPU per Keras
Passaggio 2: interrogazione dell'API di ricerca della NASA
Panoramica
La NASA ha molte API davvero utili che puoi usare con i tuoi progetti. Per questo progetto, utilizzeremo l'API di ricerca, che ci consente di cercare nel database di immagini della NASA immagini relative allo spazio.
Il codice
Innanzitutto, dobbiamo definire una funzione Python per accettare un argomento che fungerà da termine di ricerca:
def get_image_search(frase):
passaggio
Successivamente, convertiremo il termine di ricerca in formato URL, quindi utilizzeremo la libreria delle richieste per interrogare l'API:
def get_image_search(frase):
params = {"q": urllib.parse.quote(arg), "media_type": "image"} results = request.get("https://images-api.nasa.gov/search", params=params)
Infine, decodificheremo la stringa collection+JSON che l'API ci ha restituito ed estrarremo un elenco di collegamenti alle immagini relative al termine di ricerca:
def get_image_search(frase):
params = {"q": urllib.parse.quote(arg), "media_type": "image"} results = request.get("https://images-api.nasa.gov/search", params=params) data = [result['href'] per il risultato in results.json()["collection"]["items"]
Ci siamo! Ora abbiamo uno snippet di codice che può interrogare l'API di ricerca di immagini della NASA e restituire un elenco di collegamenti alle immagini relative al nostro termine di ricerca.
Passaggio 3: la rete neurale convoluzionale
Panoramica
Il compito della rete neurale è classificare se un'immagine è di qualcosa nello spazio o se non lo è. Per fare ciò, utilizzeremo una rete neurale convoluzionale, o CNN, per eseguire una serie di operazioni matriciali sull'immagine e determinare quanto è spazio-y. Non spiegherò tutto questo, perché c'è molta teoria dietro, ma se vuoi conoscere le reti neurali, ti suggerisco "Machine Learning Mastery"
Il codice
Per prima cosa, dobbiamo importare le nostre dipendenze:
importare il sistema operativo
#Risolto il problema durante il passaggio del treno sulla GPU os.environ['CUDA_VISIBLE_DEVICES'] = '' import tensorflow as tf if tf.test.gpu_device_name(): print('GPU trovata') else: print("Nessuna GPU trovata") da keras.preprocessing.image import ImageDataGenerator da keras.preprocessing importa immagine da keras.models import Sequential da keras.layers import Conv2D, MaxPooling2D da keras.layers import Activation, Dropout, Flatten, Dense from keras import backend as K from PIL import Image importa numpy come np
Successivamente dobbiamo definire il nostro modello:
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 epoche = 10 batch_size = 8 if K.image_data_format() == 'channels_first': input_shape_= (3, img_height) = (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(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(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(1)) model.add(Activation('sigmoid')) model.compile (perdita='binary_crossentropy', ottimizzatore='rmsprop', metriche=['accuratezza'])
Ho addestrato il modello per te, ma se desideri addestrare il modello da solo, sul tuo set di dati, ho allegato il codice di addestramento. Altrimenti, puoi scaricare il file HDF5 del modello addestrato. A causa delle restrizioni sui file di Instructables, ho dovuto rinominarlo con un'estensione ".txt". Per usarlo, rinomina il file con un'estensione ".h5" e caricalo con questo codice:
model.load_weights("model_saved.h5")
Per utilizzare la rete per prevedere quanto è spazio-y un'immagine, definiremo questa funzione:
def predire (percorso_immagine):
img = image.load_img(image_path, target_size=(1000, 500)) img = np.expand_dims(img, axis=0) risultato=model.predict_classes(img) return risultato[0][0]
Passaggio 4: elaborazione dell'immagine
Panoramica
Per l'elaborazione delle immagini, sto usando la libreria OpenCV (cv2). Innanzitutto, sfocamo i bordi dell'immagine, quindi rimuoveremo lo sfondo creando una maschera e modificando i valori alfa dei colori più scuri
Il codice
Questa è la parte della funzione che sfoca i bordi:
def processImage(img):
RAGGIO = 20 # Apri un'immagine im = Image.open("pilbuffer.png") # Incolla l'immagine su sfondo bianco diam = 2 * RAGGIO back = Image.new('RGB', (im.size[0] + diam, im.size[1] + diam), (0, 0, 0)) back.paste(im, (RADIUS, RADIUS)) # Crea maschera di sfocatura mask = 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)) # Sfoca l'immagine e incolla il bordo sfocato in base alla maschera blur = back.filter(ImageFilter. GaussianBlur(RADIUS / 2)) back.paste(blur, mask=mask) back.save(" transizione.png") back.close()
Successivamente, imposteremo i colori più scuri su trasparenti e salveremo temporaneamente l'immagine:
#Crea maschera e filtro sostituisci il nero con l'alfa
image = cv2.imread("transition.png") hMin = 0 sMin = 0 vMin = 20 hMax = 180 sMax = 255 vMax = 255 lower = np.array([hMin, sMin, vMin]) upper = np.array([hMax, sMax, vMax]) hsv = cv2.cvtColor(image, cv2. COLOR_BGR2HSV) mask = cv2.inRange(hsv, lower, upper) output = cv2.bitwise_and(image, image, mask=mask) *_, alpha = cv2.split(output) dst = cv2.merge((output, alpha)) output = dst con open("buffer.png", "w+") come file: passa cv2.imwrite("buffer.png", output)
Passaggio 5: unire le immagini in una proiezione equirettangolare
Panoramica
Questa funzione prende più immagini e le unisce in un formato che può essere interpretato dal pacchetto PhotoSphere.js, utilizzando la libreria PIL (cuscino)
Il codice
Innanzitutto, dobbiamo creare un'immagine che possa fungere da host per le altre immagini:
new = Image.new("RGBA", (8000, 4000), color=(0, 0, 0))
Successivamente, dobbiamo scorrere l'array di immagini (che sono state tutte ridimensionate a 1000x500) e inserirle nell'immagine:
h = 0
w = 0 i = 0 per img in img_arr: new.paste(img, (w, h), img) w += 1000 se w == 8000: h += 500 w = 0 i += 1
Ora lo avvolgiamo in una funzione che accetta un array di immagini come argomento e restituisce la nuova immagine:
def stitch_beta(img_arr):
new = Image.new("RGBA", (8000, 4000), color=(0, 0, 0)) h = 0 w = 0 i = 0 per img in img_arr: new.paste(img, (w, h), img) w += 1000 if w == 8000: h += 500 w = 0 i += 1 return new
Passaggio 6: lo script completo di Python
Questo è lo script completo della rete neurale Python, che viene salvato come net.py e importato nello script principale:
# importazione di librerie
import os #Risolto problema durante la fase di addestramenton su GPU os.environ['CUDA_VISIBLE_DEVICES'] = '' import tensorflow as tf if tf.test.gpu_device_name(): print('GPU trovata') else: print("Nessuna GPU trovata ") da keras.preprocessing.image import ImageDataGenerator da keras.preprocessing import image from keras.models import Sequential da keras.layers import Conv2D, MaxPooling2D da keras.layers import Activation, Dropout, Flatten, Dense from keras import backend come K da 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 se K.image_data_format_first: 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(Activation ('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Conv2D(32, (2, 2))) model. 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(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(1)) model.add(Activation('sigmoid')) model.compile(loss='binary_crossentropy', Optimizer='rmsprop', metrics=['accuracy']) model.load_weights("model_saved.h5") def forecast(image_path): img = image.load_img(image_path, target_size=(1000, 500)) img = np.expand_dims(img, axis=0) risultato=model.predict_classes(img) return risultato [0][0]
Questo è il file Python principale, api.py:
richieste di importazione, sys, random, urllib.parse, cv2
from PIL import 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"Conteggio immagine attuale: {count }") i = 0 parametri = {"q": urllib.parse.quote(arg), "media_type": "image"} risultati = request.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(dati) mentre conta
Passaggio 7: l'app Electron
Panoramica
Creeremo una semplice app di elettroni che posiziona e carica solo l'elemento PhotoSphere. I file main.js e package.json provengono direttamente dal sito Web Electron e l'HTML è una versione leggermente modificata dell'HTML fornito sul sito Web PhotoSphere. Ho incluso i file, ma ho rinominato tutti in.txt, poiché Instructables non consente questi tipi di file. Per utilizzare i file, rinominarli con l'estensione appropriata.
Il codice
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().then(createWindow) app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow() } })
pacchetto.json
{
"name": "space", "version": "0.1.0", "main": "main.js", "scripts": { "start": "electron." } }
index.html
Passaggio 8: esecuzione
Creazione dell'immagine equirettangolare
Per creare l'immagine, esegui lo script api.py nel prompt dei comandi, con il suo ambiente virtuale attivato:
api.py
Al termine dell'esecuzione degli script, eseguire l'app di elettroni utilizzando:
npm inizioEcco! Il tuo planetario è attivo! Grazie per aver letto:)
Consigliato:
Osservatore di umidità e temperatura che utilizza Raspberry Pi con SHT25 in Python: 6 passaggi
Osservatore di umidità e temperatura che utilizza Raspberry Pi con SHT25 in Python: essendo un appassionato di Raspberry Pi, abbiamo pensato ad alcuni esperimenti più spettacolari con esso. In questa campagna, realizzeremo un osservatore di umidità e temperatura che misura l'umidità relativa e la temperatura utilizzando Raspberry Pi e SHT25, Umidi
Stazione meteorologica che utilizza Raspberry Pi con BME280 in Python: 6 passaggi
Stazione meteorologica che utilizza Raspberry Pi con BME280 in Python: is maith an scéalaí an goalir (Il tempo è un buon narratore) Con i problemi del riscaldamento globale e dei cambiamenti climatici, il modello meteorologico globale sta diventando irregolare in tutto il mondo portando a una serie di condizioni meteorologiche disastri naturali (siccità, estrema
Inverter collegato alla rete fai-da-te (non alimenta la rete) Alternativa UPS: 7 passaggi (con immagini)
Alternativa UPS con inverter collegato alla rete fai-da-te (non alimenta la rete): questo è un post di follow-up dal mio altro Instructable sulla creazione di un inverter collegato alla rete che non alimenta la rete, poiché ora è sempre possibile farlo in alcune aree come un progetto fai-da-te e alcuni luoghi non consentono di alimentare lì g
È una mano? (Fotocamera Raspberry Pi + Rete Neurale) Parte 1/2: 16 passaggi (con immagini)
È una mano? (Raspberry Pi Camera + Neural Network) Parte 1/2: Pochi giorni fa, mi sono infortunato al polso destro in palestra. In seguito, ogni volta che ho usato il mouse del mio computer, ha causato molto dolore a causa dell'angolo ripido del polso. Fu allora che mi colpì "non sarebbe fantastico se potessimo convertire qualsiasi superficie in un trackp
Robot di rete neurale Arduino: 21 passaggi (con immagini)
Robot di rete neurale Arduino: questa istruzione si basa su una serie di 3 parti che ho realizzato per il canale YouTube Make che mostra esattamente come prototipare, progettare, assemblare e programmare il tuo robot di rete neurale Arduino. Dopo aver visto la serie completa, dovresti avere una migliore