Neuroverkolla toimiva planetaario Pythonin, Electronin ja Kerasin avulla: 8 vaihetta
Neuroverkolla toimiva planetaario Pythonin, Electronin ja Kerasin avulla: 8 vaihetta
Anonim
Neuraaliverkossa toimiva planetaario Pythonin, Electronin ja Kerasin avulla
Neuraaliverkossa toimiva planetaario Pythonin, Electronin ja Kerasin avulla

Tässä ohjeessa näytän sinulle, kuinka kirjoitin automaattisen 3D -planetaariogeneraattorin Pythonin ja Electronin avulla

Yllä oleva video näyttää yhden ohjelman luomista satunnaisista planetaarioista.

** Huomautus: Tämä ohjelma ei ole mitenkään täydellinen, ja joissain paikoissa ei kovin pythoninen. Neuraaliverkon erottelija on vain ~ 89% tarkka, joten parittomat kuvat pääsevät planetaarioon **

Erityispiirteet

Planetaario hakee avaruuteen liittyviä kuvia NASA: n sovellusliittymästä ja käyttää konvoluution hermoverkkoa määrittääkseen, soveltuuko kuva käsittelyyn. Ohjelma poistaa sitten OpenCV: n taustakuvasta ja lopuksi kuvat yhdistetään yhdeksi suureksi suorakulmaiseksi kuvaksi. Tämä kuva tallennetaan, ja Electron Node.js -sovellus avaa kuvan ja käyttää PhotoSphere.js -pakettia kuvan katsomiseen planetaario -tyylisessä 3D -muodossa.

Riippuvuudet

Python:

  • Keras
  • Tyyny
  • cv2
  • Numpy
  • Pyynnöt
  • urllib
  • Satunnainen
  • aika
  • io

Elektroni:

PhotoSphere

Vaihe 1: Ympäristön määrittäminen

Electronin ja Pythonin asennus

Varmista ensin, että olet asentanut node.js ja npm (jos ei, voit ladata täältä)

Seuraavaksi sinun on asennettava Electron. Avaa komentokehote ja anna seuraava komento:

npm asenna elektroni -g

Seuraavaksi tarvitset pythonin, jonka voit ladata täältä

Virtuaalisen ympäristön määrittäminen

Avaa komentokehote ja määritä virtuaalinen ympäristö kirjoittamalla seuraavat komennot:

pip asenna virtualenv

virtualenv tilaa

cd -tilaa

skriptit / aktivoi

Python -riippuvuuksien asentaminen

Asenna python -riippuvuutesi suorittamalla nämä komennot komentokehotteessa:

pip asenna keras

pip asenna tyyny

pip asenna numpy

pip -asennuspyynnöt

pip asenna opencv-pythonJos haluat kouluttaa verkkoa itse, muista määrittää GPU -kiihdytys Kerasille

Vaihe 2: Kyselyn tekeminen NASA Search API: sta

Yleiskatsaus

NASAlla on paljon todella hyödyllisiä sovellusliittymiä, joita voit käyttää projekteissasi. Tässä projektissa käytämme hakusovellusliittymää, jonka avulla voimme etsiä avaruuteen liittyviä kuvia NASAn kuvatietokannasta.

Koodi

Ensinnäkin meidän on määriteltävä python -funktio hyväksymään argumentti, joka toimii hakuterminä:

def get_image_search (lause):

kulkea

Seuraavaksi muunnamme hakutermin URL -muotoon ja käytämme sitten pyyntökirjastoa sovellusliittymän kyselyyn:

def get_image_search (lause):

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

Lopuksi dekoodaamme kokoelman+JSON -merkkijonon, jonka sovellusliittymä palautti meille, ja poimimme luettelon hakutermiin liittyvistä kuvista:

def get_image_search (lause):

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

Näillä mennään! Meillä on nyt koodinpätkä, joka voi tehdä kyselyn NASAn kuvahakusovellusliittymästä ja palauttaa luettelon hakutermiimme liittyvistä kuvista.

Vaihe 3: Konvoluution hermoverkko

Yleiskatsaus

Neuraaliverkon tehtävä on luokitella, onko kuva jostain avaruudessa vai ei. Tätä varten käytämme konvoluution hermoverkkoa tai CNN: ää suorittaaksemme kuvalle matriisioperaatioita ja määrittääksemme kuinka avaruus-y se on. En selitä tätä kaikkea, koska sen takana on paljon teoriaa, mutta jos haluat oppia hermoverkkoista, ehdotan "koneoppimisen hallintaa"

Koodi

Ensinnäkin meidän on tuotava riippuvuudet:

tuonti

#Korjaa ongelma junan vaiheen aikana GPU os.environ ['CUDA_VISIBLE_DEVICES'] = '' tuo tensorflow tf -muodossa, jos tf.test.gpu_device_name (): print ('GPU found') else: print ("GPU: ta ei löytynyt") from keras.preprocessing.image import ImageDataGenerator from keras.preprocessing import image from keras.models import Sequential from keras.layers import Conv2D, MaxPooling2D from keras.layers Import Activation, Dropout, Flatten, Tense from keras import backend as K from PIL import Image tuo numpy np: nä

Seuraavaksi meidän on määriteltävä mallimme:

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_shap_w = = (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 (Aktivointi ('relu')) model.add (MaxPooling2D (pool_size = (2, 2)))).add (Conv2D (64, (2, 2)))) model.add (Activation ('relu')) model.add (MaxPooling2D (pool_size = (2, 2)))) model.add (Flatten ()) model. lisää (Tiheä (64)) model.add (Aktivointi ('relu')) model.add (Dropout (0.5)) model.add (Tiheä (1)) model.add (Aktivointi ('sigmoidi')) model.compile (loss = 'binary_crossentropy', optimoija = 'rmsprop', metrics = ['tarkkuus'])

Olen kouluttanut mallin sinulle, mutta jos haluat kouluttaa mallin itse omalla tietojoukollasi, olen liittänyt siihen koulutuskoodin. Muussa tapauksessa voit ladata koulutetun mallin HDF5 -tiedoston. Instructables -tiedostorajoitusten vuoksi olen joutunut nimeämään sen uudelleen.txt -laajennuksella. Jos haluat käyttää sitä, nimeä tiedosto uudelleen.h5 -laajennukseksi ja lataa se tällä koodilla:

model.load_weights ("model_saved.h5")

Määritämme tämän toiminnon käyttääksemme verkkoa ennustamaan, kuinka tila-y kuva on

def ennustaa (image_path):

img = image.load_img (image_path, target_size = (1000, 500)) img = np.expand_dims (img, axis = 0) result = model.predict_classes (img) palautustulos [0] [0]

Vaihe 4: Kuvan käsittely

Yleiskatsaus

Kuvankäsittelyyn käytän OpenCV (cv2) -kirjastoa. Ensin sumennamme kuvan reunat ja poistamme sitten taustan luomalla maskin ja muuttamalla tummempien värien alfa -arvoja

Koodi

Tämä on osa toimintoa, joka sumentaa reunat:

def processImage (img):

RADIUS = 20 # Avaa kuva im = Image.open ("pilbuffer.png") # Liitä kuva valkoiselle taustalle diam = 2 * RADIUS back = Image.new ('RGB', (im.koko [0] + diam, im.koko [1] + halkaisija), (0, 0, 0)) back.paste (im, (RADIUS, RADIUS)) # Luo sumennusmaski = Image.new ('L', (im.koko [0] + halkaisija, im.koko [1] + halkaisija), 255) blck = Kuva.uusi ('L', (kuvakoko [0] - halkaisija, im.koko [1] - halkaisija), 0) maski. liitä (blck, (diam, diam)) # Hämärtää kuvaa ja liittää sumea reuna maskin sumennuksen mukaan = back.filter (ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (sumennus, naamio = naamio) back.save (" siirtyminen-p.webp

Seuraavaksi asetamme tummemmat värit läpinäkyviksi ja tallennamme kuvan väliaikaisesti:

#Luo naamio ja suodatin, korvaa musta alfa

image = cv2.imread ("siirtyminen.png") hMin = 0 sMin = 0 vMin = 20 hMax = 180 sMax = 255 vMax = 255 alempi = np.array ([hMin, sMin, vMin]) ylä = np.array ([hMax, sMax, vMax]) hsv = cv2.cvtColor (kuva, cv2. COLOR_BGR2HSV) mask = cv2.inRange (hsv, alempi, ylempi) output = cv2.bitwise_and (kuva, kuva, maski = maski) *_, alfa = cv2.split (output) dst = cv2.merge ((output, alpha)) output = dst with open ("buffer.png", "w+") tiedostona: pass cv2.imwrite ("buffer.png", output)

Vaihe 5: ompele kuvat yhteen suorakulmaiseksi projektioksi

Yleiskatsaus

Tämä toiminto ottaa useita kuvia ja yhdistää ne muotoon, jonka PhotoSphere.js -paketti voi tulkita PIL (tyyny) -kirjastoa käyttämällä

Koodi

Ensinnäkin meidän on luotava kuva, joka voi toimia muiden kuvien isäntänä:

new = Image.new ("RGBA", (8000, 4000), väri = (0, 0, 0))

Seuraavaksi meidän on toistettava kuvasarja (kaikki on muutettu kokoon 1000x500) ja sijoitettava ne kuvaan:

h = 0

w = 0 i = 0 img: lle img_arr: new.paste (img, (w, h), img) w += 1000 jos w == 8000: h += 500 w = 0 i += 1

Nyt vain käärimme tämän funktioon, joka ottaa argumenttina joukon kuvia ja palauttaa uuden kuvan:

def stitch_beta (img_arr):

new = Image.new ("RGBA", (8000, 4000), väri = (0, 0, 0)) h = 0 w = 0 i = 0 img_arr: new.paste (img, (w, h), img) w += 1000 jos w == 8000: h += 500 w = 0 i += 1 palauta uusi

Vaihe 6: Koko Python -skripti

Tämä on täydellinen python -hermoverkkoskripti, joka tallennetaan nimellä net.py ja tuodaan pääskriptiin:

# tuo kirjastoja

import os #Fix for the train stepn oN GPU os.environ ['CUDA_VISIBLE_DEVICES'] = '' tuo tensorflow tf -muodossa, jos tf.test.gpu_device_name (): print ('GPU found') else: print ("GPU: ta ei löydy") ") osoitteesta keras.preprocessing.image import ImageDataGenerator from keras.preprocessing 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 tuonti kuvan tuonti numpy muodossa 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 = K. 'image: 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 (Aktivointi ('relu')) model.add (MaxPooling2D (pool_size = (2, 2)))) model.add (Conv2D (32, (2, 2)))) malli. add (Aktivointi ('relu')) model.add (MaxPooling2D (pool_size = (2, 2)))) model.add (Conv2D (64, (2, 2)))) model.add (Aktivointi ('relu')) model.add (MaxPooling2D (pool_size = (2, 2))) model.add (Flatten ()) model.add (Tiheä (64)) model.add (Aktivointi ('relu')) model.add (Dropout (0.5)) model.add (Tiheä (1)) model.add (Aktivointi ('sigmoidi')) model.compile (loss = 'binary_crossentropy', optimizer = 'rmsprop', metrics = ['tarkkuus']) model.load_weights ("model_saved.h5") def ennustaa (image_path): img = image.load_img (image_path, target_size = (1000, 500)) img = np.expand_dims (img, axis = 0) result = model.predict_classes (img) palautustulos [0] [0]

Tämä on tärkein python -tiedosto, api.py:

tuontipyynnöt, sys, random, urllib.parse, cv2

PIL -tuontikuvasta, ImageFilter io -tuonnista BytesIO tuonti numpy np -muodossa tuonti net def get_image_search (numero, lause): count = 0 img_arr = argumentille lauseessa: print (arg) print (f "Nykyinen kuvien määrä: {count } ") i = 0 params = {" q ": urllib.parse.quote (arg)," media_type ":" image "} results = 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 (data) laskettaessa = numero: taukotulostus (f "\ n {count} kuvaa palautettu") return img_arr def stitch_beta (img_arr): new = Image.new ("RGBA", (8000, 4000), väri = (0, 0, 0)) h = 0 w = 0 i = 0 img_arr: #pbar.set_description (f "Kuvan käsittely {i +1}") new.paste (img, (w, h), img) w += 1000 if w == 8000: h += 500 w = 0 i += 1 palauta uusi def -prosessiKuva (img): RADIUS = 20 # Avaa kuva im = Image.open ("pilbuffer.png") # Liitä kuva valkoiselle taustalle diam = 2 * RADIUS takaisin = Kuva.uusi ('RGB', (im.koko [0] + halkaisija, im.koko [1] + halkaisija), (0, 0, 0)) back.paste (im, (RADIUS, RADIUS)) # Luo sumennusmaski = Image.new ('L', (im.koko [0] + halkaisija, im.koko [1] + halkaisija), 255) blck = Image.new ('L', (im. koko [0] - halkaisija, im. koko [1] - halkaisija), 0) mask.paste (blck, (diam, diam)) # Hämärtää kuvaa ja liittää epäselvä reuna maskin sumennuksen mukaan = back.filter (ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (sumennus, naamio = naamio) back.save ("siirtymä.png") back.close () #Luo maski ja suodatin korvaa musta alfa -kuva = cv2.imread (" kauttakulku ion.png ") hMin = 0 sMin = 0 vMin = 20 hMax = 180 sMax = 255 vMax = 255 alempi = np.array ([hMin, sMin, vMin]) ylempi = np.array ([hMax, sMax, vMax]) hsv = cv2.cvtColor (kuva, cv2. COLOR_BGR2HSV) mask = cv2.inRange (hsv, alempi, ylempi) output = cv2.bitwise_and (kuva, kuva, maski = maski) *_, alpha = cv2.split (output) dst = cv2.merge ((output, alpha)) output = dst with open ("buffer.png", "w+") tiedostona: pass cv2.imwrite ("buffer.png", output) #reunan tunnistus ja sumennus, jos _name_ == "_main_": search_terms = ["supernova", "planeetta", "galaksi", "Linnunrata", "sumu", "tähdet"] #Hakutermit voidaan muuttaa mihin tahansa planetaarion sisällytettäväksi img_arr = get_image_search (64, search_terms) print ("Kuvat haettu ja hermosuodatettu") img = stitch_beta (img_arr) print ("Images stitched") img.save ("stitched.png")

Vaihe 7: Electron -sovellus

Yleiskatsaus

Luomme yksinkertaisen elektronisovelluksen, joka vain sijoittaa ja lataa PhotoSphere -elementin. Main.js- ja package.json -tiedostot ovat suoraan Electronin verkkosivustolta, ja HTML on hieman muokattu versio PhotoSphere -verkkosivuston HTML -koodista. Olen sisällyttänyt tiedostot, mutta nimesin ne kaikki uudelleen.txt -tiedostoiksi, koska Instructables ei salli näitä tiedostotyyppejä. Jos haluat käyttää tiedostoja, nimeä ne uudelleen sopivalla laajennuksella.

Koodi

main.js

const {sovellus, BrowserWindow} = vaatii ('elektroni')

function createWindow () {const win = new BrowserWindow ({leveys: 800, korkeus: 600, webPreferences: {nodeIntegration: true}}) win.loadFile ('index.html')} app.whenReady (). sitten (createWindow) app.on ('window-all-closed', () => {if (process.platform! == 'darwin') {app.quit ()}}) app.on ('aktivoi', () => {if (BrowserWindow.getAllWindows (). length === 0) {createWindow ()}})

package.json

{

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

index.html

Vaihe 8: Toteutus

Tasasuuntaisen kuvan luominen

Luo kuva suorittamalla api.py -komentosarja komentorivillä ja sen virtuaalinen ympäristö aktivoituna:

api.py

Kun komentosarjat on suoritettu, suorita elektronisovellus käyttämällä:

npm alkuVoila! Planetaariosi on aktiivinen! Kiitos kun luit:)

Suositeltava: