Kazalo:
2025 Avtor: John Day | [email protected]. Nazadnje spremenjeno: 2025-01-23 15:08
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
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:
Kako narediti lasten prehod WIFI za povezavo vašega Arduina z omrežjem IP?: 11 korakov (s slikami)
Kako narediti svoj lasten prehod WIFI, da povežete svoj Arduino z IP omrežjem?: Kot mnogi ljudje menite, da je Arduino zelo dobra rešitev za domačo avtomatizacijo in robotizacijo! Toda v smislu komunikacije Arduinos ima samo serijske povezave. Delam na robotu, ki ga je treba trajno povezati s strežnikom, ki deluje
Nadgradite lonec za samostojno zalivanje z brezžičnim omrežjem DIY za zaznavanje gibanja domačega alarma Sadilnik: 17 korakov
Nadgradite lonec za samopolivanje z brezžičnim omrežjem DIY v alarmno napravo za zaznavanje gibanja V tem članku vam bomo pokazali, kako nadgradite svoj lonec za samostojno zalivanje z brezžičnim omrežjem DIY v lonec za samostojno zalivanje z WiFi in alarmom za odkrivanje gibanja. niste prebrali članka o tem, kako zgraditi lonček za samostojno zalivanje z WiFi z lastnimi rokami, lahko plačate
Magnetni geodetski planetarij: 7 korakov (s slikami)
Magnetni geodetski planetarij: Pozdravljeni vsi! Rad bi vas popeljal skozi moj postopek ustvarjanja geodetskega planetarija, držanega z magneti in izdelavo žice! Razlog za uporabo teh magnetov je enostavnost odstranjevanja v času dežja ali manj kot idealne vremenske razmere. Na ta način
Povežite svoj brezglavni Pi z omrežjem WiFi v knjižnici: 7 korakov
Povežite svoj brezglavni Pi z omrežjem WiFi v knjižnici: Kolikokrat ste že želeli delati na svojih brezglavih projektih Raspberry Pi v lokalni knjižnici, le da ste se obtičali, ker odprto omrežje WiFi potrebuje brskalnik? Ne skrbite več, ta Instructable je tu, da vam pomaga! Mi bomo
Planetarij/Orrery z omogočeno povezavo Bluetooth: 13 korakov (s slikami)
Planetarij/Orrery z omogočeno povezavo Bluetooth: Ta navodila so bila ustvarjena v skladu s projektnimi zahtevami Makecourseja na Univerzi v Južni Floridi (www.makecourse.com). To je moj planetarij/plovilo s tremi planeti. Začelo se je le kot semestrski projekt za Makecour