Obsah:

Planetárium poháněné neuronovou sítí využívající Python, Electron a Keras: 8 kroků
Planetárium poháněné neuronovou sítí využívající Python, Electron a Keras: 8 kroků

Video: Planetárium poháněné neuronovou sítí využívající Python, Electron a Keras: 8 kroků

Video: Planetárium poháněné neuronovou sítí využívající Python, Electron a Keras: 8 kroků
Video: Prokop Hapala, Jak stavět stroje z molekul? 2024, Červenec
Anonim
Planetárium poháněné neuronovou sítí využívající Python, Electron a Keras
Planetárium poháněné neuronovou sítí využívající Python, Electron a Keras

V tomto pokynu vám ukážu, jak jsem napsal automatický generátor 3D planetária pomocí Pythonu a Electronu

Video výše ukazuje jedno z náhodných planetárií, které program vygeneroval.

** Poznámka: Tento program není nijak dokonalý a na některých místech ani příliš pythonický. Diskriminátor neurální sítě je přesný pouze ~ 89%, takže některé podivné obrázky se dostanou do planetária **

Specifika

Planetárium vyhledává v NASA API snímky související s vesmírem a využívá konvoluční neuronovou síť k určení, zda je snímek vhodný ke zpracování. Program poté pomocí OpenCV odstraní pozadí z obrázku a nakonec jsou obrázky spojeny dohromady v jeden velký ekvirektangulární obrázek. Tento obrázek se poté uloží a aplikace Electron Node.js obrázek otevře a pomocí balíčku PhotoSphere.js si obrázek prohlédne ve formátu 3D ve stylu planetária.

Závislosti

Krajta:

  • Keras
  • Polštář
  • cv2
  • Numpy
  • Žádosti
  • urllib
  • Náhodný
  • čas
  • io

Elektron:

Fotosféra

Krok 1: Nastavení prostředí

Instalace Electronu a Pythonu

Nejprve se ujistěte, že máte nainstalované node.js a npm (pokud ne, můžete si je stáhnout zde)

Dále musíte nainstalovat Electron. Otevřete příkazový řádek a zadejte následující příkaz:

npm nainstalovat elektron -g

Dále potřebujete python, který lze stáhnout zde

Nastavení virtuálního prostředí

Otevřete příkazový řádek a poté zadejte následující příkazy k nastavení virtuálního prostředí:

pip install virtualenv

virtuální prostor

cd prostor

skripty / aktivovat

Instalace závislostí Pythonu

Spuštěním těchto příkazů na příkazovém řádku nainstalujete závislosti pythonu:

pip install keras

pip install polštář

pip install numpy

požadavky na instalaci pipu

pip install opencv-pythonPokud chcete síť trénovat sami, nezapomeňte nastavit pro GPRS akceleraci GPU

Krok 2: Dotaz na API pro vyhledávání NASA

Přehled

NASA má spoustu opravdu užitečných API, která můžete použít se svými projekty. Pro tento projekt použijeme vyhledávací API, které nám umožňuje prohledávat snímky související s vesmírem v databázi obrázků NASA.

Kód

Nejprve musíme definovat funkci pythonu, aby přijala argument, který bude fungovat jako hledaný výraz:

def get_image_search (fráze):

složit

Dále zkonvertujeme hledaný výraz do formátu URL a poté použijeme knihovnu požadavků k dotazování na API:

def get_image_search (fráze):

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

Nakonec dekódujeme řetězec kolekce+JSON, který nám API vrátilo, a extrahujeme seznam odkazů na obrázky související s hledaným výrazem:

def get_image_search (fráze):

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

Tam jedeme! Nyní máme úryvek kódu, který lze dotazovat na API pro vyhledávání obrázků NASA a vrátit seznam odkazů na obrázky související s naším hledaným výrazem.

Krok 3: Konvoluční neuronová síť

Přehled

Úkolem neuronové sítě je klasifikovat, zda obraz je něčím ve vesmíru, nebo zda není. K tomu použijeme konvoluční neuronovou síť nebo CNN k provedení řady maticových operací s obrazem a určení, jak velký je prostor-y. Nebudu to všechno vysvětlovat, protože je za tím spousta teorie, ale pokud se chcete dozvědět něco o neurálních sítích, navrhuji „Machine Learning Mastery“

Kód

Nejprve musíme importovat naše závislosti:

import os

#Opravit problém během vlaku při nástupu na GPU os.environ ['CUDA_VISIBLE_DEVICES'] = '' importovat tensorflow jako tf if tf.test.gpu_device_name (): print ('GPU found') else: print ("No GPU found") z keras.preprocessing.image import ImageDataGenerator z 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 jako np

Dále musíme definovat náš 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 = (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 (Aktivace ('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 = ['přesnost'])

Vycvičil jsem pro vás model, ale pokud byste chtěli trénovat model sami, na vlastní datové sadě, pak jsem připojil tréninkový kód. V opačném případě si můžete stáhnout soubor HDF5 natrénovaného modelu. Kvůli omezením souboru Instructables jsem jej musel přejmenovat pomocí přípony „.txt“. Chcete -li jej použít, přejmenujte soubor na příponu „.h5“a načtěte jej pomocí tohoto kódu:

model.load_weights ("model_saved.h5")

Abychom pomocí sítě mohli předpovědět, jak velký je obrázek, definujeme tuto funkci:

def předpovědět (image_path):

img = image.load_img (cesta_obrazu, cílová_ velikost = (1000, 500)) img = np.expand_dims (img, axis = 0) result = model.predict_classes (img) návratový výsledek [0] [0]

Krok 4: Zpracování obrázku

Přehled

Pro zpracování obrazu používám knihovnu OpenCV (cv2). Nejprve rozostříme okraje obrázku a poté odstraníme pozadí vytvořením masky a změnou hodnot alfa tmavších barev.

Kód

Toto je část funkce, která rozmazává okraje:

def processImage (img):

RADIUS = 20 # Otevřít obrázek im = Image.open ("pilbuffer.png") # Vložit obrázek na bílém pozadí diam = 2 * RADIUS zpět = 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) maska. paste (blck, (diam, diam)) # Rozostření obrázku a vložení rozmazaného okraje podle masky blur = back.filter (ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (blur, mask = mask) back.save (" transition-p.webp

Dále nastavíme tmavší barvy na průhledné a dočasně uložíme obrázek:

#Vytvořit masku a filtr nahradit černé alfa

image = cv2.imread ("transition.png") hMin = 0 sMin = 0 vMin = 20 hMax = 180 sMax = 255 vMax = 255 nižší = np.array ([hMin, sMin, vMin]) horní = np.array ([hMax, sMax, vMax]) hsv = cv2.cvtColor (obrázek, cv2. COLOR_BGR2HSV) maska = cv2.inRange (hsv, dolní, horní) výstup = cv2.bitwise_and (obrázek, obrázek, maska = maska) *_, alfa = cv2.split (výstup) dst = cv2.merge ((výstup, alfa)) výstup = dst s otevřeným ("buffer.png", "w+") jako soubor: předejte cv2.imwrite ("buffer.png", výstup)

Krok 5: Spojení obrazů dohromady do ekvirektangulární projekce

Přehled

Tato funkce pořídí více obrázků a spojí je do formátu, který lze interpretovat pomocí balíčku PhotoSphere.js pomocí knihovny PIL (polštář)

Kód

Nejprve musíme vytvořit obrázek, který může fungovat jako hostitel pro ostatní obrázky:

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

Dále musíme iterovat prostřednictvím řady obrázků (u všech bylo změněno rozlišení na 1000 x 500) a umístit je do obrázku:

h = 0

w = 0 i = 0 pro img v img_arr: new.paste (img, (w, h), img) w += 1000 if w == 8000: h += 500 w = 0 i += 1

Nyní to zabalíme do funkce, která jako argument vezme řadu obrázků a vrátí nový obrázek:

def stitch_beta (img_arr):

new = Image.new ("RGBA", (8000, 4000), color = (0, 0, 0)) h = 0 w = 0 i = 0 pro img in img_arr: new.paste (img, (w, h), img) w += 1000 pokud w == 8000: h += 500 w = 0 i += 1 vrátit nový

Krok 6: Úplný skript Pythonu

Toto je úplný skript neuronové sítě python, který je uložen jako net.py a importován do hlavního skriptu:

# import knihoven

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 ") 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, 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 == if_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 (Aktivace ('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 (Hustý (1)) model.add (Aktivace ('sigmoid')) model.compile (ztráta = 'binary_crossentropy', optimizer = 'rmsprop', metrics = ['přesnost']) model.load_weights ("model_saved.h5") def předpovědět (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]

Toto je hlavní soubor pythonu, api.py:

import požadavků, sys, random, urllib.parse, cv2

z PIL import Image, ImageFilter z io import BytesIO import numpy jako np import net def get_image_search (num, fráze): count = 0 img_arr = pro arg ve frázi: print (arg) print (f "Aktuální počet obrázků: {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'] pro výsledek in results.json () [" collection "] [" items "] print (len (data)) if num> len (data): num = len (data) při počítání = 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 pro img v img_arr: #pbar.set_description (f "Processing image {i +1}") new.paste (img, (w, h), img) w += 1000 if w == 8000: h += 500 w = 0 i += 1 vrátit nový proces defImage (obrázek): RADIUS = 20 # Otevřít obrázek im = Image.open ("pilbuffer.png") # Vložit obrázek na bílé pozadí průměr = 2 * RADIUS zpět = Image.new ('RGB', (im.size [0] + diam, im.size [1] + diam), (0, 0, 0)) back.paste (im, (RADIUS (RADIUS)) # Vytvořte masku masky rozostření = Image.new ('L', (velikost obrázku [0] + průměr, velikost velikosti [1] + průměr), 255) blck = Image.new ('L', (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 nižší = np.array ([hMin, sMin, vMin]) horní = np.array ([hMax, sMax, vMax]) hsv = cv2.cvtColor (obrázek, cv2. COLOR_BGR2HSV) maska = cv2.inRange (hsv, dolní, horní) výstup = cv2.bitwise_and (obrázek, obrázek, maska = maska) *_, alfa = cv2.split (výstup) dst = cv2.merge ((výstup, alfa)) výstup = dst s otevřeným ("buffer.png", "w+") jako soubor: předejte cv2.imwrite ("buffer.png", výstup) #Edge detekce a rozmazání, pokud _name_ == "_main_": search_terms = ["supernova", "planeta", "galaxie", "mléčná dráha", "mlhovina", "hvězdy"] #Hledané výrazy lze změnit na cokoli, co má planetárium obsahovat img_arr = get_image_search (64, search_terms) tisk ("Obrázky načteny a nervově filtrovány") img = stitch_beta (img_arr) tisk ("Obrázky spojeny") img.save ("stitched.png")

Krok 7: Aplikace Electron

Přehled

Vytvoříme jednoduchou elektronovou aplikaci, která pouze umístí a načte prvek PhotoSphere. Soubory main.js a package.json jsou přímo z webu Electron a HTML je mírně upravenou verzí HTML, která je k dispozici na webu PhotoSphere. Zahrnul jsem soubory, ale přejmenoval vše na.txt, protože Instructables tyto typy souborů nepovoluje. Chcete -li soubory použít, přejmenujte je s příslušnou příponou.

Kód

main.js

const {aplikace, BrowserWindow} = vyžadovat ('elektron')

funkce createWindow () {const win = new BrowserWindow ({šířka: 800, výška: 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 ()}})

balíček.json

{

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

index.html

Krok 8: Provedení

Vytvoření ekvirektangulárního obrázku

Chcete -li vytvořit bitovou kopii, spusťte na příkazovém řádku skript api.py s aktivovaným virtuálním prostředím:

api.py

Po dokončení spouštění skriptů spusťte elektronovou aplikaci pomocí:

npm startVoila! Vaše planetárium je aktivní! Děkuji za přečtení:)

Doporučuje: