Reconnaissance des panneaux de signalisation

La vision par ordinateur est un domaine de l'informatique qui se concentre sur la reproduction de parties d'un système de vision humaine complexe et permet aux ordinateurs d'identifier et de traiter des objets dans des images et des vidéos, ainsi que des personnes. Les premières expériences de vision par ordinateur ont commencé dans les années 1950 et ont été utilisées pour la première fois dans le commerce pour faire la distinction entre le texte imprimé et le texte manuscrit dans les années 1970. Aujourd'hui, les applications de vision par ordinateur ont connu une croissance exponentielle. Cet article montre un exemple de la façon dont vous pouvez reconnaître les panneaux de signalisation à l'aide de la vision par ordinateur.





,  KaggleGTSRB —  , (IJCNN) 2011. 50 000 43 . : , - .





.





import os
import matplotlib
import numpy as np
from PIL import Image
from tensorflow.keras.preprocessing.image import img_to_array
from sklearn.model_selection import train_test_split
from keras.utils import to_categorical
from keras.models import Sequential, load_model
from keras.layers import Conv2D, MaxPool2D, Dense, Flatten, Dropout
from tensorflow.keras import backend as K
import matplotlib.pyplot as plt
from sklearn.metrics import accuracy_score
      
      



«train», 43 . : data  labels. , , .





data = []
labels = []
      
      



, os  data  labels.  PIL.





for num in range(0, classes):
    path = os.path.join('train',str(num))
    imagePaths = os.listdir(path)
    for img in imagePaths:
      image = Image.open(path + '/'+ img)
      image = image.resize((30,30))
      image = img_to_array(image)
      data.append(image)
      labels.append(num)
      
      



30×30  data  labels.





 numpy  .





data = np.array(data)
labels = np.array(labels)
      
      



- (39209, 30, 30, 3), , 39 209 30×30 , 3 , ( RGB).





print(data.shape, labels.shape)
(39209, 30, 30, 3) (39209,)
      
      



sklearn



train_test_split()



, 80% 20% . .





X_train, X_test, y_train, y_test = train_test_split(data, labels, test_size=0.2, random_state=42)
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
(31367, 30, 30, 3) (7842, 30, 30, 3) (31367,) (7842,) 
      
      



, .





def cnt_img_in_classes(labels):
    count = {}
    for i in labels:
        if i in count:
            count[i] += 1
        else:
            count[i] = 1
    return count

samples_distribution = cnt_img_in_classes (y_train)

def diagram(count_classes):
    plt.bar(range(len(dct)), sorted(list(count_classes.values())), align='center')
    plt.xticks(range(len(dct)), sorted(list(count_classes.keys())), rotation=90, fontsize=7)
    plt.show()
diagram(samples_distribution)
      
      



Diagramme de distribution

, , , .





def aug_images(images, p):
    from imgaug import augmenters as iaa
    augs =  iaa.SomeOf((2, 4),
          [
              iaa.Crop(px=(0, 4)), 
              iaa.Affine(scale={"x": (0.8, 1.2), "y": (0.8, 1.2)}),
              iaa.Affine(translate_percent={"x": (-0.2, 0.2), "y": (-0.2, 0.2)}),
              iaa.Affine(rotate=(-45, 45))
              iaa.Affine(shear=(-10, 10))
])
    
    seq = iaa.Sequential([iaa.Sometimes(p, augs)])
    res = seq.augment_images(images)
    return res

def augmentation(images, labels):
    min_imgs = 500
    classes = cnt_img_in_classes(labels)
    for i in range(len(classes)):
        if (classes[i] < min_imgs):
            add_num = min_imgs - classes[i]
            imgs_for_augm = []
            lbls_for_augm = []
            for j in range(add_num):
                im_index = random.choice(np.where(labels == i)[0])
                imgs_for_augm.append(images[im_index])
                lbls_for_augm.append(labels[im_index])
            augmented_class = augment_imgs(imgs_for_augm, 1)
            augmented_class_np = np.array(augmented_class)
            augmented_lbls_np = np.array(lbls_for_augm)
            imgs = np.concatenate((images, augmented_class_np), axis=0)
            lbls = np.concatenate((labels, augmented_lbls_np), axis=0)
    return (images, labels)
X_train, y_train = augmentation(X_train, y_train)
      
      



.





print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
(36256, 30, 30, 3) (7842, 30, 30, 3) (36256,) (7842,)
      
      



.





augmented_samples_distribution = cnt_img_in_classes(y_train)
diagram(augmented_samples_distribution)
      
      



Diagramme de distribution après augmentation

, . keras.utils



to_categorical



, y_train



t_test



, one-hot encoding.





y_train = to_categorical(y_train, 43)
y_test = to_categorical(y_test, 43)
      
      



 Keras]. , CNN ( ). CNN .





:





  • 2 Conv2D (filter=32, kernel_size=(5,5), activation=”relu”)





  • MaxPool2D ( pool_size=(2,2))





  • Dropout (rate=0.25)





  • 2 Conv2D (filter=64, kernel_size=(3,3), activation=”relu”)





  • MaxPool2D ( pool_size=(2,2))





  • Dropout (rate=0.25)





  • Flatten , 1





  • Dense (500, activation=”relu”)





  • Dropout (rate=0.5)





  • Dense (43, activation=”softmax”)





class Net:
  @staticmethod
  def build(width, height, depth, classes):
    model = Sequential()
    inputShape = (height, width, depth)
    if K.image_data_format() == 'channels_first':
      inputShape = (depth, heigth, width)
    model = Sequential()
    model.add(Conv2D(filters=32, kernel_size=(5,5), activation='relu', input_shape=inputShape))
    model.add(Conv2D(filters=32, kernel_size=(5,5), activation='relu'))
    model.add(MaxPool2D(pool_size=(2, 2)))
    model.add(Dropout(rate=0.25))
    model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu'))
    model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu'))
    model.add(MaxPool2D(pool_size=(2, 2)))
    model.add(Dropout(rate=0.25))
    model.add(Flatten())
    model.add(Dense(500, activation='relu'))
    model.add(Dropout(rate=0.5))
    model.add(Dense(classes, activation='softmax'))
    return model
      
      



Adam



, — categorical_crossentropy



, . model.fit()



.





epochs = 25
model = Net.build(width=30, height=30, depth=3, classes=43)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
history = model.fit(X_train, y_train, batch_size=64, validation_data=(X_test, y_test), epochs=epochs)
      
      



, 25 93% . matplotlib



.





plt.style.use("plot")
plt.figure()
N = epochs
plt.plot(np.arange(0, N), history.history["loss"], label="train_loss")
plt.plot(np.arange(0, N), history.history["val_loss"], label="val_loss")
plt.plot(np.arange(0, N), history.history["accuracy"], label="train_acc")
plt.plot(np.arange(0, N), history.history["val_accuracy"], label="val_acc")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch")
plt.ylabel("Loss/Accuracy")
plt.legend(loc="lower left")
plt.show()
      
      



Perte et précision de l'entraînement
Training Loss and Accuracy

L'ensemble de données contient un dossier «Test» et le fichier Test.csv



contient des informations associées au chemin de l'image et aux étiquettes de classe. Nous extrayons le chemin d'accès à l'image et aux étiquettes du fichier Test.csv



à l'aide du framework Pandas



. Ensuite, nous redimensionnons l'image à 30x30 pixels et créons un tableau numpy



contenant toutes les données d'image. En utilisant accuracy_score



from, nous sklearn metrics



vérifions l'exactitude des prédictions de notre modèle. Nous avons atteint une précision de 96% sur ce modèle.





y_test = pd.read_csv('Test.csv')
labels = y_test["ClassId"].values
imgs = y_test["Path"].values

images=[]

for img in imgs:
    image = Image.open(img)
    image = image.resize((30,30))
    images.append(img_to_array(image))

X_test=np.array(images)
pred = model.predict_classes(X_test)
print(accuracy_score(labels, pred))
0.958590657165479
      
      






All Articles