Πίνακας περιεχομένων:

Πλανητάριο με νευρωνικό δίκτυο με χρήση Python, Electron και Keras: 8 βήματα
Πλανητάριο με νευρωνικό δίκτυο με χρήση Python, Electron και Keras: 8 βήματα

Βίντεο: Πλανητάριο με νευρωνικό δίκτυο με χρήση Python, Electron και Keras: 8 βήματα

Βίντεο: Πλανητάριο με νευρωνικό δίκτυο με χρήση Python, Electron και Keras: 8 βήματα
Βίντεο: Neil deGrasse Tyson: UFOs, Φιλοσοφία της Φυσικής, Θεώρημα Chaitin 2024, Νοέμβριος
Anonim
Πλανητάριο με νευρωνικό δίκτυο που χρησιμοποιεί Python, Electron και Keras
Πλανητάριο με νευρωνικό δίκτυο που χρησιμοποιεί Python, Electron και Keras

Σε αυτό το διδακτικό, θα σας δείξω πώς έγραψα μια αυτόματη γεννήτρια πλανητάριου 3D, χρησιμοποιώντας Python και Electron

Το παραπάνω βίντεο δείχνει ένα από τα τυχαία πλανητάρια που δημιούργησε το πρόγραμμα.

** Σημείωση: Αυτό το πρόγραμμα δεν είναι σε καμία περίπτωση τέλειο και σε ορισμένα σημεία όχι πολύ πυθωνικό. Ο διαχωριστής νευρικών διχτύων είναι ακριβής μόνο ~ 89%, οπότε μερικές περίεργες εικόνες θα φτάσουν στο πλανητάριο **

Ειδικότητες

Το πλανητάριο ερωτά ένα API της NASA για εικόνες που σχετίζονται με το διάστημα και χρησιμοποιεί ένα συνελικτικό νευρωνικό δίκτυο για να καθορίσει εάν η εικόνα είναι κατάλληλη για επεξεργασία. Το πρόγραμμα στη συνέχεια χρησιμοποιεί το OpenCV για να αφαιρέσει το φόντο από την εικόνα και, τέλος, οι εικόνες συρράπτονται μαζί σε μία μεγάλη ισομεγέθη εικόνα. Αυτή η εικόνα στη συνέχεια αποθηκεύεται και μια εφαρμογή Electron Node.js ανοίγει την εικόνα και χρησιμοποιεί το πακέτο PhotoSphere.js για προβολή της εικόνας σε τρισδιάστατη μορφή πλανηταρίου.

Εξαρτήσεις

Πύθων:

  • Κεράς
  • Μαξιλάρι
  • cv2
  • Numpy
  • Αιτήσεων
  • urllib
  • Τυχαίος
  • χρόνος
  • io

Ηλεκτρόνιο:

PhotoSphere

Βήμα 1: Ρύθμιση του περιβάλλοντός σας

Εγκατάσταση Electron και Python

Αρχικά, βεβαιωθείτε ότι έχετε εγκαταστήσει τα node.js και npm (αν όχι, μπορείτε να τα κατεβάσετε εδώ)

Στη συνέχεια, πρέπει να εγκαταστήσετε το Electron. Ανοίξτε μια γραμμή εντολών και εισαγάγετε την ακόλουθη εντολή:

npm εγκατάσταση ηλεκτρονίου -g

Στη συνέχεια, χρειάζεστε python, το οποίο μπορείτε να κατεβάσετε εδώ

Δημιουργία εικονικού περιβάλλοντος

Ανοίξτε μια γραμμή εντολών και, στη συνέχεια, εισαγάγετε τις ακόλουθες εντολές για να ρυθμίσετε το εικονικό σας περιβάλλον:

pip εγκατάσταση virtualenv

virtualenv χώρος

cd space

scripts / activ

Εγκατάσταση εξαρτήσεων Python

Εκτελέστε αυτές τις εντολές στη γραμμή εντολών για να εγκαταστήσετε τις εξαρτήσεις python:

pip εγκατάσταση keras

μαξιλάρι εγκατάστασης pip

pip εγκατάσταση numpy

αιτήματα εγκατάστασης pip

pip εγκατάσταση opencv-pythonΕάν θέλετε να εκπαιδεύσετε μόνοι σας το δίκτυο, φροντίστε να ρυθμίσετε την επιτάχυνση GPU για το Keras

Βήμα 2: Ερώτηση του API αναζήτησης της NASA

ΣΦΑΙΡΙΚΗ ΕΙΚΟΝΑ

Η NASA διαθέτει πολλά πραγματικά χρήσιμα API που μπορείτε να χρησιμοποιήσετε με τα έργα σας. Για αυτό το έργο, θα χρησιμοποιήσουμε το API αναζήτησης, το οποίο μας επιτρέπει να αναζητήσουμε στη βάση δεδομένων εικόνων της NASA για εικόνες που σχετίζονται με το διάστημα.

Ο κώδικας

Αρχικά, πρέπει να ορίσουμε μια συνάρτηση python για να δεχτούμε ένα όρισμα που θα λειτουργεί ως όρος αναζήτησης:

def get_image_search (φράση):

πέρασμα

Στη συνέχεια, θα μετατρέψουμε τον όρο αναζήτησης σε μορφή URL και στη συνέχεια θα χρησιμοποιήσουμε τη βιβλιοθήκη αιτημάτων για να ζητήσουμε το API:

def get_image_search (φράση):

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

Τέλος, θα αποκωδικοποιήσουμε τη συμβολοσειρά συλλογής+JSON που μας επέστρεψε το API και θα εξαγάγουμε μια λίστα συνδέσμων προς εικόνες που σχετίζονται με τον όρο αναζήτησης:

def get_image_search (φράση):

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"]

Εκεί πάμε! Έχουμε τώρα ένα απόσπασμα κώδικα που μπορεί να ερωτήσει το API αναζήτησης εικόνας της NASA και να επιστρέψει μια λίστα συνδέσμων προς εικόνες που σχετίζονται με τον όρο αναζήτησης.

Βήμα 3: Το νευρικό δίκτυο

ΣΦΑΙΡΙΚΗ ΕΙΚΟΝΑ

Η δουλειά του νευρωνικού δικτύου είναι να ταξινομήσει εάν μια εικόνα είναι κάτι στο διάστημα ή αν δεν είναι. Για να γίνει αυτό, θα χρησιμοποιήσουμε ένα συνελικτικό νευρωνικό δίκτυο, ή CNN, για να εκτελέσουμε μια σειρά πράξεων μήτρας στην εικόνα και να καθορίσουμε πόσο χώρο είναι. Δεν θα τα εξηγήσω όλα αυτά, γιατί υπάρχει πολλή θεωρία πίσω από αυτό, αλλά αν θέλετε να μάθετε για τα νευρωνικά δίκτυα, προτείνω το "Machine Learning Mastery"

Ο κώδικας

Πρώτον, πρέπει να εισαγάγουμε τις εξαρτήσεις μας:

εισαγωγή os

#Επιδιόρθωση για ζήτημα κατά τη διάρκεια του τρένου στο GPU os.environ ['CUDA_VISIBLE_DEVICES'] = '' εισαγωγή tensorflow ως tf εάν tf.test.gpu_device_name (): print ('GPU found') else: print ("No GPU found") από keras.preprocessing.image εισαγωγή ImageDataGenerator από 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 εισαγωγή numpy ως 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.image_data_format () == 'channel_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 (Activation ('relu')) model.add (MaxPooling2D (pool_size = (2, 2)))) μοντέλο.add (Conv2D (64, (2, 2)))) model.add (Ενεργοποίηση ('relu')) model.add (MaxPooling2D (pool_size = (2, 2)))) model.add (Flatten ()) μοντέλο προσθήκη (Πυκνό (64)) model.add (Ενεργοποίηση ('relu')) model.add (Dropout (0.5)) model.add (Dense (1)) model.add (Activation ('sigmoid')) model.compile (απώλεια = 'binary_crossentropy', optimizer = 'rmsprop', metrics = ['ακρίβεια'])

Έχω εκπαιδεύσει το μοντέλο για εσάς, αλλά αν θέλετε να εκπαιδεύσετε το μοντέλο μόνοι σας, στο δικό σας σύνολο δεδομένων, τότε έχω επισυνάψει τον κωδικό εκπαίδευσης. Διαφορετικά, μπορείτε να κατεβάσετε το αρχείο HDF5 του εκπαιδευμένου μοντέλου. Λόγω των περιορισμών του αρχείου Instructables, έπρεπε να το μετονομάσω με επέκταση ".txt". Για να το χρησιμοποιήσετε, μετονομάστε το αρχείο σε επέκταση ".h5" και φορτώστε το με αυτόν τον κωδικό:

model.load_weights ("model_saved.h5")

Για να χρησιμοποιήσουμε το δίκτυο για να προβλέψουμε πόσο χώρος είναι μια εικόνα, θα ορίσουμε αυτήν τη συνάρτηση:

def parashik (image_path):

img = image.load_img (image_path, target_size = (1000, 500)) img = np.expand_dims (img, axis = 0) result = model.predict_classes (img) αποτέλεσμα επιστροφής [0] [0]

Βήμα 4: Επεξεργασία της εικόνας

ΣΦΑΙΡΙΚΗ ΕΙΚΟΝΑ

Για την επεξεργασία εικόνας, χρησιμοποιώ τη βιβλιοθήκη OpenCV (cv2). Αρχικά, θα θολώσουμε τις άκρες της εικόνας και στη συνέχεια θα αφαιρέσουμε το φόντο δημιουργώντας μια μάσκα και αλλάζοντας τις τιμές άλφα των πιο σκούρων χρωμάτων

Ο κώδικας

Αυτό είναι το μέρος της συνάρτησης που θολώνει τις άκρες:

def processImage (img):

RADIUS = 20 # Άνοιγμα εικόνας im = Image.open ("pilbuffer.png") # Επικόλληση εικόνας σε λευκό φόντο diam = 2 * RADIUS back = 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) mask. επικόλληση (blck, (diam, diam)) # Θόλωση εικόνας και επικόλληση θολής άκρης σύμφωνα με τη μάσκα blur = back.filter (ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (blur, mask = mask) back.save (" μετάβαση-p.webp

Στη συνέχεια, θα ορίσουμε τα πιο σκούρα χρώματα σε διαφανή και θα αποθηκεύσουμε προσωρινά την εικόνα:

#Δημιουργήστε μάσκα και φίλτρο αντικαταστήστε το μαύρο με άλφα

image = cv2.imread ("transfer.png") hMin = 0 sMin = 0 vMin = 20 hMax = 180 sMax = 255 vMax = 255 κάτω = np.array ([hMin, sMin, vMin]) άνω = np.array ([hMax, sMax, vMax]) hsv = cv2.cvtColor (εικόνα, cv2. COLOR_BGR2HSV) μάσκα = cv2.inRange (hsv, κάτω, επάνω) έξοδος = cv2.bitwise_and (εικόνα, εικόνα, μάσκα = μάσκα) *_, άλφα = cv2.split (output) dst = cv2.merge ((output, alpha)) output = dst with open ("buffer.png", "w+") as file: pass cv2.imwrite ("buffer.png", output)

Βήμα 5: Συρραφή εικόνων μαζί σε μια ισοσκελή προβολή

ΣΦΑΙΡΙΚΗ ΕΙΚΟΝΑ

Αυτή η λειτουργία λαμβάνει πολλές εικόνες και τις ράβει σε μορφή που μπορεί να ερμηνευτεί από το πακέτο PhotoSphere.js, χρησιμοποιώντας τη βιβλιοθήκη PIL (μαξιλάρι)

Ο κώδικας

Πρώτον, πρέπει να δημιουργήσουμε μια εικόνα που μπορεί να λειτουργήσει ως κεντρικός υπολογιστής για τις άλλες εικόνες:

new = Image.new ("RGBA", (8000, 4000), χρώμα = (0, 0, 0))

Στη συνέχεια, πρέπει να επαναλάβουμε τον πίνακα των εικόνων (που έχουν αλλάξει όλες τις διαστάσεις σε 1000x500) και να τις τοποθετήσουμε στην εικόνα:

h = 0

w = 0 i = 0 για img στο img_arr: new.paste (img, (w, h), img) w += 1000 αν w == 8000: h += 500 w = 0 i += 1

Τώρα απλά το ολοκληρώνουμε σε μια συνάρτηση που παίρνει μια σειρά εικόνων ως όρισμα και επιστρέφει τη νέα εικόνα:

def stitch_beta (img_arr):

new = Image.new ("RGBA", (8000, 4000), color = (0, 0, 0)) h = 0 w = 0 i = 0 for img in img_arr: new.paste (img, (w, h), img) w += 1000 αν w == 8000: h += 500 w = 0 i += 1 επιστροφή νέου

Βήμα 6: Το πλήρες σενάριο Python

Αυτό είναι το πλήρες σενάριο νευρωνικού δικτύου python, το οποίο αποθηκεύεται ως net.py και εισάγεται στο κύριο σενάριο:

# εισαγωγή βιβλιοθηκών

εισαγωγή os #Fix για έκδοση κατά τη διάρκεια της αμαξοστοιχίας σε GPU os.environ ['CUDA_VISIBLE_DEVICES'] = '' εισαγωγή tensorflow ως tf if tf.test.gpu_device_name (): print ('GPU found') else: print ("No GPU found ") από keras.preprocessing.image import ImageDataGenerator από keras.preprocessing image import 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 εισαγωγή εικόνας: 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)))) μοντέλο. προσθήκη (Ενεργοποίηση ('relu')) model.add (MaxPooling2D (pool_size = (2, 2))) model.add (Conv2D (64, (2, 2))) model.add (Ενεργοποίηση ('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 (Πυκνό (1)) model.add (Ενεργοποίηση ('sigmoid')) model.compile (loss = 'binary_crossentropy', optimizer = 'rmsprop', metrics = ['ακρίβεια']) 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) αποτέλεσμα επιστροφής [0] [0]

Αυτό είναι το κύριο αρχείο python, api.py:

αιτήματα εισαγωγής, sys, random, urllib.parse, cv2

από εικόνα εισαγωγής PIL, ImageFilter από io εισαγωγή BytesIO import numpy as np import net def get_image_search (num, φράση): count = 0 img_arr = για arg στη φράση: print (arg) print (f "Τρέχων αριθμός εικόνας: {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 (δεδομένα) ενώ μετράτε = 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 για img στο img_arr: #pbar.set_description (f "Επεξεργασία εικόνας {i +1}") new.paste (img, (w, h), img) w += 1000 αν w == 8000: h += 500 w = 0 i += 1 επιστροφή νέας διαδικασίας defImage (img): RADIUS = 20 # Άνοιγμα εικόνας im = Image.open ("pilbuffer.png") # Επικόλληση εικόνας σε λευκό φόντο = 2 * RADIUS back = 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) mask.paste (blck, (diam, diam)) # Θολώστε την εικόνα και επικολλήστε τη θολή άκρη σύμφωνα με τη μάσκα blur = back.filter (ImageFilter. GaussianBlur (RADIUS / 2)) back.paste (blur, mask = mask) back.save ("transfer.png") back.close () #Δημιουργία μάσκας και φίλτρο αντικαταστήστε το μαύρο με άλφα εικόνα = cv2.imread (" διαμετακόμιση ion.png ") hMin = 0 sMin = 0 vMin = 20 hMax = 180 sMax = 255 vMax = 255 κάτω = np.array ([hMin, sMin, vMin]) άνω = np.array ([hMax, sMax, vMax]) hsv = cv2.cvtColor (εικόνα, cv2. COLOR_BGR2HSV) μάσκα = cv2.inRange (hsv, κάτω, επάνω) έξοδος = cv2.bitwise_and (εικόνα, εικόνα, μάσκα = μάσκα) *_, alpha = cv2.split (έξοδος) dst = cv2.merge ((έξοδος, άλφα)) έξοδος = dst με ανοιχτό ("buffer.png", "w+") ως αρχείο: περάστε cv2.imwrite ("buffer.png", output) #Edge detection and blurring if _name_ == "_main_": search_terms = ["σουπερνόβα", "πλανήτης", "γαλαξίας", "γαλαξίας", "νεφέλωμα", "αστέρια"] #Οι όροι αναζήτησης μπορούν να αλλάξουν σε ό, τι θέλετε να περιλαμβάνει το πλανητάριο img_arr = get_image_search (64, search_terms) εκτύπωση ("Εικόνες που ανακτήθηκαν και φιλτράρονται νευρικά") img = stitch_beta (img_arr) εκτύπωση ("Εικόνες ραμμένες") img.save ("stitched.png")

Βήμα 7: Η εφαρμογή Electron

ΣΦΑΙΡΙΚΗ ΕΙΚΟΝΑ

Θα δημιουργήσουμε μια απλή εφαρμογή ηλεκτρονίων που απλώς τοποθετεί και φορτώνει το στοιχείο PhotoSphere. Τα αρχεία main.js και package.json προέρχονται απευθείας από τον ιστότοπο της Electron και το HTML είναι μια ελαφρώς τροποποιημένη έκδοση του HTML που παρέχεται στον ιστότοπο PhotoSphere. Έχω συμπεριλάβει τα αρχεία, αλλά μετονομάστηκαν σε.txt, καθώς το Instructables δεν επιτρέπει αυτούς τους τύπους αρχείων. Για να χρησιμοποιήσετε τα αρχεία, μετονομάστε τα με την κατάλληλη επέκταση.

Ο κώδικας

main.js

const {app, BrowserWindow} = απαιτούν ('electron')

λειτουργία createWindow () {const win = new BrowserWindow ({πλάτος: 800, ύψος: 600, webPreferences: {nodeIntegration: true}}) win.loadFile ('index.html')} app.whenReady (). στη συνέχεια (createWindow) app.on ('window-all-κλειστό', () => {if (process.platform! == 'darwin') {app.quit ()}}) app.on ('activ', () => {if (BrowserWindow.getAllWindows (). μήκος === 0) {createWindow ()}})

πακέτο.json

{

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

index.html

Βήμα 8: Εκτέλεση

Δημιουργία ισομεγέθους εικόνας

Για να δημιουργήσετε την εικόνα, εκτελέστε το σενάριο api.py στη γραμμή εντολών, με ενεργοποιημένο το εικονικό περιβάλλον:

api.py

Αφού ολοκληρωθεί η εκτέλεση των σεναρίων, εκτελέστε την εφαρμογή ηλεκτρονίων χρησιμοποιώντας:

npm έναρξηΒοϊλα! Το πλανητάριό σας είναι ενεργό! Ευχαριστώ για την ανάγνωση:)

Συνιστάται: