[PYTHON] Eine Geschichte, bei der es mir schwer gefallen ist, mit der ersten Webanwendung eine "App zu erstellen, die Bilder wie Gemälde konvertiert"

Einführung

Dies ist eine Geschichte, in der der Autor, der wenig über Netzwerke weiß, versuchte, eine Bildverarbeitungs-Webanwendung als erste Webanwendung zu erstellen, und Probleme beim Umgang mit Bildern hatte. Selbst wenn ich im Internet gesucht habe, gab es überraschend wenige Artikel über ** Bildverarbeitungs-Webanwendungen mit Python, GCP, Flask **, daher hatte ich Probleme mit dem Verfahren zum Erstellen einer Bildverarbeitungs-Webanwendung **, die vorerst funktioniert. Ich werde es vorstellen.

Fertiges Produkt

** 1. Öffnen Sie die Website, wählen Sie das Bild aus, das Sie verarbeiten möchten, und senden Sie es. ** image.png ** Ausgewähltes Originalbild ** 処理前.jpg

** 2. Ein wie ein Gemälde konvertiertes Bild wird zurückgegeben. ** ** ** 処理後.PNG

Web-App, die Bilder wie Gemälde konvertiert

Web App Übersicht

Ich habe versucht, den Umriss der erstellten Webanwendung in der Abbildung zusammenzufassen. Dieses Mal habe ich Googles Cloud ** GCP ** als Webserver im Rahmen des kostenlosen Dienstes verwendet. Der eigentliche Bildverarbeitungsteil wurde mit ** Python ** erstellt, und das Erscheinungsbild der Website konnte problemlos nur mit ** HTML ** erstellt werden. Dann habe ich die Verknüpfung zwischen Python und HTML mit ** Flask ** erstellt, einer Art Python-API.

image.png

1. Aufbau der GCE-Umgebung (Google Cloud Engine)

Zunächst erstellen wir eine Umgebung zum Veröffentlichen von Webanwendungen mithilfe eines Dienstes namens GCE in GCP. ** Google-Konto und Kreditkarte sind erforderlich, um GCP zu verwenden **. Halten Sie sie bereit. In diesem Artikel wird außerdem die ** SSH-Verbindung von Google Chrome zu GCE ** verwendet, um die virtuelle Umgebung in der Cloud fernzusteuern. Um den GCE-Dienst nutzen zu können, müssen Sie die folgenden drei Aufgaben ausführen. Lesen Sie jedoch den Artikel, in dem er auf leicht verständliche Weise erläutert wird. Da ich über die Google Cloud Platform Console eine Verbindung herstelle (Browser ist Google Chrome), habe ich den SSH-Authentifizierungsschlüsselteil des Artikels übersprungen. Einstellungen sind erforderlich, wenn Sie eine SSH-Verbindung über das Mac-Terminal herstellen möchten. [Referenzartikel] GCP (GCE), um von nun an zu beginnen, verwenden Sie sicher die kostenlose Stufe

[Erforderliche Arbeit] ・ Registrieren Sie sich für eine kostenlose Testversion von GCP ・ Projekt erstellen -Erstellen einer Instanz einer virtuellen Maschine

2. So starten Sie die Cloud-Shell

Öffnen Sie nach dem Erstellen der GCE-Umgebung die Seite Instanzen (https://console.cloud.google.com/compute/instances) und klicken Sie oben rechts auf Cloud-Shell aktivieren, um das Terminal zu starten. .. ** Sobald das Terminal gestartet wurde, können Sie die mit Linux-Befehlen erstellte GCE-Instanz bedienen. ** Laut der offiziellen Website stellt die Compute Engine zum ersten Mal automatisch eine automatische Verbindung zur VM-Instanz her. Es scheint, dass ein SSH-Authentifizierungsschlüsselpaar generiert wurde.

image.png

3. Übertragen von Daten zur und von der lokalen Umgebung

Damit GCE Websites und Bildverarbeitungen ausführen kann, die in der lokalen Umgebung erstellt wurden, müssen die Daten in der lokalen Umgebung mit GCE geteilt werden. Es gibt eine Möglichkeit, es mit einem Befehl cool auszudrücken, aber ich habe die ** am einfachsten zu verstehende Methode mit Cloud Storage ** gewählt, da die Einstellungen problematisch sind. Wählen Sie auf der Registerkarte GCP die Option Strage → Browser. Laden Sie nach dem Erstellen eines Buckets mit einem geeigneten Namen im Speicherbrowser die Datei hoch, die Sie lokal für GCE freigeben möchten. image.png

Sie können die im Speicher gespeicherten Daten an einem beliebigen Ort von GCE speichern, indem Sie den folgenden Code mit der Cloud-Shell ausführen. gsutil ist eine Anwendung für den Zugriff auf Cloud Storage über die Befehlszeile.

gsutil cp -r gs://{Eimername}/ ./{GCE-Ordnername usw.}

[Referenzartikel] [Free] Die Geschichte der Qiita Hall of Fame [Easy]

4. Struktur der Webanwendungsdatei (bei Verwendung von GCE / Python / Flask)

Wenn Sie eine Webanwendung mit Python und Flask auf GCE erstellen, müssen Sie über die folgende Datei- und Verzeichnisstruktur verfügen. ** Umgekehrt können Sie das erstellte Programm mit der folgenden Konfiguration speichern und einige Befehle in GCP ausführen, um sofort eine App zu erstellen. ** Wenn Sie jede Datei und jeden Ordner anders als meinen Ordnernamen anders als die folgenden benennen, tritt ein Fehler auf, daher müssen Sie vorsichtig sein.

mein Ordnername (jeder Name ist OK) /  ├ static/  ├ templates/  │  └ index.html  ├ app.yaml  ├ main.py  └ requirements.txt

Ich werde jede Rolle kurz beschreiben.

5. Erstellen Sie eine Web-App

Sobald die obige Dateistruktur in GCE erstellt wurde, ist es einfach, eine Webanwendung zu erstellen. Führen Sie den folgenden Befehl aus.

Um eine App bereitzustellen, müssen Sie zuerst die App in einer Region erstellen.

gcloud app create

Stellen Sie die App bereit.

gcloud app deploy app.yaml --project {my project name}

Geben Sie Ihren Projektnamen in den Teil {Mein Projektname} ein. Ich denke, es ist in der Cloud Shell geschrieben. Wenn Sie den Quellcode in Kapitel 9 dieses Artikels kopieren und einfügen, um eine Programmdatei zu erstellen, und die Verzeichnisstruktur der in Kapitel 4 entspricht, funktioniert dies. Wenn Sie eine Fehlermeldung erhalten, können Sie den Inhalt in App Engine Dashboard überprüfen.

6. Bildverarbeitungsmethode

Ich habe den im folgenden Artikel eingeführten ** Kuwahara-Filter ** übernommen und den Code so verwendet, wie er ist. ** Es ist erstaunlich, dass Sie ein malerisches Bild erhalten können, das wie eine aufwändige, tief lernende Bildverarbeitung aussieht, obwohl es durch eine einfache Formel ausgedrückt werden kann **. Ich finde es ziemlich interessant. Weitere Informationen finden Sie im folgenden Artikel. Ich bin auf einen Bildfilter mit einem eindeutig japanischen Namen namens Kuwahara-Filter gestoßen, und als ich ihn ausprobiert habe, war er erstaunlich, daher werde ich ihn vorstellen.

** Das Originalbild ** a.jpeg

** Nach dem Auftragen des Filters ** b.jpe

7. Probleme beim Übergeben von Bildern von Python an HTML

Es fiel mir schwer, das Bild nach der Bildverarbeitung in Python an HTML zu übergeben. Zuerst habe ich das Bild normalerweise einmal in einer statischen Datei gespeichert, den Pfad zu HTML übergeben und das Bild aus HTML gelesen. ** Während die App in der GCE-Umgebung ausgeführt wird, scheint das Schreiben von Python in den Ordner eingeschränkt zu sein, was zu einem Fehler führt. ** Laut der offiziellen Website werden die folgenden vier zum Speichern von Daten in der Laufzeitumgebung empfohlen. War dort. · Cloud Firestore im Datenspeichermodus ・ Cloud SQL für MySQL ・ Cloud SQL für PostgreSQL ・ Cloud-Speicher

Ich habe Cloud Storage ausprobiert, mit dem anscheinend Bilder gespeichert werden können, aber ich konnte es mit meinem aktuellen Netzwerkwissen nicht zum Laufen bringen. Außerdem habe ich einen Artikel gefunden, in dem Daten mit tempfile, einer Python-API, gespeichert werden können, und habe es versucht. Ich konnte Daten aus Python speichern, aber im Gegenteil, ich konnte nicht über HTML zugreifen und es blieb hängen. Es war.

Wenn ich darüber nachdenke, muss ich das Bild nicht irgendwo speichern, also habe ich nach einer Möglichkeit gesucht, Bilddaten direkt von Python an HTML ** zu übergeben. ** Es gab eine Methode, Bilddaten mit base64 auf der Python-Seite zu codieren, sie als Zeichenfolge an HTML zu übergeben und die Zeichenfolge auf der HTML-Seite zu dekodieren, um ein Bild zu erstellen! ** Als ich es tatsächlich mit Bezug auf den folgenden Artikel ausprobiert habe, hat es funktioniert. HTML von Bildern anzeigen, die mit Kissen erstellt wurden, ohne in einer Datei gespeichert zu werden [Django]

8. Probleme aufgrund von Speichermangel

** Als ich verschiedene Bilder ausprobierte, schien der maximale Speicher (256 MB) der freien Version GCE abhängig von der Bildgröße überschritten worden zu sein, und es trat ein Fehler auf (es war nutzlos, wenn es größer als 1000 x 600 war). ** Vielleicht kann ich das Programm und die Datenstruktur verbessern, ohne die Maschine zu aktualisieren, aber ich habe es noch nicht getan. ** GCP hat für das erste Jahr ein kostenloses Guthaben von 300 USD **. Vielleicht möchten Sie ein Upgrade durchführen und es ausprobieren. Übrigens können Sie die Details des Fehlers über das App Engine-Dashboard auf der Registerkarte GCP überprüfen. メモリ不足エラー.PNG

9. Quellcode

app.yaml


runtime: python37

main.py


#Laden Sie das gewünschte Modul
#Flasche verwandt
from flask import Flask, render_template, request, redirect, url_for, abort
import base64
import tempfile
from PIL import Image
import io
import numpy as np
import cv2

app = Flask(__name__)

def kuwahara(pic,r=5,resize=False,rate=0.5): #Originalbild, eine Seite einer quadratischen Fläche, Verhältnis beim Ändern der Größe oder Größe
    h,w,_=pic.shape
    if resize:pic=cv2.resize(pic,(int(w*rate),int(h*rate)));h,w,_=pic.shape
    pic=np.pad(pic,((r,r),(r,r),(0,0)),"edge")
    ave,var=cv2.integral2(pic)
    ave=(ave[:-r-1,:-r-1]+ave[r+1:,r+1:]-ave[r+1:,:-r-1]-ave[:-r-1,r+1:])/(r+1)**2 #Chargenberechnung des Durchschnittswertes
    var=((var[:-r-1,:-r-1]+var[r+1:,r+1:]-var[r+1:,:-r-1]-var[:-r-1,r+1:])/(r+1)**2-ave**2).sum(axis=2) #Massenberechnung der Verteilung
    
    def filt(i,j):
        return np.array([ave[i,j],ave[i+r,j],ave[i,j+r],ave[i+r,j+r]])[(np.array([var[i,j],var[i+r,j],var[i,j+r],var[i+r,j+r]]).argmin(axis=0).flatten(),j.flatten(),i.flatten())].reshape(w,h,_).transpose(1,0,2)
    filtered_pic = filt(*np.meshgrid(np.arange(h),np.arange(w))).astype(pic.dtype) #Farbbestimmung
    return filtered_pic
    
@app.route("/", methods=["GET", "POST"])
def upload_file():
    if request.method == "GET":
        return render_template("index.html")
    if request.method == "POST":
        #Speichern Sie die hochgeladene Datei einmal
        f = request.files["file"]
        filepath = tempfile.mkdtemp()+"/a.png "
        #filepath = "{}/".format(tempfile.gettempdir()) + datetime.now().strftime("%Y%m%d%H%M%S") + ".png "
        
        f.save(filepath)
        image = Image.open(filepath)
        
        #Bildverarbeitungsteil
        image = np.asarray(image)
        filtered = kuwahara(image, r=7)        
        filtered = Image.fromarray(filtered)
        
        #Codiert mit base64
        buffer = io.BytesIO()
        filtered.save(buffer, format="PNG")
        img_string = base64.b64encode(buffer.getvalue()).decode().replace("'", "")
        
        result = "image size {}×{}".format(len(image[0]), len(image))
        return render_template("index.html", filepath=filepath, result=result, img_data=img_string)
    
    
if __name__ == "__main__":
     app.run(host="127.0.0.1", port=8080, debug=True)

Der folgende Artikel wurde als Referenz beim Schreiben des Flask-Codes verwendet. Python x Flask x PyTorch Einfacher Aufbau einer Webanwendung zur Nummernerkennung

requirements.txt


Flask==1.1.2
Pillow==7.2.0
Numpy==1.16.4
opencv-python==4.2.0.34

index.html


<html>
    <body>
        {% if result %}
	<IMG SRC="data:image/png;base64,{{img_data}}" alt="img_data"  id="imgslot"/>
        <div>{{result}}</div>
	<HR>
        {% endif %}
Bitte wählen Sie eine Datei und senden Sie<BR>
        <form action = "./" method = "POST" 
           enctype = "multipart/form-data">
           <input type = "file" name = "file" />
           <input type = "submit"/>
        </form>
     </body>
</html>

10. Schließlich

Vielen Dank, dass Sie den Artikel bis zum Ende gelesen haben. Das Erstellen einer Web-App war nicht einfach, aber ich habe es geschafft, etwas zu erstellen, das funktioniert. ** LGTM wird eine der Motivationen für das Schreiben von Artikeln sein, also danke. ** ** **

Recommended Posts

Eine Geschichte, bei der es mir schwer gefallen ist, mit der ersten Webanwendung eine "App zu erstellen, die Bilder wie Gemälde konvertiert"
Die Geschichte, die nichts mit der Partition zu tun hatte, als ich zum ersten Mal eine Festplatten-Sicherung mit dd durchführte
Beachten Sie, dass ich süchtig danach war, mit Pythons mysql.connector über eine Webanwendung auf die Datenbank zuzugreifen
Eine Geschichte, bei der es mir schwer fiel, Grafiken mit matplotlib anzuzeigen
Ich habe eine Webanwendung in Python erstellt, die Markdown in HTML konvertiert
Mit LINEBot habe ich eine Anwendung erstellt, die mich über die "Buszeit" informiert.
Die Geschichte der Erstellung einer Webanwendung, die umfangreiche Lesungen mit Django aufzeichnet
Ich möchte eine WEB-Anwendung mit den Daten von League of Legends ① erstellen
Erstellen Sie eine Web-App, die PDF mit Flask und PyPDF2 in Text konvertiert
Ich möchte eine API erstellen, die ein Modell mit einer rekursiven Beziehung im Django REST Framework zurückgibt
(Hinweis) Eine Webanwendung, die TensorFlow verwendet, um empfohlene Songnamen abzuleiten. [Erstellen Sie eine Ausführungsumgebung mit Docker-Compose.]
Eine Geschichte, die fehlgeschlagen ist, als versucht wurde, das Suffix mit rstrip aus einem String zu entfernen
Ich wollte eine DLL erstellen, um eine in C von Python in ctypes geschriebene Funktion zu verwenden, aber es fiel mir schwer
Es fiel mir schwer, über einen Browser (und ArchLinux) auf Hadoop3.0.0 zuzugreifen.
Ich habe mit Single GANs (SinGAN) gespielt (+ Ich habe auch die Punkte zusammengefasst, die ich nur schwer implementieren konnte (über Pfad, Linux-Befehl, Googlecolab-Nutzung usw.)).
Ich möchte zum ersten Mal eine Django-Studie zur Mittagsdatenbank [EP1] erstellen
Ich möchte zum ersten Mal eine Django-Studie zum Mittagessen [EP1-4] erstellen
Eine Geschichte, bei der ich das Teilungsergebnis (%) in HTML mit einer Anwendung mit Django anzeigen wollte [Anfänger lernt Python mit einem Nachschlagewerk in einer Hand]
Eine Geschichte, bei der ich darüber nachdachte, die Informationen über die Fülle des Parkplatzes anhand des von der Webkamera und Razpai erhaltenen Bildes und durch tiefes Lernen zu ermitteln.
Erstellen Sie eine Web-App, die Zahlen mit einem neuronalen Netzwerk erkennt
Der erste Schritt beim Erstellen einer serverlosen Anwendung mit Zappa
Erstellen Sie eine Web-API, die Bilder mit Django liefern kann
Ich möchte vorerst eine Docker-Datei erstellen.
Ich habe zum ersten Mal versucht, mit DynamoDB und Step Functions eine serverlose Stapelverarbeitung zu erstellen
Eine Geschichte, die nicht funktioniert hat, als ich versucht habe, mich mit dem Python-Anforderungsmodul anzumelden
Ich habe eine Webanwendung erstellt, die das auf Google Home aufgezeichnete Lebensprotokoll wie ein Gantt-Diagramm grafisch darstellt.
Erstellen Sie einen BOT, der mit Discord registrierte Bilder wie Piktogramme aufrufen kann
Ich hatte Schwierigkeiten mit dem Importfehler: Das Laden der DLL in Tensorflow 2.0 ist fehlgeschlagen
Erstellen Sie eine Web-App, die mit Plotly Dash einfach visualisiert werden kann
Eine Geschichte, die ich süchtig danach war, eine Video-URL mit Tweepy zu bekommen
Die Geschichte der Entwicklung einer WEB-Anwendung, die automatisch Fangkopien generiert [MeCab]
Spielen Sie wie eine Web-App mit ipywidgets
Erstellen Sie eine einfache Web-App mit Flasche
Ich habe eine WEB-Bewerbung bei Django gemacht
Lassen Sie uns mit Flask eine Webanwendung zur Konvertierung von A nach B erstellen! Von Grund auf neu ...
Die Geschichte der IPv6-Adresse, die ich auf ein Minimum beschränken möchte
[kotlin] Erstellen Sie eine App, die Fotos erkennt, die mit einer Kamera auf Android aufgenommen wurden
Ich habe einen Appdo-Befehl erstellt, um Befehle im Kontext der App auszuführen
Erstellen Sie mithilfe der COTOHA-API eine App, die gut mit Berichten von Personen funktioniert
Eine Geschichte, der ich nach der SFTP-Kommunikation mit Python verfallen war
Ich habe versucht, ein Modell mit dem Beispiel von Amazon SageMaker Autopilot zu erstellen
Erstellen Sie eine App, die Schüler mit Python errät
Verfahren zur Erstellung plattformübergreifender Apps mit kivy
Ich habe eine Twitter-App erstellt, die die Zeichen der Vorverbindung mit Heroku entschlüsselt (Fehler).
Eine Geschichte, die vorbereitet werden musste, wenn versucht wurde, ein Django-Tutorial mit einfachen Centos7 zu erstellen
Ich habe versucht, mit dem Seq2Seq-Modell von TensorFlow so etwas wie einen Chatbot zu erstellen
Eine Geschichte, die beim Versuch, die Python-Version mit GCE zu aktualisieren, hängen blieb
Ich kann die Uhrenquelle tsc nicht finden! ?? Die Geschichte des Versuchs, einen Kernel-Patch zu schreiben
Erstellt eine Web-App, die IT-Ereignisinformationen mit Vue und Flask abbildet
Versuchen Sie, mit Python eine Wellenform (Audiospektrum) zu erstellen, die sich entsprechend dem Klang bewegt
Verwenden Sie die Twitter-API, um die von Twitter benötigte Zeit zu verkürzen (erstellen Sie eine Hervorhebungszeitleiste).
Beim Schreiben in eine CSV-Datei mit Python habe ich einen kleinen Fehler gemacht und den Liefertermin nicht eingehalten
Ich habe in Python ein Programm erstellt, das die 1-Minuten-Daten von FX auf eine beliebige Zeit (1 Stunde usw.) ändert.
Eine Geschichte, die Django mit einer Funktion wie before_action ausführen wollte, die in Schienen verwendet wird [Anfänger lernt Python mit einem Nachschlagewerk]
Eine Geschichte, die ich nicht wusste, wie man Mixin lädt, wenn ich mit der Django-App eine Front mache [Anfänger lernt Python mit einem Nachschlagewerk]