Innholdsfortegnelse:

Neuralt nettverk drevet planetarium ved hjelp av Python, Electron og Keras: 8 trinn
Neuralt nettverk drevet planetarium ved hjelp av Python, Electron og Keras: 8 trinn

Video: Neuralt nettverk drevet planetarium ved hjelp av Python, Electron og Keras: 8 trinn

Video: Neuralt nettverk drevet planetarium ved hjelp av Python, Electron og Keras: 8 trinn
Video: Международный аэропорт Ханэда всегда будет в курсе потребностей наших клиентов. 🇷🇺 2024, November
Anonim
Neuralt nettverk drevet planetarium ved hjelp av Python, Electron og Keras
Neuralt nettverk drevet planetarium ved hjelp av Python, Electron og Keras

I denne instruksen vil jeg vise deg hvordan jeg skrev en automatisk 3D planetariumgenerator ved hjelp av Python og Electron

Videoen ovenfor viser et av de tilfeldige planetariene som programmet genererte.

** Merk: Dette programmet er på ingen måte perfekt, og noen steder ikke veldig pytonisk. Den nevrale nettdiskriminatoren er bare ~ 89% nøyaktig, så noen merkelige bilder vil gjøre det til planetariet **

Spesifikasjoner

Planetariet spør en NASA API for romrelaterte bilder, og bruker et konvolusjonelt nevralnettverk for å avgjøre om bildet er egnet for behandling. Programmet bruker deretter OpenCV til å fjerne bakgrunnen fra bildet, og til slutt blir bildene sydd sammen til ett stort ekvectangulært bilde. Dette bildet blir deretter lagret, og en Electron Node.js -applikasjon åpner bildet, og bruker PhotoSphere.js -pakken til å se bildet i et 3D -format i planetariumstil.

Avhengigheter

Python:

  • Keras
  • Pute
  • cv2
  • Klumpete
  • Forespørsler
  • urllib
  • Tilfeldig
  • tid
  • io

Elektron:

PhotoSphere

Trinn 1: Konfigurere miljøet

Installere elektron og python

Kontroller først at du har node.js og npm installert (hvis ikke, kan du laste ned her)

Deretter må du installere Electron. Åpne en ledetekst, og skriv inn følgende kommando:

npm installer elektron -g

Deretter trenger du python, som kan lastes ned her

Sette opp et virtuelt miljø

Åpne en ledetekst, og skriv deretter inn følgende kommandoer for å konfigurere det virtuelle miljøet ditt:

pip installere virtualenv

virtualenv plass

cd -plass

skript / aktivere

Installere Python -avhengigheter

Kjør disse kommandoene i ledeteksten for å installere python -avhengighetene dine:

pip install keras

pip installer pute

pip installer numpy

pip installasjonsforespørsler

pip installer opencv-pythonHvis du vil trene nettverket selv, må du sette opp GPU -akselerasjon for Keras

Trinn 2: Spør etter NASA Search API

Oversikt

NASA har mange veldig nyttige APIer som du kan bruke med prosjektene dine. For dette prosjektet bruker vi søke-API, som lar oss søke i NASAs bildedatabase etter plassrelaterte bilder.

Koden

Først må vi definere en python -funksjon for å godta et argument som vil fungere som søkeord:

def get_image_search (setning):

sende

Deretter konverterer vi søkeordet til URL -format, og bruker deretter forespørselsbiblioteket til å spørre API:

def get_image_search (setning):

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

Til slutt vil vi dekode samlingen+JSON -strengen som API -en returnerte til oss, og trekke ut en liste med lenker til bilder relatert til søkeordet:

def get_image_search (setning):

