Neuroninio tinklo planetarijus naudojant „Python“, „Electron“ir „Keras“: 8 žingsniai
Neuroninio tinklo planetarijus naudojant „Python“, „Electron“ir „Keras“: 8 žingsniai
Anonim
Neuroninio tinklo planetarijus naudojant „Python“, „Electron“ir „Keras“
Neuroninio tinklo planetarijus naudojant „Python“, „Electron“ir „Keras“

Šioje pamokoje aš jums parodysiu, kaip parašiau automatinį 3D planetariumo generatorių, naudodamas „Python“ir „Electron“

Aukščiau esančiame vaizdo įraše rodomas vienas iš atsitiktinių planetariumų, kuriuos sukūrė programa.

** Pastaba: ši programa jokiu būdu nėra tobula ir kai kuriose vietose nėra labai pitoniška. Neuronų tinklo diskriminatorius yra tik ~ 89% tikslus, todėl į planetariumą pateks keletas nelyginių vaizdų **

Specifika

Planetariumas užklausia NASA API su kosmosu susijusių vaizdų ir naudoja konvoliucinį nervų tinklą, kad nustatytų, ar vaizdas tinkamas apdoroti. Tada programa naudoja „OpenCV“, kad pašalintų vaizdo foną, ir galiausiai vaizdai sujungiami į vieną didelį lygiakampį vaizdą. Tada šis vaizdas išsaugomas, o programa „Electron Node.js“atidaro vaizdą ir naudoja „PhotoSphere.js“paketą, kad peržiūrėtų vaizdą planetariumo stiliaus 3D formatu.

Priklausomybės

Python:

  • Keras
  • Pagalvė
  • cv2
  • Kvaila
  • Prašymai
  • urllib
  • Atsitiktinis
  • laikas
  • io

Elektronas:

„PhotoSphere“

1 žingsnis: nustatykite aplinką

„Electron“ir „Python“diegimas

Pirmiausia įsitikinkite, kad įdiegėte node.js ir npm (jei ne, galite atsisiųsti čia)

Toliau turite įdiegti „Electron“. Atidarykite komandų eilutę ir įveskite šią komandą:

npm įdiegti elektroną -g

Tada jums reikia „python“, kurį galite atsisiųsti čia

Virtualios aplinkos nustatymas

Atidarykite komandų eilutę, tada įveskite šias komandas, kad nustatytumėte savo virtualią aplinką:

pip install virtualenv

virtualenv erdvė

cd erdvė

scenarijai / suaktyvinti

Python priklausomybių diegimas

Vykdykite šias komandas komandų eilutėje, kad įdiegtumėte „Python“priklausomybes:

pip įdiegti keras

pip įdiegti pagalvę

pip install numpy

pip diegimo užklausos

pip įdiegti opencv-pythonJei norite patys mokyti tinklą, būtinai nustatykite „Keras“GPU pagreitį

2 veiksmas: užklausa apie NASA paieškos API

Apžvalga

NASA turi daug tikrai naudingų API, kurias galite naudoti savo projektuose. Šiam projektui naudosime paieškos API, leidžiančią ieškoti NASA vaizdų duomenų bazėje su kosmosu susijusių vaizdų.

Kodas

Pirmiausia turime apibrėžti „python“funkciją, kad galėtume priimti argumentą, kuris veiks kaip paieškos terminas:

def get_image_search (frazė):

praeiti

Tada paieškos terminą paversime URL formatu, tada naudosime užklausų biblioteką, norėdami pateikti užklausą API:

def get_image_search (frazė):

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

Galiausiai iššifruosime kolekciją+JSON eilutę, kurią mums grąžino API, ir išskleisime nuorodų į vaizdus, susijusius su paieškos terminu, sąrašą:

def get_image_search (frazė):

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

Štai ir einam! Dabar turime kodo fragmentą, kuris gali pateikti užklausą NASA vaizdų paieškos API ir grąžinti nuorodų į vaizdus, susijusius su mūsų paieškos terminu, sąrašą.

3 žingsnis: Konvoliucinis nervų tinklas

Apžvalga

Neuroninio tinklo užduotis yra klasifikuoti, ar vaizdas yra kažkas erdvėje, ar ne. Norėdami tai padaryti, mes naudosime konvoliucinį nervų tinklą arba CNN, kad atliktume matricos operacijų seriją su vaizdu ir nustatytume, kokia ji yra erdvė. Viso to nepaaiškinsiu, nes už jos slypi daug teorijų, bet jei norite sužinoti apie neuroninius tinklus, siūlau „Mašinų mokymosi meistriškumą“

Kodas

Pirma, turime importuoti savo priklausomybes:

importuoti

#Fix problemai traukinio žingsnio metu GPU os.environ ['CUDA_VISIBLE_DEVICES'] = '' importuoti tensorflow kaip tf, jei tf.test.gpu_device_name (): print ('GPU found') else: print ("GPU nerastas") iš keras.preprocessing.image importuoti ImageDataGenerator iš keras.preprocessing importuoti vaizdą iš keras.models importuoti Iš eilės iš keras.layers importuoti Conv2D, MaxPooling2D iš keras.layers importuoti Aktyvinimas, iškritimas, išlyginimas, tankus iš keras importo užpakalinės dalies kaip K iš PIL importo vaizdo importuoti numpy kaip np

Toliau turime apibrėžti savo modelį:

img_width, img_height = 1000, 500

train_data_dir = 'v_data/traukinys' validation_data_dir = 'v_data/test' nb_train_samples = 203 nb_validation_samples = 203 epochos = 10 batch_size = 8, jei K.image_data_format () == 'channels_first': input_shap_ = = (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 ()) modelis. pridėti (tankus (64)) model.add (aktyvinimas („relu“)) model.add (iškritimas (0,5)) model.add (tankus (1)) model.add (aktyvinimas („sigmoid“)) model.compile (nuostolis = 'binary_crossentropy', optimizatorius = 'rmsprop', metrika = ['tikslumas'])

Aš paruošiau modelį jums, bet jei norėtumėte mokyti modelį patys, naudodamiesi savo duomenų rinkiniu, pridėjau mokymo kodą. Priešingu atveju galite atsisiųsti apmokyto modelio HDF5 failą. Dėl „Instructables“failų apribojimų turėjau jį pervadinti „.txt“plėtiniu. Norėdami jį naudoti, pervardykite failą į plėtinį „.h5“ir įkelkite jį naudodami šį kodą:

model.load_weights ("model_saved.h5")

Norėdami naudoti tinklą, kad nuspręstumėte, kokia erdvė yra vaizdas, apibrėžsime šią funkciją:

def prognozuoti (vaizdo_ kelias):

img = image.load_img (image_path, target_size = (1000, 500)) img = np.expand_dims (img, axis = 0) result = model.predict_classes (img) grąžinimo rezultatas [0] [0]

4 žingsnis: vaizdo apdorojimas

Apžvalga

Vaizdų apdorojimui naudoju „OpenCV“(cv2) biblioteką. Pirmiausia neryškinsime vaizdo kraštus, o tada pašalinsime foną, sukurdami kaukę ir pakeisdami tamsesnių spalvų alfa reikšmes

Kodas

Tai yra funkcijos dalis, kuri sulieja kraštus:

def processImage (img):

RADIUS = 20 # Atidaryti vaizdą im = Image.open ("pilbuffer.png") # Įklijuoti vaizdą baltame fone im.size [1] + diam), (0, 0, 0)) back.paste (im, (RADIUS, RADIUS)) # Sukurti 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) kaukė. įklijuoti (blck, (diam, diam)) # Sulieti vaizdą ir įklijuoti neryškų kraštą pagal kaukės suliejimą = back.filter (ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (suliejimas, kaukė = kaukė) back.save (" transfer-p.webp

Tada mes nustatysime tamsesnes spalvas į skaidrias ir laikinai išsaugosime vaizdą:

#Sukurkite kaukę ir filtrą juodą pakeiskite alfa

image = cv2.imread ("perėjimas.png") hMin = 0 sMin = 0 vMin = 20 hMax = 180 sMax = 255 vMax = 255 mažesnis = np.masyvas ([hMin, sMin, vMin]) viršutinė = np.array ([hMax, sMax, vMax]) hsv = cv2.cvtColor (vaizdas, cv2. COLOR_BGR2HSV) kaukė = cv2.inRange (hsv, apatinė, viršutinė) išvestis = cv2.bitwise_and (vaizdas, vaizdas, kaukė = kaukė) *_, alfa = cv2.split (išvestis) dst = cv2.merge ((išvestis, alfa)) išvestis = dst su atidarytu ("buffer.png", "w+") kaip failas: perduoti cv2.imwrite ("buffer.png", išvestis)

5 žingsnis: vaizdų sujungimas į stačiakampę projekciją

Apžvalga

Ši funkcija naudoja kelis vaizdus ir sujungia juos į formatą, kurį gali suprasti „PhotoSphere.js“paketas, naudojant PIL (pagalvės) biblioteką

Kodas

Pirma, turime sukurti vaizdą, kuris galėtų veikti kaip kitų vaizdų šeimininkas:

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

Toliau turime pakartoti vaizdų masyvą (kurių visų dydis pakeistas iki 1000 x 500) ir įdėti juos į vaizdą:

h = 0

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

Dabar mes tiesiog užbaigiame tai funkcija, kurios argumentas yra vaizdų masyvas, ir pateikiamas naujas vaizdas:

def stitch_beta (img_arr):

new = Image.new ("RGBA", (8000, 4000), spalva = (0, 0, 0)) h = 0 w = 0 i = 0 img_arr: new.paste (img, (w, h), img) w += 1000, jei w == 8000: h += 500 w = 0 i += 1 grąžinti naują

6 veiksmas: visas „Python“scenarijus

Tai yra visas „Python“neuronų tinklo scenarijus, kuris išsaugomas kaip net.py ir importuojamas į pagrindinį scenarijų:

# importuojančios bibliotekos

importuoti os #Fix problemai traukinio žingsnio metu GPU os.environ ['CUDA_VISIBLE_DEVICES'] = '' importuoti tensorflow kaip tf, jei tf.test.gpu_device_name (): print ('GPU rasta') else: print ("GPU nerastas ") iš keras.preprocessing.image importuoti ImageDataGenerator iš keras.preprocessing importuoti vaizdą iš keras.models importuoti Sequential iš keras.layers importuoja Conv2D, MaxPooling2D iš keras.layers importuoja aktyvinimą, iškritimą, išlyginimą, tankų iš keras importuoja backend kaip K iš PIL importuoti paveikslėlio importo skaičių kaip 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 (Aktyvinimas ('relu')] model.add (MaxPooling2D (pool_size = (2, 2)))) model.add (Conv2D (32, (2, 2)))) modelis. add (Aktyvinimas ('relu')] model.add (MaxPooling2D (pool_size = (2, 2)))) model.add (Conv2D (64, (2, 2)))) model.add (Aktyvinimas ('relu')) model.add (MaxPooling2D (pool_size = (2, 2))) model.add (Flatten ()) model.add (Tankus (64)) model.add (Activation ('relu')) model.add (Dropout (0.5)) model.add (Tankus (1)) model.add (Aktyvinimas ('sigmoidas')) model.compile (nuostolis = 'binary_crossentropy', optimizatorius = 'rmsprop', metrika = ['tikslumas']) model.load_weights ("model_saved.h5") def prognozuoti (image_path): img = image.load_img (image_path, target_size = (1000, 500)) img = np.expand_dims (img, axis = 0) result = model.predict_classes (img) grąžinimo rezultatas [0] [0]

Tai yra pagrindinis „python“failas api.py:

importuoti užklausas, sys, random, urllib.parse, cv2

iš PIL importuojamo vaizdo, „ImageFilter“iš „io import BytesIO“importo numpy kaip np importo net def get_image_search (num, frazė): count = 0 img_arr = arg argumentuose frazėje: print (arg) print (f "Dabartinių vaizdų skaičius: {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 (duomenys) skaičiuojant = num: break print (f "\ n {count} vaizdai atkurti") return img_arr def stitch_beta (img_arr): new = Image.new ("RGBA", (8000, 4000), spalva = (0, 0, 0)) h = 0 w = 0 i = 0 img_arr: #pbar.set_description (f "Vaizdo apdorojimas {i +1}") new.paste (img, (w, h), img) w += 1000 if w == 8000: h += 500 w = 0 i += 1 grąžinti naują def procesą Vaizdas (img): RADIUS = 20 # Atidaryti vaizdą im = Image.open ("pilbuffer.png") # Įklijuoti vaizdą baltame fone = 2 * RADIUS atgal = Image.new ('RGB', (im.size [0] + diam, im.size [1] + diam), (0, 0, 0)) back.paste (im, (RADIUS, RADIUS)) # Sukurkite suliejimo kaukės kaukę = 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)) # Sulieti vaizdą ir įklijuoti neryškų kraštą pagal kaukės suliejimą = back.filter (ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (suliejimas, kaukė = kaukė) back.save ("pāreja.png") back.close () #Kurti kaukę ir filtrą juodą pakeisti alfa paveikslėliu = cv2.imread (" tranzitas jonas.png ") hMin = 0 sMin = 0 vMin = 20 hMax = 180 sMax = 255 vMax = 255 mažesnis = np.masyvas ([hMin, sMin, vMin]) viršutinis = np.masyvas ([hMax, sMax, vMax]) hsv = cv2.cvtColor (vaizdas, cv2. COLOR_BGR2HSV) kaukė = cv2.inRange (hsv, apatinė, viršutinė) išvestis = cv2.bitwise_and (vaizdas, vaizdas, kaukė = kaukė) *_, alfa = cv2.split (išėjimas) dst = cv2.merge ((išvestis, alfa)) išvestis = dst su atidarytu ("buffer.png", "w+") kaip failas: perduoti cv2.imwrite ("buffer.png", išvestis) #Krašto aptikimas ir suliejimas, jei _name_ == "_main_": search_terms = ["supernova", "planeta", "galaktika", "pieno kelias", "ūkas", "žvaigždės"] #Paieškos terminai gali būti pakeisti į tai, ką norite įtraukti į planetariumą img_arr = get_image_search (64, search_terms) print („Vaizdai gauti ir nervų filtrai“) img = stitch_beta (img_arr) print („Vaizdai susiūti“) img.save ("stitched.png")

7 žingsnis: „Electron“programa

Apžvalga

Mes sukursime paprastą elektronų programą, kuri tik pozicionuoja ir įkelia „PhotoSphere“elementą. „Main.js“ir „package.json“failai yra tiesiai iš „Electron“svetainės, o HTML yra šiek tiek pakeista „PhotoSphere“svetainėje pateikto HTML versija. Įtraukiau failus, bet visus pervadinau į.txt, nes „Instructables“neleidžia šių tipų failų. Norėdami naudoti failus, pervardykite juos naudodami atitinkamą plėtinį.

Kodas

main.js

const {app, BrowserWindow} = reikalauti ('elektronas')

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

package.json

{

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

index.html

8 žingsnis: vykdymas

Lygiakampio vaizdo kūrimas

Norėdami sukurti vaizdą, komandų eilutėje paleiskite api.py scenarijų, suaktyvinę virtualią aplinką:

api.py

Baigę vykdyti scenarijus, paleiskite elektroninę programą naudodami:

npm pradžiaVoila! Jūsų planetariumas aktyvus! Ačiū, kad skaitote:)

Rekomenduojamas: