<jupyter_start><jupyter_text>Der Arbeitsplan des gesamten Systems sieht ungefähr wie folgt aus:Das von der Kamera aufgenommene Bild wird an CNN (Erste künstliche Intelligenz)übermittelt. CNN entscheidet über Zustand der Anlage (0: gut oder 1: durstig). Die Entscheidung des CNN und die Werte des Bodenfeuchtesensors werden an das DNN (Zweite Künstliche Intelligenz) übermittelt. DNN (Dens Neural Network) ist darauf trainiert, viele Informationen auszuwerten. Eine Liste davon finden Sie oben.   - 0: Es ist nicht notwendig, die Pflanzen zu gießen   - 1: Es ist notwendig, die Pflanzen zu gießenSchließlich wird das Relais mit einem einfachen Algorithmus gemäß der Entscheidung des DNN geöffnet oder geschlossen.  1. Notwendige ImporteWir importieren die notwendigen Python-Bibliotheken, um unser Projekt auszuführen.<jupyter_code>import torch
from torchvision import transforms, models
from torch import nn
import numpy as np
import cv2   # pip install opencv-python==3.3.0.9
from PIL import Image
import pandas as pd
import time
import matplotlib.pyplot as plt

%matplotlib inline<jupyter_output><empty_output><jupyter_text>2. Pflanzenklassifizierung (Erste künstliche Intelligenz)Um das zuvor trainierte Modell zu verwenden, importieren wir es und laden die Modellgewichte.Zur Klassifizierung haben wir die Transfer Learning Methode verwendet. Als Modell wurde densenet121 gewählt. Wenn der folgende Code ausgeführt wird, werden Modellparameter auf den Computer heruntergeladen (falls erforderlich).<jupyter_code># use densenet121 as model
model = models.densenet121(pretrained=True)
# freez model parameters
for param in model.parameters():
    param.requires_grad = False
# make the classifier part of the model suitable for our project
model.classifier = nn.Sequential(nn.Linear(1024, 256),
                                 nn.ReLU(),
                                 nn.Dropout(0.2),
                                 nn.Linear(256, 2),
                                 nn.LogSoftmax(dim=1))
# !! This is important. Bring model in to test mode
model.eval()
# Load best weights that before has been trained
model.load_state_dict(torch.load('92transferlearning_model_equal_Adam003_ColorJitter.pt', map_location=torch.device('cpu')))<jupyter_output><empty_output><jupyter_text>Um die Details des Modells anzuzeigen, lassen Sie diese Zelle bitte unkommentiert und führen Sie sie aus.<jupyter_code># model<jupyter_output><empty_output><jupyter_text>Wir schreiben eine Funktion, die das Foto der Pflanze als Argument nimmt und den Zustand der Pflanze (gut oder dehydriert) mit unserem Modell der künstlichen Intelligenz festhält.Unsere Funktion gibt **0** für einen **guten** Zustand und **1** für einen **dehydrierten** Zustand zurück.<jupyter_code>class_names = ['good', 'thirsty']

def predict_plant_situation(img):
    # Check if it's an array of picture or a path of picture
    if isinstance(img, str):        
        # load the image from path
        img = Image.open(img, mode='r')
    else:
        # convert image array in to PIL image
        img = Image.fromarray(img)
    # normalize picture    
    img_transform = transforms.Compose([
#                                         transforms.Resize(255),
#                                         transforms.CenterCrop(224),
                                        transforms.ToTensor()
                                        ])
    img = img_transform(img)
    # reshape the picture for the model
    img = img.reshape((1, img.shape[0], img.shape[1], img.shape[2]))    
    # pass the picture from model
    model.eval()
    output = model(img)
    # if you want to use index of pred
    _, pred = torch.max(output, 1)
    # if you want to use label 
#     pred = class_names[np.squeeze(output.data.max(1, keepdim=True)[1])]         
    
    return pred.numpy()[0]<jupyter_output><empty_output><jupyter_text>Die folgende Funktion nimmt Bilder mit Hilfe einer an den Computer angeschlossenen Webcamera auf. Mit dieser Funktion machen wir ein Foto der Pflanze.<jupyter_code># take a picture from webcam
def get_image(path=False, cam_no=0, show_img=False):
    # get an image from path
    if path:
        img = plt.imread(path)
        if show_img:            
            plt.imshow(img)
        return img
    # if path=0 get image from cam_no=0
    cap = cv2.VideoCapture(cam_no)
    cap.set(3,640) # adjust width
    cap.set(4,480) # adjust height
#     time.sleep(4) # if necessary wait for outofocus
    success, img = cap.read()
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    cap.release()
    if show_img:
        plt.imshow(img)
    return img<jupyter_output><empty_output><jupyter_text>Jetzt machen wir ein Foto und testen unsere Funktion, **get_image()**.<jupyter_code>img=get_image(cam_no=0, show_img=True)