params = {"q": urllib.parse.quote (arg), "media_type": "image"} results = requests.get ("https://images-api.nasa.gov/search", params = params) data = [resultat ['href'] for resultat i results.json () ["samling"] ["varer"]

Der går vi! Vi har nå en kodebit som kan søke etter NASA bildesøk -API, og returnere en liste med lenker til bilder relatert til søkeordet vårt.

Trinn 3: Det konvolusjonelle nevrale nettverket

Oversikt

Jobben til det nevrale nettverket er å klassifisere om et bilde er av noe i verdensrommet, eller om det ikke er det. For å gjøre dette, vil vi bruke et konvolusjonelt nevralnettverk, eller CNN, til å utføre en serie matriseoperasjoner på bildet, og bestemme hvor mellomrom-y det er. Jeg vil ikke forklare alt dette, fordi det er mye teori bak, men hvis du vil lære om nevrale nettverk, foreslår jeg "Machine Learning Mastery"

Koden

Først må vi importere våre avhengigheter:

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") fra keras.preprocessing.image import ImageDataGenerator fra keras.preprocessing import image from keras.models import Sequential fra keras.layers import Conv2D, MaxPooling2D fra keras.layers import Activation, Dropout, Flatten, Tett fra keras import backend som K fra PIL import Image importer numpy som np

Deretter må vi definere modellen vår:

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 = (3, im_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 (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. legg til (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'])

Jeg har trent modellen for deg, men hvis du vil trene modellen selv, på ditt eget datasett, så har jeg lagt ved treningskoden. Ellers kan du laste ned den opplærte modellens HDF5 -fil. På grunn av Instructables -filbegrensninger, har jeg måttet gi nytt navn til den med en ".txt" -tillegg. For å bruke den, gi filen nytt navn til en ".h5" -utvidelse og laste den med denne koden:

model.load_weights ("model_saved.h5")

For å bruke nettverket til å forutsi hvor mellomrom-y et bilde er, vil vi definere denne funksjonen:

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) return result [0] [0]

Trinn 4: Behandle bildet

Oversikt

For bildebehandling bruker jeg OpenCV (cv2) biblioteket. Først vil vi uskarpe kantene på bildet, og deretter vil vi fjerne bakgrunnen ved å lage en maske og endre alfa -verdiene til de mørkere fargene

Koden

Dette er den delen av funksjonen som slører kantene:

def processImage (img):

RADIUS = 20 # Åpne et bilde im = Image.open ("pilbuffer.png") # Lim inn bilde på hvit bakgrunn diam = 2 * RADIUS back = Image.new ('RGB', (im.size [0] + diam, im.size [1] + diam), (0, 0, 0)) back.paste (im, (RADIUS, RADIUS)) # Lag uskarphetsmaske = 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) maske. lim inn (blck, (diam, diam)) # Slør bilde og lim ut uskarpt kant i henhold til maske uskarphet = tilbake.filter (ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (uskarphet, maske = maske) tilbake.save (" transition-p.webp

Deretter vil vi sette de mørkere fargene til gjennomsiktig, og lagre bildet midlertidig:

#Lag maske og filter erstatt svart med alfa

image = cv2.imread ("transition.png") hMin = 0 sMin = 0 vMin = 20 hMax = 180 sMax = 255 vMax = 255 lavere = np.array ([hMin, sMin, vMin]) øvre = np.array ([hMax, sMax, vMax]) hsv = cv2.cvtColor (image, cv2. COLOR_BGR2HSV) mask = cv2.inRange (hsv, nedre, øvre) output = cv2.bitwise_and (bilde, bilde, maske = maske) *_, alfa = cv2.split (output) dst = cv2.merge ((output, alpha)) output = dst with open ("buffer.png", "w+") as file: pass cv2.imwrite ("buffer.png", output)

Trinn 5: Sy sammen bilder i en ekvivalentvinklet projeksjon

Oversikt

Denne funksjonen tar flere bilder og syr dem til et format som kan tolkes av PhotoSphere.js -pakken ved hjelp av PIL (pute) bibliotek

Koden

Først må vi lage et bilde som kan fungere som vert for de andre bildene:

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

Deretter må vi iterere gjennom en rekke bilder (som alle er endret til 1000x500) og plassere dem i bildet:

h = 0

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

Nå pakker vi dette inn i en funksjon som tar en rekke bilder som argument, og returnerer det nye bildet:

def stitch_beta (img_arr):

new = Image.new ("RGBA", (8000, 4000), color = (0, 0, 0)) h = 0 w = 0 i = 0 for img i img_arr: new.paste (img, (w, h), img) w += 1000 hvis w == 8000: h += 500 w = 0 i += 1 retur ny

Trinn 6: Full Python Script

Dette er hele python -nevrale nettverksskriptet, som lagres som net.py og importeres til hovedskriptet:

# importerer biblioteker

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 ("Ingen GPU funnet ") fra keras.preprocessing.image import ImageDataGenerator fra keras.preprocessing import image from keras.models import Sequential fra keras.layers import Conv2D, MaxPooling2D fra keras.layers import Activation, Dropout, Flatten, Tett fra keras import backend som K fra 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 (Activation ('relu')) model.add (MaxPooling2D (pool_size = (2, 2)))) model.add (Conv2D (32, (2, 2)))) modell. legg til (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 = ['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) returresultat [0] [0]

Dette er den viktigste python -filen, api.py:

importforespørsler, sys, random, urllib.parse, cv2

fra PIL import Image, ImageFilter fra io import BytesIO import numpy som np import net def get_image_search (num, frase): count = 0 img_arr = for arg i setning: print (arg) print (f "Gjeldende bildetall: {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 resultat i results.json () [" collection "] [" items "] print (len (data)) if num> len (data): num = len (data) mens tellingen = num: break print (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 for img i img_arr: #pbar.set_description (f "Behandler bilde {i +1}") new.paste (img, (w, h), img) w += 1000 if w == 8000: h += 500 w = 0 i += 1 returnerer ny def -prosess Bilde (bilde): RADIUS = 20 # Åpne et bilde im = Image.open ("pilbuffer.png") # Lim inn bilde på hvit bakgrunn diam = 2 * RADIUS tilbake = Image.new ('RGB', (im.size [0] + diam, im.size [1] + diam), (0, 0, 0)) back.paste (im, (RADIUS, RADIUS)) # Lag uklarhetsmaske = 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)) # Slør bilde og lim ut uskarpt kant i henhold til maske uskarphet = bakside. ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (blur, mask = mask) back.save ("transition.png") back.close () #Lag maske og filter erstatt svart med alfa image = cv2.imread (" gjennomreise ion.png ") hMin = 0 sMin = 0 vMin = 20 hMax = 180 sMax = 255 vMax = 255 lavere = np.array ([hMin, sMin, vMin]) øvre = np.array ([hMax, sMax, vMax]) hsv = cv2.cvtColor (image, cv2. COLOR_BGR2HSV) mask = cv2.inRange (hsv, nedre, øvre) utgang = cv2.bitwise_and (bilde, bilde, maske = maske) *_, alfa = cv2.split (output) dst = cv2.merge ((output, alpha)) output = dst with open ("buffer.png", "w+") as file: pass cv2.imwrite ("buffer.png", output) #Edge detection and uskarphet hvis _name_ == "_main_": search_terms = ["supernova", "planet", "galaxy", "milky way", "nebula", "stars"] #Søkeordene kan endres til det du vil at planetariet skal inkludere img_arr = get_image_search (64, search_terms) print ("Bilder hentet og nevralfiltrert") img = stitch_beta (img_arr) print ("Images stitched") img.save ("stitched.png")

Trinn 7: Elektron -appen

Oversikt

Vi skal lage en enkel elektronapp som bare plasserer og laster PhotoSphere -elementet. Main.js- og package.json -filene er rett fra Electrons nettsted, og HTML -koden er en litt modifisert versjon av HTML -koden på PhotoSphere -nettstedet. Jeg har tatt med filene, men gitt nytt navn til.txt, ettersom Instructables ikke tillater disse filtypene. For å bruke filene, gi dem nytt navn med den riktige utvidelsen.

Koden

main.js

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

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

package.json

{

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

index.html

Trinn 8: Utførelse

Opprette det ekvectangulære bildet

For å lage bildet, kjør api.py -skriptet i ledeteksten, med det virtuelle miljøet aktivert:

api.py

Etter at skriptene er ferdig med å kjøre, kjører du elektronappen ved å bruke:

npm startVoila! Planetariet ditt er aktivt! Takk for at du leste:)

Anbefalt: