Turinys:
2025 Autorius: John Day | [email protected]. Paskutinį kartą keistas: 2025-01-23 14:58
Š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
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:
Tinklo laiko skaitmeninis laikrodis naudojant ESP8266: 4 žingsniai (su paveikslėliais)
Tinklo laiko skaitmeninis laikrodis naudojant ESP8266: Mes mokomės sukurti mielą mažą skaitmeninį laikrodį, kuris bendrauja su NTP serveriais ir rodo tinklo ar interneto laiką. Mes naudojame „WeMos D1 mini“, kad prisijungtume prie „WiFi“tinklo, gautume NTP laiką ir rodytume jį OLED modulyje. Vaizdo įrašas aukščiau
Viso tinklo skelbimų blokavimas naudojant „Raspberry Pi“: 4 veiksmai
Viso tinklo skelbimų blokavimas naudojant „Raspberry Pi“: mėgaukitės švaresniu, spartesniu žiniatinkliu ir blokuokite erzinančius skelbimus visame namų tinkle naudodami „Pi-hole“ir „Raspberry Pi“
NAS (prie tinklo prijungta saugykla) naudojant „Raspberry Pi“: 6 veiksmai
NAS (prie tinklo prijungta saugykla) „Raspberry Pi“naudojimas: prie tinklo prijungta saugykla arba trumpai tariant, NAS yra tikrai geras įrenginys, jei turite daug failų ir duomenų. Kompiuterio vidiniame HDD turiu tiek daug su darbu susijusio turinio, kad jame nelieka daug vietos mano asmeniniams duomenims, todėl
„Arduino“neuroninio tinklo robotas: 21 žingsnis (su nuotraukomis)
„Arduino“neuroninio tinklo robotas: šis nurodymas yra pagrįstas 3 dalių serija, kurią sukūriau „YouTube“kanalui, kuriame tiksliai parodoma, kaip prototipuoti, kurti, surinkti ir programuoti savo „Arduino“neuroninio tinklo robotą. Peržiūrėję visą serialą, turėtumėte turėti geresnį
Ilgalaikis belaidis tinklo adapteris naudojant vandens buteliuką: 4 žingsniai (su nuotraukomis)
Ilgalaikis belaidis tinklo adapteris, naudojant vandens buteliuką: Būdamas Irake, aš naudoju vandens buteliuką savo belaidžio tinklo adapteriui. Tai paprasta procedūra, tačiau ji yra labai efektyvi. Akivaizdu, kad šis nurodymas bus naudingiausias vyrų ir moterų paslaugoms Artimuosiuose Rytuose, tačiau taip pat gali būti naudojamas