[PYTHON] Obstacle (noir) J'ai fait une chenille d'évitement automatique.

Ce que j'ai fait

Une chenille qui utilise un Raspeye 3b + et un appareil photo Pi pour classer les photos prises en temps réel avec SVM en «avant», «virage à droite», «virage à gauche» et «en arrière». IMG_1029.JPG

Veuillez voir ici car une image vaut mille mots. YouTube: test de la chenille d'évitement d'obstacles avec tarte aux râpes

Livres de référence

[Illustration couleur Apprenez le travail électronique avec le dernier Raspberry Pi Make et déplacez-le pour comprendre son fonctionnement (Blue Bucks)](https://www.amazon.co.jp/%E3%82%AB%E3%83%A9%E3% 83% BC% E5% 9B% B3% E8% A7% A3-Raspberry-Pi% E3% 81% A7% E5% AD% A6% E3% 81% B6% E9% 9B% BB% E5% AD% 90% E5% B7% A5% E4% BD% 9C-% E4% BD% 9C% E3% 81% A3% E3% 81% A6% E5% 8B% 95% E3% 81% 8B% E3% 81% 97% E3 % 81% A6% E3% 81% 97% E3% 81% 8F% E3% 81% BF% E3% 81% 8C% E3% 82% 8F% E3% 81% 8B% E3% 82% 8B-% E3% 83% 96% E3% 83% AB% E3% 83% BC% E3% 83% 90% E3% 83% 83% E3% 82% AF% E3% 82% B9 / dp / 4062579774 / ref = sr_1_3? __Mk_ja_JP = % E3% 82% AB% E3% 82% BF% E3% 82% AB% E3% 83% 8A & mots-clés =% E3% 83% A9% E3% 82% BA% E3% 83% 99% E3% 83% AA% E3% 83% BC% E3% 83% 91% E3% 82% A4% E3% 81% A7% E5% AD% A6% E3% 81% B6% E9% 9B% BB% E5% AD% 90% E5% B7% A5% E4% BD% 9C & qid = 1561894984 & s = hobby & sr = 1-3-catcorr)

Pour le matériel, voir le chapitre 10 + Fixez simplement la caméra Pi Pour le logiciel, reportez-vous au Chapitre 8 + Prétraitement + svm (Scikit-learn) + Enregistrer l'image pour réapprentissage

Ingéniosité

Difficile: la caméra ne filme que devant moi. Puisqu'il semble qu'il ne puisse pas être classé si l'arrière-plan est réfléchi, entrez l'image uniquement devant la chenille.

Soft ①: l'entrée dans svm est de 28x28 pixels / photo (échelle de gris) La prise de vue de la caméra Pi a été réduite à 64x64 pixels (couleur) et prétraitée à 28x28 pixels (échelle de gris). Si le prétraitement prend du temps, il y aura un décalage dans la transmission au moteur. Avec cette résolution, je n'ai pas vraiment remarqué le retard. À propos, l'image 64x64 (couleur) ressemble à ceci 1291.jpg

28x28 (échelle de gris) 1292_1_93784.jpg

Soft②: j'ai créé un mode à exécuter tout en collectant des données pour réapprendre Si SavePics est 1, continuez tout en enregistrant l'image capturée pour réapprentissage. L'image sauvegardée se déplace vers l'avant tout en étiquetant le nom du fichier selon lequel «avant», «virage à droite», «virage à gauche» et «arrière» a été jugé. Après avoir conduit, les gens peuvent facilement réapprendre les images avec la mauvaise étiquette en les divisant en dossiers et en déplaçant camera_car_preprocess.py. Environ 200 feuilles x 4 classifications prennent environ 3 minutes pour le prétraitement, et l'apprentissage est terminé en un instant, il est donc facile de faire des ajustements localement.

Soft ③: tourner à droite en reculant Si vous revenez tout droit, vous entrerez dans une boucle infinie, alors j'essaye de tourner vers la droite.

schéma

IMG_1030.JPG

code

camera_car_preprocess.py


from PIL import Image
import numpy as np
import glob
from sklearn import svm, metrics
from sklearn.model_selection import train_test_split
import pickle

ModelName = "model_20191102_9.pickle"#As you wish.

def main():
    Path = '/home/pi/document/camera_car/Train/'
    Left_L = glob.glob(Path + '1_Left/*.jpg')
    Right_L = glob.glob(Path + '2_Right/*.jpg')
    Center_L = glob.glob(Path + '0_Center/*.jpg')
    Back_L = glob.glob(Path + '3_Back/*.jpg')
    X_L = Preprocess(Left_L)
    Y_L = np.ones(int(len(X_L)/784))
    X_R = Preprocess(Right_L)
    Y_R = np.full(int(len(X_R)/784),2)
    X_C = Preprocess(Center_L)
    Y_C = np.zeros(int(len(X_C)/784))
    X_B = Preprocess(Back_L)
    Y_B = np.full(int(len(X_B)/784),3)
    
    X = np.r_[X_L, X_R, X_C, X_B]#concatinate all preprocessed pics.Toutes les combinaisons de photos pré-traitées
    X = X.reshape([int(len(X)/784),784])#make array.Matrice
    y = np.r_[Y_L, Y_R, Y_C, Y_B]#teacher data addition.Ajout de données d'enseignant
    print(X.shape)
    print(y.shape)
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=42)

    clf = svm.SVC(kernel='linear')
    clf.fit(X_train, y_train)
    pre = clf.predict(X_test)    
    ac_score = metrics.accuracy_score(y_test, pre)
    print(ac_score)#print score.Affichage de la précision

    with open(ModelName, mode='wb') as fp:
        pickle.dump(clf, fp)#save model.Sortie du modèle


def Preprocess(files):
    size = [28,28]
    array = np.empty([size[0]*size[1],0],int)
    print(array.shape)
    print(files)
    for i, file in enumerate(files):
        img = Image.open(file).convert('L')
        img = img.resize(size, Image.ANTIALIAS)
        print(img.format, img.size, img.mode,img.getextrema())
        img_arr = np.asarray(img)
        print("OD"+str(img_arr.ravel().shape))
        array = np.append(array,img_arr.ravel())
        print(array.shape)
    return array

if __name__ == '__main__':
    main()

camera_car_main.py


# -*- coding: utf-8 -*-
from picamera import PiCamera
import RPi.GPIO as GPIO
from time import sleep
from PIL import Image
import numpy as np
import os
import glob
import pickle
import shutil
import random

def Preprocess(i,SaveP):
    size = [28,28]
    array = np.empty([size[0]*size[1],0],int)
    print(array.shape)
    FullPath = glob.glob('/home/pi/document/camera_car/Predict/*.jpg')
    print(FullPath)
    #Preprocessing
    img = Image.open(FullPath[0]).convert('L')
    img = img.resize(size, Image.ANTIALIAS)
    print(img.format, img.size, img.mode,img.getextrema())
    #Make one dimention array
    img_arr = np.asarray(img)
    print("OneDimention"+str(img_arr.ravel().shape))
    if SaveP:
        os.remove(FullPath[0])
    else:#saving pics for re-training the model.Talent enregistre des photos pour Hashu
        shutil.move(FullPath[0],'/home/pi/document/camera_car/Predict/done/%s.jpg' % i)
    return img_arr.ravel(), img


PickleName = "model_20191102_9.pickle"#indicate trained model(pickle)
SavePics = 0
with open(PickleName, mode='rb') as fp:
    clf = pickle.load(fp)

camera = PiCamera()
#camera.rotation = 180#si la caméra est à l'envers Si la caméra est à l'envers
camera.resolution = (64,64)

GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.OUT)
GPIO.setup(24, GPIO.OUT)
GPIO.setup(23, GPIO.OUT)
GPIO.setup(22, GPIO.OUT)

p0 = GPIO.PWM(25, 50)#RH
p1 = GPIO.PWM(24, 50)#RH
p2 = GPIO.PWM(23, 50)#LH
p3 = GPIO.PWM(22, 50)#LH

p0.start(0)
p1.start(0)
p2.start(0)
p3.start(0)
print("start moving...")
sleep(10)
i = 0
duty = 70


#At first go forward
p0.ChangeDutyCycle(20)
p1.ChangeDutyCycle(0)
p2.ChangeDutyCycle(20)
p3.ChangeDutyCycle(0)
try:
    while True:
        #Take a pic and save to indicated folder.Prenez une photo et enregistrez-la dans le dossier spécifié
        i += 1
        camera.capture('/home/pi/document/camera_car/Predict/%s.jpg' % i)
        #preprocessing at indicated folder.Prétraitez les photos dans le dossier spécifié
        X_pred, img = Preprocess(i, SavePics)
        #prédire l'estimation
        pred = clf.predict(X_pred)
        #change duty ratio.Changement de rapport de service
        if pred[0] == 0:#Avance
            print("Forward")
            p0.ChangeDutyCycle(duty)
            p1.ChangeDutyCycle(0)
            p2.ChangeDutyCycle(duty)
            p3.ChangeDutyCycle(0)
            sleep(0.8)
        elif pred[0] == 1:#tourner à gauche à gauche
            print("Left")
            p0.ChangeDutyCycle(duty-20)
            p1.ChangeDutyCycle(0)
            p2.ChangeDutyCycle(0)
            p3.ChangeDutyCycle(20)
            sleep(0.3)
        elif pred[0] == 2:#tourner à droite à droite
            print("Right")
            p0.ChangeDutyCycle(0)
            p1.ChangeDutyCycle(20)
            p2.ChangeDutyCycle(duty-20)
            p3.ChangeDutyCycle(0)
            sleep(0.3)
        elif pred[0]  == 3:#en arrière en arrière
            p0.ChangeDutyCycle(0)
            p1.ChangeDutyCycle(duty-10)
            p2.ChangeDutyCycle(0)
            p3.ChangeDutyCycle(duty-40)
            print("Backing...")
            sleep(1)
            print("finish backing")
        #enregistrer la photo pré-traitée Enregistrer la photo pré-traitée
        if SavePics:
            pass
        else:#collect preprocessed pics with pred number.Enregistrer la photo de réapprentissage (avec valeur estimée)
            rand = random.randint(0,100000)
            img.save('/home/pi/document/camera_car/Train/'
                     +str(i)+'_'+str(int(pred[0]))+
                     '_'+str(rand)+'.jpg')

except KeyboardInterrupt:
    pass

p0.stop()
p1.stop()
GPIO.cleanup()

La structure des dossiers est

│ camera_car_main.py │ camera_car_preprocess.py │ model_20191102_8_best.pickle │ model_20191102_9.pickle ├─Predict │ └─done └─Train ├─0_Center ├─1_Left ├─2_Right └─3_Back

S'il vous plaît. Au fait, il y a deux cornichons, mais 8 était le meilleur. 9 est une version de réapprentissage de 8, mais comme elle ne fonctionne pas réellement, la capacité est inconnue.

Impressions

C'était intéressant parce que j'étais capable de réfléchir à diverses choses, du matériel à la logique et de l'implémenter, et j'ai appris la logique en pensant au réapprentissage. En guise d'amélioration, les gens doivent annoter pour réapprendre, donc l'inconvénient est que vous ne pouvez pas réapprendre sur place sans un grand écran.

Recommended Posts

Obstacle (noir) J'ai fait une chenille d'évitement automatique.
J'ai créé un installateur Ansible
J'ai créé un serveur Xubuntu.
J'ai fait un peintre discriminateur Anpanman
J'ai fait un kit de démarrage angulaire
J'ai créé une application d'analyse de fréquence en ligne
J'ai créé un module alternatif pour les japandas.
J'ai créé un outil d'estampage automatique du navigateur.
J'ai créé un package extenum qui étend enum
J'ai créé un bouton Amazon Web Service Dash
J'ai écrit un script de kit automatique pour OpenBlocks IoT
J'ai écrit un script d'installation automatique pour Arch Linux
J'ai créé une application Android qui affiche Google Map