print(img.shape)<jupyter_output>(480, 640, 3)<jupyter_text>Hier schreiben wir eine Funktion, die das mit Hilfe von **get_image()** (oder aus einer Datei auf dem Computer) aufgenommene Pflanzenfoto als Argument an **get_plant_situation()** gibt und den Zustand der Anlage ( gut oder dehydrate ) einfriert.<jupyter_code>def get_plant_situation(cam_no=0, path=False, show_img=False):
    if path:
        img = get_image(path=path, show_img=show_img) 
    else:
        # get an image from webcam
        img = get_image(cam_no=cam_no, show_img=show_img)
    return predict_plant_situation(img)<jupyter_output><empty_output><jupyter_text>Lassen Sie uns nun die Funktion get_plant_situation() testen.<jupyter_code># img_path = r"C:\Users\sahin\Desktop\sharerd_folder\flowers\test\good\healthy_070.jpg"  # 0
# img_path = r"C:\Users\sahin\Desktop\sharerd_folder\flowers\test\thirsty\wilted_202.jpg"  # 1

# get_plant_situation(path=img_path, show_img=True)
get_plant_situation(cam_no=0, path=0, show_img=True)<jupyter_output><empty_output><jupyter_text>3. Entscheidungsträger (Zweite Künstliche Intelligenz)Unser Klassifikator, den wir in diesem Abschnitt verwenden werden, ist ein Modell der künstlichen Intelligenz, das anhand verschiedene Daten entscheidet, ob die Pflanze gegossen werden soll oder nicht. Ich liste unten auf, welche Daten als Argument verwendet werden. Damit dieses Modell eine Entscheidung treffen kann, müssen ähnliche Informationen bereitgestellt werden. * 'season': Saison (1:Frühling, 2:Sommer, 3:Herbst, 4:Winter) * 'yr': Jahr (0: letztes Jahr, 1: dieses Jahr) * 'mnth': Monat (1 bis 12) * 'hr' : Stunde (0 bis 23) * 'b12h_weathersit' : Wetterlage vor 12 Stunden        - 1: Klar, Sonnig        - 2: Bewölkt, unterbrochene Wolken        - 3: Leichter Schnee, leichter Regen        - 4: Starker Regen + Eispaletten * 'b6h_weathersit' : Wetterlage vor 6 Stunden * 'b3h_weathersit' : Wetterlage vor 3 Stunden * 'crnt_weathersit': Aktuelle Wetterlage * 'a3h_weathersit' : Wettervorhersage after 3 Stunden * 'a6h_weathersit' : Wettervorhersage after 6 Stunden * 'a9h_weathersit' : Wettervorhersage after 9 Stunden * 'a12h_weathersit' : Wettervorhersage after 12 Stunden * 'temp' : Normalisierte Temperatur in Celsius. Die Werte werden auf 41 (max) geteilt  * 'atemp' : Normalisierte Gefühlstemperatur in Celsius. Die Werte werden auf 50 (max) geteilt  * 'hum' : Normalisierte Luftfeuchtigkeit. Die Werte werden durch 100 (max) geteilt * 'soil_hum' : Normalisierte Bodenfeuchte. Die Werte werden durch 100 (max) geteilt * 'windspeed' : Normalisierte Windgeschwindigkeit. Die Werte werden auf 67 (max) geteilt * 'CNN_decision' : Die Entscheidung der ersten künstlichen Intelligenz über den Zustand der Anlage         - 0: gut         - 1: durstig  Wir haben eine solche Methode befolgt, um die Daten ordnungsgemäß auf das Modell zu übertragen. Wir speichern die Bearbeitungsinformationen, einschließlich der vom Modell während des Trainings verwendeten Grenzen, in einer CSV-Datei. Am Ende der Liste in dieser csv-Datei speichern wir die gerade erstellten Daten mit dem Namen example. Nachdem der Normalisierungsprozess abgeschlossen ist, nehmen wir die letzten normalisierten Daten und geben sie als Argument an unser Modell weiter.<jupyter_code>def sigmoid(x):
    return 1 / (1 + np.exp(-x))
def run_nn(x, weights):
    output = sigmoid(np.dot(x, weights))
    return np.rint(output)
def decider(weights, CNN_decision, s_humidity, csv_path = 'temporary_data_.csv'):
    example = {
           'season': [2],
           'yr': [0], 
           'mnth': [7],
           'hr': [18], 
           'b12h_weathersit': [2],
           'b9h_weathersit': [2], 
           'b6h_weathersit': [2],
           'b3h_weathersit': [2], 
           'crnt_weathersit': [2],
           'a3h_weathersit': [2], 
           'a6h_weathersit': [2],
           'a9h_weathersit': [2], 
           'a12h_weathersit': [2],
           'temp': [0.5], 
           'atemp': [0.5],
           'hum': [s_humidity], 
           'soil_hum': [s_humidity],
           'windspeed': [0.2], 
           'CNN_decision': [CNN_decision]
          }
    # convert dictionary to pandas dataframe
    example = pd.DataFrame.from_dict(example)
    # add example to csv file
    example.to_csv(csv_path, mode='a', header=False)
    # read csv file
    rides = pd.read_csv(csv_path)
    # normalize data
    dummy_fields = ['season', 'b12h_weathersit', 'b9h_weathersit', 'b6h_weathersit', 'b3h_weathersit', 
                'crnt_weathersit', 'a3h_weathersit', 'a6h_weathersit', 'a9h_weathersit', 'a12h_weathersit', 
                'mnth', 'hr']
    for each in dummy_fields:
        dummies = pd.get_dummies(rides[each], prefix=each, drop_first=False)
        rides = pd.concat([rides, dummies], axis=1)
    fields_to_drop = ['instant',  'season', 'b12h_weathersit', 'b9h_weathersit', 'b6h_weathersit', 'b3h_weathersit', 
                    'crnt_weathersit', 'a3h_weathersit', 'a6h_weathersit', 'a9h_weathersit', 'a12h_weathersit', 
                    'mnth', 'hr', 'conclusion']
    data = rides.drop(fields_to_drop, axis=1)
#     print(data)
    # Convert dataframe to numpy and get last data from list
    data = data.to_numpy()[-1]    
    # run second model to decition
    decition = run_nn(data, weights)
    
    return decition<jupyter_output><empty_output><jupyter_text>Wir laden die Gewichte, die wir als Ergebnis des Trainings erhalten haben, in unser Modell.<jupyter_code># load trained weights from path
weights = np.loadtxt('nn_weights.csv', delimiter=',')<jupyter_output><empty_output><jupyter_text>In diesem Abschnitt werden wir die Daten, die wir von den Sensoren und der ersten künstlichen Intelligenz erhalten haben, in unser Dictionary '{}' aufnehmen. Andere Daten wurden angepasst, um das Modell nicht zu beeinflussen.<jupyter_code>decider(weights, 
        CNN_decision = get_plant_situation(cam_no=0, show_img=True),        
        s_humidity = 0.8,
        csv_path = 'temporary_data_.csv')<jupyter_output><empty_output><jupyter_text>4. ArduinoLassen Sie uns die notwendige Bibliothek importieren, um den Arduino zu steuern. Es ist notwendig, vorher die firmta-Standardbibliothek auf den Arduino hochzuladen. [Hier](https://realpython.com/arduino-python/:~:text=pySerial%3A%20Arduino%20Uno%20cannot%20run,Python%20using%20your%20own%20protocol.) finden Sie grundlegende Informationen zur Verwendung von Arduino mit Pyfirmata.<jupyter_code>import pyfirmata<jupyter_output><empty_output><jupyter_text>Schaltplan von Arduino und Sensoren<jupyter_code># connect to Arduino
board = pyfirmata.Arduino('Com4')
# get messages from Arduino
it = pyfirmata.util.Iterator(board)
it.start()
# set sensors
water_sensor = board.get_pin('a:0:i')
relay = board.get_pin('d:13:o')
%matplotlib inline

import matplotlib.pyplot as plt
from IPython import display
from IPython.display import clear_output

while True:
    # Get a plant picture from kamera
    CNN_decision = get_plant_situation(cam_no=0, path=0, show_img=True)
    plt.show()
    soil_humidity = water_sensor.read()
    decision = decider(weights, 
                       CNN_decision = CNN_decision,
                       s_humidity = 0.51,
                       csv_path = 'temporary_data_.csv'
                      )
    print("decision :", decision, "soil_humidity: ",soil_humidity, "CNN_decision", CNN_decision)
    if decision:        
        relay.write(1)
        time.sleep(150)
    elif decision==0 or soil_humidity>0.4:
        relay.write(0)
    # clear output
    clear_output(wait=True)
%%HTML
<video width="640" height="480" controls>
  <source src="test.mp4" type="video/mp4">
</video><jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.093396453502367, 'fraction_numerical': 0.019257000722137527, 'mean_word_length': 3.6420856610800745, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 56, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '615765', 'license': 'MIT', 'n_tokens_mistral': 4355, 'n_tokens_neox': 4188, 'n_words': 1141, 'path': 'Run The Project.ipynb', 'repo_name': 'coder52/equal_project', 'size': '12463'}