Verknüpfung von PHP und Python von Grund auf auf Laravel

Einführung

Implementieren wir eine auf Laravel basierende Software, die Python von PHP aus ausführt und das Ergebnis der Bilderkennung anzeigt.

Die Implementierung der Bilderkennung ist Versuchen Sie, MNIST mit TensorFlow zu lernen, die auf dem separaten Training und Test basiert. Zu

[2020/4/15] Bootstrap in Sicht eingeführt

Umgebung

--OS: Ubuntu 18.04.4 LTS (auf Virtual BOX)

Python3, das standardmäßig in Ubuntu 18.04.4 LTS enthalten ist, war 3.6.9, daher habe ich es aktualisiert. Fügen Sie gleichzeitig die in Python verwendete Bibliothek hinzu.

$sudo apt install python3.8
$sudo apt-get install python3-pip python3-dev
$pip3 install tensorflow
$pip3 install numpy
$pip3 install opencv-python

Beachten Sie, dass die Python2-Bibliothek enthalten ist, wenn Sie mit den Befehlen $ sudo apt-get install python-pip python-dev und pip installieren.

Schreiben Sie "~ / .bashrc" neu, um python3.8 zu verwenden.

..bashrc


alias python3='/usr/bin/python3.8'

Ein Projekt erstellen

Erstellen Sie ein Projekt mit dem Namen laravelAI.

$ composer create-project laravel/laravel laravelAI --prefer-dist

Verzeichnis- / Dateistruktur

Es werden nur die Elemente aufgelistet, die dieses Mal hinzugefügt / korrigiert werden sollen. Das Defizit wird hinzugefügt. laravelAI  ┗ app   ┗ Http    ┗ MnistController.php Python </ font>: Speichert Python-bezogene Dateien    ┗ mnist_test.py    ┗ DeepConvNet.py ckpt </ font>: Lernergebnisse speichern  ┗ resources   ┗ views    ┗ mnist     ┗ index.blade.php  ┗ routes   ┗ wab.php

PHP (Controller)

Erstellen Sie einen Controller.

$ php artisan make:controller MnistController

MnistController.php


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class MnistController extends Controller
{
    public function index(Request $request)
    {
        $data = [
            'msg' => "Bitte geben Sie ein Bild ein",
        ];
        return view('mnist.index', $data);
    }

    public function test(Request $request)
    {
        if(!empty($request->test_image))
        {
            //Holen Sie sich das Bild per Post gesendet
            $image = $request->file('test_image');
            //Das Speicherziel ist"storage/app/public/image"Wird sein
            //Der Dateiname wird automatisch vergeben
            $up_pass = $image->store('public/image');
            $image_pass = "./storage/image/".basename($up_pass);
            //Legen Sie den Pfad fest, in dem sich die Python-Datei befindet
            $pythonPath =  "../app/Python/";
            $command = "/usr/bin/python3 " . $pythonPath . "mnist_test.py " . $pythonPath . " " .$image_pass;
            exec($command , $outputs);

            //Extrahieren von Ergebniszeilen mit regulären Ausdrücken
            $results = preg_grep('/result:.*/' , $outputs);
            if(count($results) == 1){
                //Holen Sie sich den Anfang eines assoziativen Arrays
                $result = reset($results);
                $result = substr($result , strlen('result:') , 1 );
            } 
            else {
                $result = "Analyse fehlgeschlagen.";
            }
            $data = [
                'msg' => "Hast du ein?",
                'image_pass' => $image_pass,
                'result'  => $result,
                'lines'   => count($outputs),
                'outputs' => $outputs,
            ];
        }
        else {
            $data = [
                'msg' => "Es gibt kein Bild",
            ];
        }
        return view('mnist.index', $data);
    }
}

Erläuterung

Ausführen von Python-Befehlen

//Legen Sie den Pfad fest, in dem sich die Python-Datei befindet
$pythonPath =  "../app/Python/";
$command = "/usr/bin/python3 " . $pythonPath . "mnist_test.py " . $pythonPath . " " .$image_pass;
exec($command , $outputs);

Verwenden Sie die Funktion exec (), um Befehle von PHP auszuführen. Geben Sie den Befehl an, der im ersten Argument ausgeführt werden soll, und geben Sie die Variable an, die das Ausgabeergebnis des Befehls im zweiten Argument speichert. Weitere Informationen finden Sie unter hier.

Führen Sie Python in der Python-Datei "/ usr / bin / python3" aus. Die obige Zeichenfolge $ command sieht folgendermaßen aus: /usr/bin/python3 ../app/Python/mnist_test.py ../app/Python/ ./storage/image/FxY92Ji6j04cyozrx62yGHu9NQzLgsIqQq23YIcH.png

Wenn Sie den Befehl als "$ command =" pwd ";" ändern und ausführen, können Sie sehen, dass der Ausführungspfad von Laravel "/ home / hogehoge / laravelAI / public" lautet. Angenommen, geben Sie den Speicherort an, an dem sich die Python-Datei befindet.

Das erste Argument von "mnist_test.py" ist der "Trainingsdatenpfad" und das zweite Argument ist der "Bildpfad".

In Bezug auf den Speicherort des empfangenen Bildes

//Holen Sie sich das Bild per Post gesendet
$image = $request->file('test_image');
$up_pass = $image->store('public/image');
$image_pass = "./storage/image/".basename($up_pass);

Das Speicherziel des Bildes ist "Speicher / App / Öffentlich / Bild". Erstellen Sie mit dem folgenden Befehl einen symbolischen Link von "public / storage" zu "storage / app / public". Geben Sie für das zweite Argument von "mnist_test.py" und das in der Ansicht angezeigte Bild den Pfad unter "public / storage" an.

$ php artisan storage:link
$ cd public
$ ls -la
=> storage -> /home/hogehoge/laravelAI/storage/app/public

PHP (Routing)

Fügen Sie Folgendes zu route / web.php hinzu.

routes/web.php


Route::get ('mnist', 'MnistController@index');
Route::post('mnist', 'MnistController@test');

Pyhton Das Lernergebnis kann so verwendet werden, wie es aus Versuchen Sie, MNIST mit TensorFlow zu lernen stammt. Speichern Sie es im Ordner "Python / ckpt".

Der Testcode wird geringfügig geändert. Ermöglicht die Angabe von "Trainingsdatenpfad" und "Bildpfad" mit Befehlszeilenargumenten.

mnist_test.py


# -*- coding: utf-8 -*-
print('mnist_test.py START')
import sys
import tensorflow as tf
import cv2
import numpy as np
import DeepConvNet as CNN
#Befehlszeilenargumente abrufen
args = sys.argv

IMAGE_SIZE  = 28    #Bildgröße
NUM_CLASSES = 10    #Anzahl der Identifikationen

if __name__ == "__main__":
    tf.reset_default_graph()
    
    print('START einstellen')
    #In Ausdrücken verwendete Variableneinstellungen
    x_image = tf.placeholder("float", shape=[None, IMAGE_SIZE * IMAGE_SIZE])    #Eingang
    y_label = tf.placeholder("float", shape=[None, NUM_CLASSES]) #Ausgabe
    keep_prob = tf.placeholder("float")

    #Erstellen Sie ein Modell
    logits = CNN.CNN.makeMnistCNN(x_image, keep_prob , IMAGE_SIZE , NUM_CLASSES)
    sess = tf.InteractiveSession()

    saver = tf.train.Saver()
    #Variablen initialisieren und ausführen
    sess.run(tf.global_variables_initializer())
    print('END einstellen')
    
    print('Restore Param Start')
    ckpt = tf.train.get_checkpoint_state(args[1] + 'ckpt')
    #print(os.path.exists(args[1] + 'ckpt'))
    if ckpt: #Wenn es einen Kontrollpunkt gibt
        last_model = ckpt.model_checkpoint_path #Pfad zum zuletzt gespeicherten Modell
        print ("Restore load:" + last_model)
        saver.restore(sess, last_model) #Variable Daten lesen
    else:
        print('Restore Failed')
    print('Restore Param End')
    
    
    #Bild wird geladen
    inputNum = 1
    for count in range(int(inputNum)):
        fileName =  args[2]
        print('fileName:' + fileName)

        #Initialisieren
        ximage = []
        
        #Bild wird geladen
        image = cv2.imread(fileName, cv2.IMREAD_GRAYSCALE)
        if not image is None:
            image = cv2.resize(image, (IMAGE_SIZE, IMAGE_SIZE))
            ximage = image.flatten().astype(np.float32)/255.0
        else:
            print('Error:File Read Failed !!')

        if len(ximage)!=0:
            pred = np.argmax(logits.eval(feed_dict={x_image: [ximage], keep_prob: 1.0})[0])
            
            print("result:" + str(pred))
    sess.close()
    print('mnist_test.py END')

PHP (Ansicht)

Erstellen Sie eine Ansicht. Das Layout ist geeignet.

index.blade.php  //.html


<html>
<head>
    <title>Mnist</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" >
    <style>
        body{
            background-color: #EEFFEE;
        }
    </style>
</head>

<body>
<div class="container">
        <div class="row">
            <div class="col-sm-10">
                <h2>1-Erkenne die Nummer 9</h2>
                <p>{{$msg}}</p>

                <form method = "POST" action="/mnist" enctype="multipart/form-data">
                    @csrf
                    <input type="file" name="test_image"><BR>
                    <input type="submit" id="submit" value="Senden">
                </form>
            </div>
        </div>

        <div class="row">
            @isset($image_pass)
                <div class="col-sm-5">
                    <h3>Ergebnis</h3>
                    <img src="{{ asset($image_pass)}}" width="112" height="112"> <BR>
                    @isset($result)
                        <p>Dieses Bild ist "{{$result}}"ist</p>
                    @endempty
                </div>
            @endempty

            @isset($outputs)
                <div class="col-sm-5">
                    <h3>Python-Ausgabe( {{$lines}}Linie)</h3>
                    @foreach ($outputs as $output)
                        {{$output}}<BR>
                    @endforeach
                </div>
            @endempty
        </div>
    </div>
</body>
</html>

Funktionsprüfung

Starten Sie den Server mit dem folgenden Befehl.

$ php artisan serve 

Gehen Sie in Ihrem Browser zu "http: // localhost: 8000 / mnist". WS000226.JPG

Wählen Sie eine Datei aus und senden Sie sie. WS000225.JPG

Ich konnte es erkennen!

Am Ende

Die Einführung von Vue und TypeScript wird in Verknüpfung zwischen PHP und Python von Grund auf auf Laravel + Vue + TypeScript beschrieben.

Ergänzung

Ausnahme beim Speichern der Datei: Die Datei "" existiert nicht oder ist nicht lesbar.

Als ich in einem anderen Fall mit dem Code herumgespielt habe, bin ich auf die obige Ausnahme mit $ image-> store () von file save gestoßen, also habe ich sie abgefangen.

Symfony\Component\Mime\Exception\InvalidArgumentException
The "" file does not exist or is not readable. 

An der Ausnahmemeldung oder dem Aufrufstapel ist es schwer zu erkennen, aber es liegt daran, dass Sie an eine Größenbeschränkung für hochgeladene Dateien gebunden sind.

Gegenmaßnahmen

Die Dateigröße ist in der Datei php.ini definiert. Ändern Sie sie daher. (Als ich im Internet gesucht habe, gab es auch eine Methode zum Ändern von .htaccess, aber das Ändern von "public / .htaccess" hat es nicht verbessert.)

# php.Überprüfen Sie den Standort von ini
$ php -i | grep php.ini
Configuration File (php.ini) Path => /etc/php/7.2/cli
Loaded Configuration File => /etc/php/7.2/cli/php.ini

$ sudo vi  /etc/php/7.2/cli/php.ini

Ändern Sie die folgenden zwei Zeilen nach Bedarf. In PHP7.2 werden standardmäßig 2 MB und 8 MB verwendet.

php.ini


;Maximale Gesamtgröße aller von POST hochgeladenen Dateien
post_max_size=2M
;Maximale Größe pro Datei
upload_max_filesize=8M

Bitte starten Sie den Server nach der Änderung neu.

$ php artisan  serve

Recommended Posts