Cuprins:

Planetariu alimentat de rețea neuronală folosind Python, Electron și Keras: 8 pași
Planetariu alimentat de rețea neuronală folosind Python, Electron și Keras: 8 pași

Video: Planetariu alimentat de rețea neuronală folosind Python, Electron și Keras: 8 pași

Video: Planetariu alimentat de rețea neuronală folosind Python, Electron și Keras: 8 pași
Video: Cum sa faci Simplu Perna de AER la Hidrofor 2024, Noiembrie
Anonim
Planetariu alimentat de rețea neuronală folosind Python, Electron și Keras
Planetariu alimentat de rețea neuronală folosind Python, Electron și Keras

În acest instructable, vă voi arăta cum am scris un generator automat de planetariu 3D, folosind Python și Electron

Videoclipul de mai sus arată unul dintre planetariile aleatorii pe care le-a generat programul.

** Notă: Acest program nu este în niciun fel perfect și, în unele locuri, nu este foarte pitonic. Discriminatorul de rețea neuronală are o precizie de numai ~ 89%, deci unele imagini ciudate vor ajunge în planetariu **

Specificații

Planetariul interogă un API NASA pentru imagini legate de spațiu și folosește o rețea neuronală convoluțională pentru a determina dacă imaginea este potrivită pentru procesare. Programul folosește apoi OpenCV pentru a elimina fundalul din imagine și, în cele din urmă, imaginile sunt îmbinate într-o singură imagine echirectangulară mare. Această imagine este apoi salvată și o aplicație Electron Node.js deschide imaginea și folosește pachetul PhotoSphere.js pentru a vizualiza imaginea într-un format 3D în stil planetariu.

Dependențe

Piton:

  • Keras
  • Pernă
  • cv2
  • Numpy
  • Cereri
  • urllib
  • Aleatoriu
  • timp
  • io

Electron:

Fotosferă

Pasul 1: Configurarea mediului dvs

Instalarea Electron și Python

Mai întâi, asigurați-vă că ați instalat node.js și npm (dacă nu, puteți descărca aici)

Apoi, trebuie să instalați Electron. Deschideți un prompt de comandă și introduceți următoarea comandă:

npm instala electron -g

Apoi, aveți nevoie de python, care poate fi descărcat de aici

Configurarea unui mediu virtual

Deschideți un prompt de comandă, apoi introduceți următoarele comenzi pentru a vă configura mediul virtual:

pip instala virtualenv

spațiu virtualenv

cd spatiu

scripturi / activate

Instalarea dependențelor Python

Rulați aceste comenzi în promptul de comandă pentru a instala dependențele dvs. Python:

pip instalează keras

pip instala perna

pip instalează numpy

solicitări de instalare pip

pip instalează opencv-pythonDacă doriți să instruiți singuri rețeaua, asigurați-vă că configurați accelerarea GPU pentru Keras

Pasul 2: interogarea NASA Căutare API

Prezentare generală

NASA are o mulțime de API-uri cu adevărat utile pe care le puteți folosi cu proiectele dvs. Pentru acest proiect, vom folosi API-ul de căutare, care ne permite să căutăm în baza de date a imaginilor NASA imagini legate de spațiu.

Codul

În primul rând, trebuie să definim o funcție python pentru a accepta un argument care va acționa ca termen de căutare:

def get_image_search (frază):

trece

Apoi, vom converti termenul de căutare în format URL, apoi vom folosi biblioteca de cereri pentru a interoga API-ul:

def get_image_search (frază):

params = {"q": urllib.parse.quote (arg), "media_type": "imagine"} rezultate = solicitări.get ("https://images-api.nasa.gov/search", params = params)

În cele din urmă, vom decoda colecția + șirul JSON pe care ni l-a returnat API-ul și vom extrage o listă de linkuri către imagini legate de termenul de căutare:

def get_image_search (frază):

params = {"q": urllib.parse.quote (arg), "media_type": "imagine"} rezultate = solicitări.get ("https://images-api.nasa.gov/search", params = params) date = [result ['href'] pentru rezultatul în results.json () ["collection"] ["items"]

Iată-ne! Acum avem un fragment de cod care poate interoga API-ul de căutare a imaginilor NASA și poate returna o listă de linkuri către imagini legate de termenul nostru de căutare.

Pasul 3: Rețeaua neuronală convoluțională

Prezentare generală

Sarcina rețelei neuronale este de a clasifica dacă o imagine este a ceva în spațiu sau dacă nu este. Pentru a face acest lucru, vom folosi o rețea neuronală convoluțională, sau CNN, pentru a efectua o serie de operații matrice pe imagine și pentru a determina cât de spațial este. Nu voi explica toate acestea, deoarece există o mulțime de teorii în spatele ei, dar dacă doriți să aflați despre rețelele neuronale, vă sugerez „Mașină de învățare automată”

Codul

În primul rând, trebuie să importăm dependențele noastre:

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") din keras.preprocessing.image import ImageDataGenerator din keras.preprocessing import image from keras.models import Sequential from keras.layers import Conv2D, MaxPooling2D from keras.layers import Activation, Dropout, Platten, Dense from keras import backend as K from PIL import Image import numpy ca np

În continuare, trebuie să ne definim modelul:

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_shape =: input_shape = = (img_width, img_height, 3) model = Sequential () model.add (Conv2D (32, (2, 2), input_shape = input_shape)) model.add (Activare ('relu'))) model.add (MaxPooling2D (pool_size = (2, 2))) model.add (Conv2D (32, (2, 2))) model.add (Activare ('relu')) model.add (MaxPooling2D (pool_size = (2, 2)))) model.add (Conv2D (64, (2, 2)))) model.add (Activare ('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 = ['precision'])

Am pregătit modelul pentru dvs., dar dacă doriți să instruiți modelul dvs., pe propriul set de date, atunci am atașat codul de instruire. În caz contrar, puteți descărca fișierul HDF5 al modelului instruit. Datorită restricțiilor de fișier Instructables, a trebuit să îl redenumesc cu o extensie „.txt”. Pentru a-l utiliza, redenumiți fișierul într-o extensie „.h5” și încărcați-l cu acest cod:

model.load_weights ("model_saved.h5")

Pentru a utiliza rețeaua pentru a prezice cât de spațiu este o imagine, vom defini această funcție:

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) returnează rezultatul [0] [0]

Pasul 4: Procesarea imaginii

Prezentare generală

Pentru procesarea imaginilor, folosesc biblioteca OpenCV (cv2). Mai întâi, vom estompa marginile imaginii și apoi vom elimina fundalul creând o mască și schimbând valorile alfa ale culorilor mai întunecate.

Codul

Aceasta este partea funcției care estompează marginile:

def processImage (img):

RADIUS = 20 # Deschideți o imagine im = Image.open ("pilbuffer.png") # Inserați imaginea pe fundal alb diam = 2 * RADIUS înapoi = Image.new ('RGB', (im.size [0] + diam, im.size [1] + diam), (0, 0, 0)) back.paste (im, (RADIUS, RADIUS)) # Create mask blur mask 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) mască. paste (blck, (diam, diam)) # Blur image and paste blurred edge according to mask blur = back.filter (ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (blur, mask = mask) back.save (" transition-p.webp

Apoi, vom seta culorile mai închise la transparent și vom salva temporar imaginea:

#Creați masca și filtru înlocuiți negrul cu 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 (imagine, cv2. COLOR_BGR2HSV) mască = cv2.inRange (hsv, jos, superior) ieșire = cv2.bitwise_and (imagine, imagine, mască = mască) * _, alfa = cv2.split (output) dst = cv2.merge ((output, alfa)) output = dst cu open ("buffer.png", "w +") ca fișier: trece cv2.imwrite ("buffer.png", output)

Pasul 5: Îmbinarea imaginilor împreună într-o proiecție echirectangulară

Prezentare generală

Această funcție preia mai multe imagini și le îmbină într-un format care poate fi interpretat de pachetul PhotoSphere.js, utilizând biblioteca PIL (pernă)

Codul

În primul rând, trebuie să creăm o imagine care poate acționa ca gazdă pentru celelalte imagini:

nou = Image.new ("RGBA", (8000, 4000), culoare = (0, 0, 0))

Apoi, trebuie să parcurgem matricea de imagini (care au fost redimensionate la 1000x500) și să le plasăm în imagine:

h = 0

w = 0 i = 0 pentru img în img_arr: new.paste (img, (w, h), img) w + = 1000 dacă w == 8000: h + = 500 w = 0 i + = 1

Acum, doar încheiem acest lucru într-o funcție care ia o serie de imagini ca argument și returnează noua imagine:

def stitch_beta (img_arr):

new = Image.new ("RGBA", (8000, 4000), color = (0, 0, 0)) h = 0 w = 0 i = 0 pentru img în img_arr: new.paste (img, (w, h), img) w + = 1000 if w == 8000: h + = 500 w = 0 i + = 1 return new

Pasul 6: Scriptul complet Python

Acesta este scriptul complet de rețea neuronală Python, care este salvat ca net.py și importat în scriptul principal:

# importarea bibliotecilor

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 ") din keras.preprocessing.image import ImageDataGenerator din keras.preprocessing import image from keras.models import Sequential from keras.layers import Conv2D, MaxPooling2D from keras.layers import Activation, Dropout, Platten, Dense from keras import backend as K from PIL import imagine import numpy ca 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 (Activare ('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 (Activare ('relu')) model.add (Dropout (0.5))) model.add (Dense (1)) model.add (Activare ('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) returnează rezultatul [0] [0]

Acesta este fișierul principal python, api.py:

solicitări de import, sys, random, urllib.parse, cv2

din 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 "Număr curent de imagini: {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 (date) în timp ce contează = num: break print (f "\ n {count} imagini recuperate") returnează img_arr def stitch_beta (img_arr): new = Image.new ("RGBA", (8000, 4000), color = (0, 0, 0)) h = 0 w = 0 i = 0 pentru img în img_arr: # pbar.set_description (f "Prelucrarea imaginii {i + 1}") new.paste (img, (w, h), img) w + = 1000 if w == 8000: h + = 500 w = 0 i + = 1 returnează noul proces def Imagine (img): RADIUS = 20 # Deschide o imagine im = Image.open ("pilbuffer.png") # Inserați imaginea pe fundal alb diam = 2 * RADIUS înapoi = Image.new ('RGB', (im.size [0] + diam, im.size [1] + diam), (0, 0, 0)) back.paste (im, (RADIUS); (im.size [0] - diam, im.size [1] - diam), 0) mask.paste (blck, (diam, diam)) # Blur image and paste blurred edge according to mask blur = back.filter (ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (blur, mask = mask) back.save ("transition.png") back.close () #Create mask and filter replace black with alpha image = cv2.imread (" tranzit ion.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 ((ieșire, alfa)) ieșire = dst cu open ("buffer.png", "w +") ca fișier: trece cv2.imwrite ("buffer.png", ieșire) #Edge detectare și estompare dacă _name_ == "_main_": search_terms = ["supernova", "planetă", "galaxie", "cale lactee", "nebuloasă", "stele"] # Termenii de căutare pot fi modificați pentru orice doriți să includă planetariul img_arr = get_image_search (64, search_terms) print ("Imagini recuperate și filtrate neuronal") img = stitch_beta (img_arr) print ("Imagini cusute") img.save ("stitched.png")

Pasul 7: Aplicația Electron

Prezentare generală

Vom crea o aplicație electronică simplă care poziționează și încarcă elementul PhotoSphere. Fișierele main.js și package.json sunt direct de pe site-ul Electron, iar codul HTML este o versiune ușor modificată a codului HTML furnizat pe site-ul PhotoSphere. Am inclus fișierele, dar le-am redenumit toate la.txt, deoarece Instructables nu permite aceste tipuri de fișiere. Pentru a utiliza fișierele, redenumiți-le cu extensia corespunzătoare.

Codul

main.js

const {app, BrowserWindow} = require ('electron')

funcție 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 ()}})

pachet.json

{

"nume": "spațiu", "versiune": "0.1.0", "principal": "main.js", "scripturi": {"start": "electron." }}

index.html

Pasul 8: Executarea

Crearea imaginii echirectangulare

Pentru a crea imaginea, rulați scriptul api.py în linia de comandă, cu mediul său virtual activat:

api.py

După ce scripturile au terminat de executat, rulați aplicația electron folosind:

npm startVoila! Planetariul tău este activ! Multumesc pentru citire:)

Recomandat: