Neurale netwerk -aangedrewe planetarium met behulp van Python, elektron en Keras: 8 stappe
Neurale netwerk -aangedrewe planetarium met behulp van Python, elektron en Keras: 8 stappe
Anonim
Neurale netwerk -aangedrewe planetarium met behulp van Python, elektron en Keras
Neurale netwerk -aangedrewe planetarium met behulp van Python, elektron en Keras

In hierdie instruksies sal ek jou wys hoe ek 'n outomatiese 3D -planetariumgenerator met Python en Electron geskryf het

Die video hierbo toon een van die ewekansige planetariums wat die program gegenereer het.

** Opmerking: hierdie program is geensins perfek nie en op sommige plekke nie baie pythonies nie. Die neurale netto diskriminator is slegs ~ 89% akkuraat, so 'n paar vreemde beelde sal die planetarium bereik **

Spesifiek

Die planetarium vra 'n NASA API vir ruimteverwante beelde en gebruik 'n konvolusionele neurale netwerk om te bepaal of die beeld geskik is vir verwerking. Die program gebruik dan OpenCV om die agtergrond van die prent te verwyder, en laastens word die beelde in een groot gelykhoekige beeld saamgevoeg. Hierdie prent word dan gestoor, en 'n Electron Node.js -toepassing maak die prent oop en gebruik die PhotoSphere.js -pakket om die beeld in 'n planetarium -styl 3D -formaat te sien.

Afhanklikes

Python:

  • Keras
  • Kussing
  • cv2
  • Knorrig
  • Versoeke
  • urllib
  • Willekeurig
  • tyd
  • io

Elektron:

PhotoSphere

Stap 1: Stel u omgewing op

Elektron en Python geïnstalleer

Maak eers seker dat node.js en npm geïnstalleer is (indien nie, kan u dit hier aflaai)

Vervolgens moet u Electron installeer. Open 'n opdragprompt en voer die volgende opdrag in:

npm installeer elektron -g

Daarna benodig u python, wat hier afgelaai kan word

Die opstel van 'n virtuele omgewing

Open 'n opdragprompt en voer die volgende opdragte in om u virtuele omgewing op te stel:

pip installeer virtualenv

virtualenv ruimte

cd spasie

skrifte / aktiveer

Die installering van Python -afhanklikhede

Voer hierdie opdragte uit in die opdragprompt om u python -afhanklikhede te installeer:

pip installeer keras

pip installeer kussing

pip installeer numpy

pip -installeringsversoeke

pip installeer opencv-pythonAs u self die netwerk wil oplei, moet u GPU -versnelling vir Keras instel

Stap 2: Stel navraag oor die NASA Search API

Oorsig

NASA het baie nuttige API's wat u met u projekte kan gebruik. Vir hierdie projek gebruik ons die soek-API, waarmee ons NASA se beelddatabasis kan soek na ruimteverwante beelde.

Die kode

Eerstens moet ons 'n luislangfunksie definieer om 'n argument te aanvaar wat as die soekterm sal dien:

def get_image_search (frase):

slaag

Vervolgens sal ons die soekterm in URL -formaat omskakel en dan die versoekbiblioteek gebruik om navraag te doen na die API:

def get_image_search (frase):

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

Laastens sal ons die versameling+JSON -string wat die API aan ons teruggestuur het, dekodeer en 'n lys met skakels na beelde wat verband hou met die soekterm uittrek:

def get_image_search (frase):

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

Daar gaan ons! Ons het nou 'n kodefragment wat die NASA -beeldsoek -API kan navraag doen, en 'n lys met skakels na beelde wat met ons soekterm verband hou, kan teruggee.

Stap 3: Die konvolutionele neurale netwerk

Oorsig

Die taak van die neurale netwerk is om te klassifiseer of 'n beeld van iets in die ruimte is, of nie. Om dit te doen, sal ons 'n konvolusionele neurale netwerk, of CNN, gebruik om 'n reeks matriksbewerkings op die beeld uit te voer en te bepaal hoe spasie-y dit is. Ek sal dit nie alles verduidelik nie, want daar is baie teorie daaragter, maar as u meer wil leer oor neurale netwerke, stel ek 'Machine Learning Mastery' voor

Die kode

Eerstens moet ons ons afhanklikes invoer:

invoer os

#Fix for issue during train stepn on GPU os.environ ['CUDA_VISIBLE_DEVICES'] = '' invoer tensorflow as tf if tf.test.gpu_device_name (): print ('GPU found') else: print ("No GPU found") vanaf keras.preprocessing.image import ImageDataGenerator van 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 import Image invoer numpy as np

Vervolgens moet ons ons model definieer:

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 () == 'channel_first': input_shape = (3, img_ = (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 (Aktivering ('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. voeg by (Dig (64)) model.add (Aktivering ('relu')) model.add (Uitval (0.5)) model.add (Dig (1)) model.add (Aktivering ('sigmoid')) model.com (loss = 'binary_crossentropy', optimizer = 'rmsprop', metrics = ['accuracy'])

Ek het die model vir u opgelei, maar as u die model self wil oplei, op u eie datastel, het ek die opleidingskode aangeheg. Anders kan u die opgeleide model se HDF5 -lêer aflaai. Weens Instructables lêer beperkings, moes ek dit hernoem met 'n ".txt" uitbreiding. Om dit te gebruik, hernoem die lêer na 'n ".h5" -uitbreiding en laai dit met hierdie kode:

model.load_weights ("model_saved.h5")

Om die netwerk te gebruik om te voorspel hoe ruimte-y 'n beeld is, definieer ons hierdie funksie:

def voorspel (image_path):

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

Stap 4: Verwerking van die prent

Oorsig

Vir beeldverwerking gebruik ek die OpenCV (cv2) biblioteek. Eerstens vervaag ons die rande van die prent, en dan verwyder ons die agtergrond deur 'n masker te skep en die alfa -waardes van die donkerder kleure te verander

Die kode

Dit is die deel van die funksie wat die rande vervaag:

def processImage (img):

RADIUS = 20 # Maak 'n prent oop im = Image.open ("pilbuffer.png") # Plak prent op wit agtergrond diam = 2 * RADIUS back = Image.new ('RGB', (im.size [0] + diam, im.size [1] + diam), (0, 0, 0)) back.paste (im, (RADIUS, RADIUS)) # Skep vervaagmaskermasker = 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) masker. plak (blck, (diam, diam)) # Vervaag beeld en plak vervaagde rand volgens maskervervaaging = agterkant.filter (ImageFilter. GaussianBlur (RADIUS / 2)) terug.plak (vervaag, masker = masker) terug.save (" transition-p.webp

Vervolgens stel ons die donkerder kleure op deursigtig en stoor die prent tydelik:

#Skep masker en filter, vervang swart met 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, onderste, boonste) uitvoer = cv2.bitwise_and (beeld, beeld, masker = masker) *_, alfa = cv2.split (output) dst = cv2.merge ((output, alpha)) output = dst with open ("buffer.png", "w+") as file: pass cv2.imwrite ("buffer.png", output)

Stap 5: Beelde saamvoeg tot 'n gelykhoekige projeksie

Oorsig

Hierdie funksie neem verskeie beelde en maak dit in 'n formaat wat deur die PhotoSphere.js -pakket geïnterpreteer kan word, met behulp van die PIL (kussing) biblioteek

Die kode

Eerstens moet ons 'n beeld skep wat kan dien as die gasheer vir die ander beelde:

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

Vervolgens moet ons deur die verskeidenheid beelde (wat almal na 1000x500 verander is) herhaal en in die beeld geplaas word:

h = 0

w = 0 i = 0 vir img in img_arr: new.paste (img, (w, h), img) w += 1000 as w == 8000: h += 500 w = 0 i += 1

Nou sluit ons dit net in 'n funksie wat 'n verskeidenheid beelde as argument aanneem en die nuwe beeld terug:

def stitch_beta (img_arr):

new = Image.new ("RGBA", (8000, 4000), color = (0, 0, 0)) h = 0 w = 0 i = 0 vir img in img_arr: new.paste (img, (w, h), img) w += 1000 as w == 8000: h += 500 w = 0 i += 1 opgawe nuut

Stap 6: Die volledige Python -script

Dit is die volledige python neurale netwerk script, wat as net.py gestoor word en in die hoof script ingevoer word:

# biblioteke invoer

import os #Fix for issue during train stepn of GPU os.environ ['CUDA_VISIBLE_DEVICES'] = '' import tensorflow as tf if tf.test.gpu_device_name (): print ('GPU found') else: print ("Geen GPU gevind nie ") vanaf keras.preprocessing.image import ImageDataGenerator van 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 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 if K.imat_data ': 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 (Aktivering ('relu')) model.add (MaxPooling2D (pool_size = (2, 2)))) model.add (Conv2D (32, (2, 2)))) model. voeg (Aktivering ('relu')) model.add (MaxPooling2D (pool_size = (2, 2))) model.add (Conv2D (64, (2, 2))) model.add (Aktivering ('relu')) model.add (MaxPooling2D (pool_size = (2, 2))) model.add (Flatten ()) model.add (Dicht (64)) model.add (Aktivering ('relu')) model.add (Uitval (0.5)) model.add (Dig (1)) model.add (Aktivering ('sigmoid')) model.compile (loss = 'binary_crossentropy', optimizer = 'rmsprop', metrics = ['akkuraatheid']) model.load_weights ("model_saved.h5") def voorspel (image_path): img = image.load_img (image_path, target_size = (1000, 500)) img = np.expand_dims (img, axis = 0) result = model.predict_classes (img) opbrengs resultaat [0] [0]

Dit is die belangrikste python -lêer, api.py:

invoerversoeke, sys, random, urllib.parse, cv2

vanaf PIL import Image, ImageFilter van io import BytesIO import numpy as np import net def get_image_search (num, frase): count = 0 img_arr = vir arg in frase: print (arg) print (f "Huidige beeldtelling: {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'] vir resultaat in results.json () [" collection "] [" items "] print (len (data)) as num> len (data): num = len (data) terwyl tel = num: breek afdruk (f "\ n {count} images retreived") return img_arr def stitch_beta (img_arr): new = Image.new ("RGBA", (8000, 4000), color = (0, 0, 0)) h = 0 w = 0 i = 0 vir img in img_arr: #pbar.set_description (f "Beeld verwerk {i +1}") new.paste (img, (w, h), img) w += 1000 if w == 8000: h += 500 w = 0 i += 1 gee nuwe def proses terug Beeld (img): RADIUS = 20 # Maak 'n prent oop im = Image.open ("pilbuffer.png") # Plak prent op wit agtergrond diam = 2 * RADIUS terug = Image.new ('RGB', (im.size [0] + diam, im.size [1] + diam), (0, 0, 0)) back.paste (im, (RADIUS, RADIUS)) # Skep vervaagmaskermasker = 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)) # Vervaag beeld en plak vervaagde rand volgens masker vervaag = terug.filter (ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (blur, mask = mask) back.save ("transition.png") back.close () #Maak masker en filter vervang swart met alfa image = cv2.imread (" transito 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 (beeld, cv2. COLOR_BGR2HSV) masker = cv2.inRange (hsv, onderste, boonste) uitvoer = cv2.bitwise_and (beeld, beeld, masker = masker) *_, alfa = cv2.split (uitset) dst = cv2.merge ((output, alpha)) output = dst with open ("buffer.png", "w+") as file: pass cv2.imwrite ("buffer.png", output) #Edge detectie en vervaging as _name_ == "_main_": search_terms = ["supernova", "planeet", "sterrestelsel", "melkweg", "newel", "sterre"] #Die soekterme kan verander word na alles wat u wil hê die planetarium moet insluit img_arr = get_image_search (64, search_terms) druk ("Beelde opgespoor en neuraal gefiltreer") img = stitch_beta (img_arr) print ("Images stitched") img.save ("stitched.png")

Stap 7: Die elektron -app

Oorsig

Ons sal 'n eenvoudige elektroniese app skep wat die PhotoSphere -element net posisioneer en laai. Die main.js- en package.json -lêers kom direk vanaf die Electron -webwerf, en die HTML is 'n effens aangepaste weergawe van die HTML wat op die PhotoSphere -webwerf verskyn. Ek het die lêers ingesluit, maar alles hernoem na.txt, aangesien Instructables hierdie lêertipes nie toelaat nie. Om die lêers te gebruik, hernoem dit met die toepaslike uitbreiding.

Die kode

main.js

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

funksie createWindow () {const win = nuwe BrowserWindow ({width: 800, height: 600, webPreferences: {nodeIntegration: true}}) win.loadFile ('index.html')} app.whenReady (). dan (createWindow) app.on ('window-all-closed', () => {if (process.platform! == 'darwin') {app.quit ()}}) app.on ('activeer', () => {if (BrowserWindow.getAllWindows (). length === 0) {createWindow ()}})

package.json

{

"name": "spasie", "weergawe": "0.1.0", "main": "main.js", "scripts": {"start": "elektron." }}

indeks.html

Stap 8: Uitvoering

Die skep van 'n gelykhoekige beeld

Om die prentjie te skep, voer die api.py -script uit in die opdragprompt, met die virtuele omgewing geaktiveer:

api.py

Nadat die skrifte klaar is met uitvoer, voer die elektron -app uit met:

npm beginVoila! U planetarium is aktief! Dankie vir die lees:)

Aanbeveel: