Planetarij z nevronskim omrežjem, ki uporablja Python, Electron in Keras: 8 korakov
Planetarij z nevronskim omrežjem, ki uporablja Python, Electron in Keras: 8 korakov
Anonim
Planetarij z nevronskim omrežjem, ki uporablja Python, Electron in Keras
Planetarij z nevronskim omrežjem, ki uporablja Python, Electron in Keras

V tem navodilu vam bom pokazal, kako sem s Pythonom in Electronom napisal samodejni 3D planetarijski generator

Zgornji video prikazuje enega od naključnih planetarij, ki jih je ustvaril program.

** Opomba: Ta program nikakor ni popoln in ponekod ni zelo pythonic. Diskriminator nevronske mreže je natančen le ~ 89%, zato bodo nekatere čudne slike prišle v planetarij **

Posebnosti

Planetarij poizveduje NASA API za slike, povezane s vesoljem, in uporablja konvolucijsko nevronsko mrežo, da ugotovi, ali je slika primerna za obdelavo. Program nato uporabi OpenCV za odstranjevanje ozadja s slike, na koncu pa slike združijo v eno veliko enako pravokotno sliko. Ta slika se nato shrani in aplikacija Electron Node.js odpre sliko ter s pomočjo paketa PhotoSphere.js prikaže sliko v 3D -formatu v slogu planetarij.

Odvisnosti

Python:

  • Keras
  • Blazina
  • cv2
  • Numpy
  • Zahteve
  • urllib
  • Naključen
  • čas
  • io

Elektron:

PhotoSphere

1. korak: Nastavite svoje okolje

Namestitev programa Electron in Python

Najprej se prepričajte, da imate nameščeni node.js in npm (če ne, lahko prenesete tukaj)

Nato morate namestiti Electron. Odprite ukazni poziv in vnesite naslednji ukaz:

npm namestite elektron -g

Nato potrebujete python, ki ga lahko prenesete tukaj

Nastavitev virtualnega okolja

Odprite ukazni poziv in vnesite naslednje ukaze za nastavitev navideznega okolja:

pip namestite virtualenv

virtualenv prostor

prostor na cd -ju

skripti / aktiviraj

Namestitev odvisnosti Python

Zaženite te ukaze v ukaznem pozivu, da namestite svoje odvisnosti od pythona:

pip namestite keras

pip namestite vzglavnik

pip install numpy

zahteve za namestitev pipa

pip namestite opencv-pythonČe želite sami usposobiti omrežje, nastavite pospeševanje grafičnega procesorja za Keras

2. korak: Poizvedovanje o iskalnem API -ju NASA

Pregled

NASA ima veliko res uporabnih API -jev, ki jih lahko uporabite pri svojih projektih. Za ta projekt bomo uporabili iskalni API, ki nam omogoča iskanje slik, povezanih z vesoljem, v Nasini zbirki slik.

Kodeks

Najprej moramo definirati funkcijo python, da sprejme argument, ki bo deloval kot iskalni izraz:

def get_image_search (fraza):

prehod

Nato bomo iskalni izraz pretvorili v obliko URL -ja in nato uporabili knjižnico zahtev za poizvedbo po API -ju:

def get_image_search (fraza):

params = {"q": urllib.parse.quote (arg), "media_type": "image"} results = requests.get ("https://images-api.nasa.gov/search", params = params)

Nazadnje bomo dekodirali zbirko+niz JSON, ki nam ga je vrnil API, in izvlekli seznam povezav do slik, povezanih z iskalnim izrazom:

def get_image_search (fraza):

params = {"q": urllib.parse.quote (arg), "media_type": "image"} results = requests.get ("https://images-api.nasa.gov/search", params = params) data = [result ['href'] za rezultat v results.json () ["collection"] ["items"]

No pa gremo! Zdaj imamo delček kode, ki lahko poizveduje API za iskanje slik NASA in vrne seznam povezav do slik, povezanih z našim iskalnim izrazom.

3. korak: Konvolucijsko nevronsko omrežje

Pregled

Naloga nevronskega omrežja je razvrstiti, ali je slika nečesa v vesolju ali ne. Za to bomo uporabili konvolucijsko nevronsko mrežo ali CNN, da izvedemo vrsto matričnih operacij na sliki in ugotovimo, kako velik je prostor-y. Tega ne bom razlagal, ker je za tem veliko teorije, če pa želite izvedeti več o nevronskih omrežjih, predlagam "Obvladovanje strojnega učenja"

Kodeks

Najprej moramo uvoziti naše odvisnosti:

uvoz os

#Popravite težavo med korakom vlaka na GPU os.environ ['CUDA_VISIBLE_DEVICES'] = '' uvozite tensorflow kot tf, če tf.test.gpu_device_name (): print ('GPU najden') else: print ("GPU ni mogoče najti") from keras.preprocessing.image import ImageDataGenerator from keras.preprocess import image from keras.models import Sequential from keras.layers import Conv2D, MaxPooling2D from keras.layers import Activation, Dropout, Flatten, Dense from keras import backend as K from PIL import Image uvoz numpy kot np

Nato moramo določiti naš 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 epochs = 10 batch_size = 8 if K.image_data_format () == 'channels_first': input_shape_id_heth_id, = (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 (izguba = 'binary_crossentropy', optimizer = 'rmsprop', metrics = ['natančnost'])

Model sem usposobil za vas, če pa želite model izučiti sami, na svojem naboru podatkov, sem priložil kodo usposabljanja. V nasprotnem primeru lahko prenesete datoteko HDF5 usposobljenega modela. Zaradi omejitev datotek Instructables sem jo moral preimenovati s pripono ".txt". Če ga želite uporabiti, preimenujte datoteko v razširitev ".h5" in jo naložite s to kodo:

model.load_weights ("model_saved.h5")

Za uporabo omrežja za predvidevanje prostora-y slike je opredeljena ta funkcija:

def napovedati (image_path):

img = image.load_img (pot_slike, velikost_cilja = (1000, 500)) img = np.expand_dims (img, os = 0) rezultat = model.predict_classes (img) vrni rezultat [0] [0]

4. korak: Obdelava slike

Pregled

Za obdelavo slik uporabljam knjižnico OpenCV (cv2). Najprej bomo zameglili robove slike, nato pa bomo odstranili ozadje z ustvarjanjem maske in spreminjanjem alfa vrednosti temnejših barv

Kodeks

To je del funkcije, ki zamegljuje robove:

def processImage (img):

RADIUS = 20 # Odpri sliko im = Image.open ("pilbuffer.png") # Prilepi sliko na belo ozadje diam = 2 * RADIUS nazaj = Image.new ('RGB', (im.size [0] + premer, im.size [1] + premer), (0, 0, 0)) back.paste (im, (RADIUS, RADIUS)) # Ustvari masko zameglitve = Image.new ('L', (im.size [0] + premer, im.size [1] + premer), 255) blck = Image.new ('L', (im.size [0] - premer, im.size [1] - premer), 0) maska. prilepi (blck, (premer, premer)) # Zameglite sliko in prilepite zamegljen rob glede na masko blur = back.filter (ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (blur, mask = mask) back.save (" transition.png ") back.close ()

Nato bomo temnejše barve nastavili na prozorne in sliko začasno shranili:

#Ustvarite masko in filter, črno zamenjajte z alfa

image = cv2.imread ("transition.png") hMin = 0 sMin = 0 vMin = 20 hMax = 180 sMax = 255 vMax = 255 spodnji = np.array ([hMin, sMin, vMin]) zgornji = np.array ([hMax, sMax, vMax]) hsv = cv2.cvtColor (slika, cv2. COLOR_BGR2HSV) maska = cv2.inRange (hsv, spodnji, zgornji) izhod = cv2.bitwise_and (slika, slika, maska = maska) *_, alfa = cv2.split (output) dst = cv2.merge ((output, alpha)) output = dst z odprto ("buffer.png", "w+") kot datoteka: pass cv2.imwrite ("buffer.png", output)

5. korak: Združite slike v enakopravno projekcijo

Pregled

Ta funkcija posname več slik in jih združi v obliko, ki jo lahko razlaga paket PhotoSphere.js s knjižnico PIL (blazina)

Kodeks

Najprej moramo ustvariti sliko, ki lahko deluje kot gostiteljica za druge slike:

novo = Image.new ("RGBA", (8000, 4000), barva = (0, 0, 0))

Nato moramo ponoviti niz slik (ki so bile vse spremenjene na 1000x500) in jih postaviti v sliko:

h = 0

w = 0 i = 0 za img v img_arr: new.paste (img, (w, h), img) w += 1000, če je w == 8000: h += 500 w = 0 i += 1

Zdaj to samo zavijemo v funkcijo, ki za argument vzame niz slik in vrne novo sliko:

def stitch_beta (img_arr):

novo = Image.new ("RGBA", (8000, 4000), barva = (0, 0, 0)) h = 0 w = 0 i = 0 za img v img_arr: new.paste (img, (w, h), img) w += 1000, če je w == 8000: h += 500 w = 0 i += 1 vrne novo

Korak 6: Celoten skript Python

To je celoten skript nevronskega omrežja python, ki je shranjen kot net.py in uvožen v glavni skript:

# uvoz knjižnic

import os #Fix za težavo med korakom vlaka na GPU os.environ ['CUDA_VISIBLE_DEVICES'] = '' uvoz tensorflow kot tf, če je tf.test.gpu_device_name (): print ('GPU najden') else: print ("GPU ni mogoče najti ") iz keras.preprocessing.image import ImageDataGenerator iz keras.preprocess uvoz slike iz keras.models import Sequential iz keras.layers uvoz Conv2D, MaxPooling2D iz keras.layers uvoz Activation, Dropout, Flatten, Dense from keras import backend as K from PIL uvoz slike uvoz numpy kot 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 ': 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 (Aktivacija ('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 = ['točnost']) model.load_weights ("model_saved.h5") def napovedati (image_path): img = image.load_img (image_path, target_size = (1000, 500)) img = np.expand_dims (img, axis = 0) result = model.predict_classes (img) vrniti rezultat [0] [0]

To je glavna datoteka python, api.py:

uvozne zahteve, sys, naključno, urllib.parse, cv2

iz PIL import Image, ImageFilter from io import BytesIO import numpy kot np import net def get_image_search (num, phrase): count = 0 img_arr = za arg v frazi: print (arg) print (f "Število trenutnih slik: {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'] za rezultat v results.json () [" collection "] [" items "] print (len (podatki)), če num> len (podatki): num = len (podatki) med štetjem = num: break print (f "\ n {count} slik obnovljenih") return img_arr def stitch_beta (img_arr): new = Image.new ("RGBA", (8000, 4000), color = (0, 0, 0)) h = 0 w = 0 i = 0 za img v img_arr: #pbar.set_description (f "Obdelava slike {i +1}") new.paste (img, (w, h), img) w += 1000 če w == 8000: h += 500 w = 0 i += 1 vrne nov def procesImage (img): RADIUS = 20 # Odpri sliko im = Image.open ("pilbuffer.png") # Prilepi sliko na belo ozadje diam = 2 * RADIUS nazaj = Image.new ('RGB', (im.size [0] + premer, im.size [1] + premer), (0, 0, 0)) back.paste (im, (RADIUS, RADIUS)) # Ustvari masko zameglitvene maske = Image.new ('L', (im.size [0] + premer, im.size [1] + premer), 255) blck = Image.new ('L', (im.size [0] - premer, im. ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (zamegljenost, maska = maska) back.save ("transition.png") back.close () #Ustvari masko in filter zamenjaj črno z alfa image = cv2.imread (" tranzit ion.png ") hMin = 0 sMin = 0 vMin = 20 hMax = 180 sMax = 255 vMax = 255 spodaj = np. matrika ([hMin, sMin, vMin]) zgornja = np. matrika ([hMax, sMax, vMax]) hsv = cv2.cvtColor (image, cv2. COLOR_BGR2HSV) mask = cv2.inRange (hsv, spodnji, zgornji) output = cv2.bitwise_and (image, image, mask = mask) *_, alpha = cv2.split (output) dst = cv2.merge ((output, alpha)) output = dst z odprto datoteko ("buffer.png", "w+") kot datoteka: pass cv2.imwrite ("buffer.png", output) #Zaznavanje robov in zameglitev, če _name_ == "_main_": search_terms = ["supernova", "planet", "galaksija", "mlečna pot", "meglica", "zvezde"] #Iskalne izraze lahko spremenite tako, kot želite, da planetarij vključuje img_arr = get_image_search (64, search_terms) print ("Pridobljene slike in nevronsko filtrirano") img = stitch_beta (img_arr) print ("Images stitched") img.save ("stitched.png")

7. korak: aplikacija Electron

Pregled

Ustvarili bomo preprosto elektronsko aplikacijo, ki samo pozicionira in naloži element PhotoSphere. Datoteki main.js in package.json sta neposredno na spletnem mestu Electron, HTML pa je nekoliko spremenjena različica HTML -ja na spletnem mestu PhotoSphere. Vključil sem datoteke, vendar sem vse preimenoval v.txt, saj Instructables ne dovoljuje teh vrst datotek. Če želite uporabiti datoteke, jih preimenujte z ustrezno razširitvijo.

Kodeks

main.js

const {app, BrowserWindow} = zahteva ("elektron")

funkcija createWindow () {const win = new BrowserWindow ({širina: 800, višina: 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 ('enable', () => {if (BrowserWindow.getAllWindows (). length === 0) {createWindow ()}})

package.json

{

"name": "space", "version": "0.1.0", "main": "main.js", "scripts": {"start": "electron." }}

index.html

8. korak: Izvedba

Ustvarjanje enakopravne podobe

Če želite ustvariti sliko, zaženite skript api.py v ukaznem pozivu z aktiviranim virtualnim okoljem:

api.py

Ko se skripti končajo z izvajanjem, zaženite elektronsko aplikacijo z uporabo:

npm startVoila! Vaš planetarij je aktiven! Hvala za branje:)

Priporočena: