L'environnement d'exécution de cet article est collaboratif.
** L'objectif de cette fois **
Tout d'abord, jetez un œil au produit fini téléchargé sur YouTube. Traffic Safety-kun
table des matières
** 1, préparation préalable ** ① Prenez une vidéo avec votre smartphone à un endroit avec un panneau de signalisation. L'effet d'une qualité d'image élevée est bon. (1920 * 1080, 30FPS dans mon cas) ** Faites attention à la sécurité routière lorsque vous prenez des vidéos! ** ** (2) Créez des voix d'avertissement pour "Arrêt", "Feu rouge" et "Aucune entrée" Je l'ai créé avec gTTS, bien sûr, vous pouvez enregistrer votre propre voix.
makeAudio_Arrêtez.ipynb
from gtts import gTTS #Google Text to Speech
from google import colab
#Monter Google Drive
colab.drive.mount('/content/gdrive')
path="gdrive/My Drive/make_video/"
word="Arrête ça"
tts = gTTS(word,lang='ja') #Provide the string to convert to speech
tts.save(path+'STOP_2.wav') #save the string converted to speech as a .wav file
Audio(path+'STOP_2.wav')
③ Préparez des images de panneaux de signalisation (feu rouge, feu vert, arrêt, pas d'entrée, ciel bleu). (2, utilisé pour l'apprentissage en profondeur des panneaux de signalisation)
Téléchargez des images à partir de la recherche d'images de Google.
python:1.getImage_STOP.ipynb
#Prendre une image d'un arrêt
!apt-get update
!apt install chromium-chromedriver
!cp /usr/lib/chromium-browser/chromedriver /usr/bin
!pip install selenium
import urllib.request as req
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
from selenium.webdriver.common.keys import Keys
from google import colab
colab.drive.mount('/content/gdrive')
#Lancez le navigateur en mode sans tête et affichez le site Web
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome('chromedriver',options=options)
driver.implicitly_wait(10)
count=1
tempImageCount=0
#Spécification de l'URL cible
driver.get("https://www.google.com/search?rlz=1C1CAFC_enJP862JP870&biw=1366&bih=657&tbm=isch&sxsrf=ACYBGNSNeQ5IaB9V8b-6pc6q9gOtbrY4Uw%3A1577968008026&sa=1&ei=iOENXoiRAfCSr7wP-8ee0As&q=%E6%AD%A2%E3%81%BE%E3%82%8C%E6%A8%99%E8%AD%98&oq=%E6%AD%A2%E3%81%BE%E3%82%8C%E6%A8%99%E8%AD%98&gs_l=img.3..0l2j0i24l8.144019.154252..155304...3.0..0.429.5395.0j1j5j10j1......0....1..gws-wiz-img.......0i4i37j35i39j0i23j0i4i37i24.zXhLgCDtIBY&ved=0ahUKEwiI9db09OTmAhVwyYsBHfujB7oQ4dUDCAc&uact=5")
time.sleep(3)
while True:
#acquisition de liste d'images
image_list = driver.find_elements_by_class_name('rg_ic')
print(len(image_list))
#ScrollBar en bas
driver.find_element_by_tag_name('body').send_keys(Keys.END)
if len(image_list) > tempImageCount:
tempImageCount = len(image_list)
print('------------------- go to next page --------------------------')
try:
#Afficher le bouton "Afficher plus de résultats"
driver.find_element_by_id('smb').click()
print('------------------- click success --------------------------')
except:
driver.find_element_by_tag_name('body').send_keys(Keys.END)
print('------------------- KEY END --------------------------')
else:
break
#acquisition de liste d'images
image_list = driver.find_elements_by_class_name('rg_ic')
print(len(image_list))
for image in image_list:
#Obtenir l'URL de l'image
image_url = image.get_attribute('src')
#Enregistrer l'image
try:
image = req.urlopen(image_url).read()
with open('gdrive/My Drive/image/Sécurité routière/Arrêtez/'+str(count)+'.jpg',mode='wb') as f:
f.write(image)
print('download - {}'.format(count))
count += 1
except:
print('cant open url')
driver.quit()
Choisissons un bon parmi les images acquises. (Autant que possible, 20 ou plus) Bon exemple: (sans arrière-plan) Exemple NG:
** 2, panneau de signalisation Deep Learning **
① Convertir le fichier image au format Numpy
Les données de l'ensemble de données "MNIST" sont un tableau de (28,28) comme indiqué ci-dessous. En imitant ↑, redimensionnez d'abord le fichier image en un carré de 50 * 50 puis convertissez-le au format Numpy. Puisqu'il s'agit d'un mode couleur RVB, ce sera un tableau de (50,50,3).
to_Dat.ipynb
import cv2
import os
from sklearn.model_selection import train_test_split
from PIL import Image
import os,glob
import numpy as np
from google import colab
colab.drive.mount('/content/gdrive')
!ls 'gdrive/My Drive'
#Sélectionnez une catégorie de classification
root_dir = 'gdrive/My Drive/image/Sécurité routière-kun 2/'
train_dir = 'gdrive/My Drive/data/'
groups = ['Lumière verte','une manière','Arrêtez','Entrée interdite','lumière rouge','ciel bleu']
nb_classes = len(groups)
image_size = 50
#Convertir les données d'image au format Numpy
#Lire les données d'image pour chaque dossier
X = []
Y = []
#Puisqu'il y a peu d'images, laissez-les étudier la même image 20 fois. Les humains se souviennent des choses encore et encore, est-ce que Deeplearning est la même chose?
for i in range(0,20,1):
for idx,group in enumerate(groups):
image_dir = root_dir + group
files = glob.glob(image_dir+'/*.jpg')
for i,f in enumerate(files):
img = Image.open(f)
img = img.convert('RGB') #Passer en mode RVB
img = img.resize((image_size,image_size))#50*Redimensionner à 50
data = np.asarray(img)
X.append(data)
Y.append(idx)
X = np.array(X)
Y = np.array(Y)
X_train,X_test,y_train,y_test = train_test_split(X,Y,random_state=0)
xy = (X_train,X_test,y_train,y_test)
np.save('gdrive/My Drive/data/Sécurité routière-kun 2.npy', xy)
print(X_train.shape[1:])
print('ok',len(Y))
② Apprentissage avec un réseau neuronal Présentant la technique de "Convolution", veuillez vous référer à l'URL suivante. Qu'est-ce qu'un réseau neuronal convolutif? La procédure est également expliquée avec soin Après avoir appliqué un filtre bidimensionnel aux données d'image comme indiqué dans ↑, vous pouvez accentuer les lignes horizontales et verticales, ce qui peut considérablement améliorer le taux de réussite.
deeplearning.ipynb
!pip install keras==2.2.4
import keras
from google import colab
colab.drive.mount('/content/gdrive')
!ls 'gdrive/My Drive'
import numpy as np
from keras.datasets import mnist
from keras.utils import np_utils
#Lire les données enregistrées en cours ①
x_train,x_test,y_train,y_test = np.load('gdrive/My Drive/data/Sécurité routière-kun 2.npy', mmap_mode=None, allow_pickle=True , fix_imports=True, encoding='ASCII')
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
num_classes = 10
y_train = np_utils.to_categorical(y_train, num_classes)
y_test = np_utils.to_categorical(y_test, num_classes)
#réseau neuronal
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.optimizers import Adam
import time
model = Sequential()
model.add(Conv2D(50, (3, 3),
input_shape=(50, 50, 3), activation='relu')) #Pliage ①
model.add(Conv2D(32, (3, 3), activation='relu')) #Pliage ②
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu')) ##Pliage ③
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer=Adam(),
metrics=['accuracy'])
startTime = time.time()
history = model.fit(x_train, y_train, batch_size=3000, epochs=20,
verbose=1, validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
#loss
print('loss:', score[0])
#taux de réussite
print('accuracy:', score[1])
#Temps d'étude
print("Computation time:{0:.3f} sec".format(time.time() - startTime))
#Enregistrer le modèle entraîné
model.save('gdrive/My Drive/model/Sécurité routière.h5')
Le taux de réussite est de 0,98, ce qui est un bon sentiment. loss: 0.11440953898268777 accuracy: 0.9878378378378379 Computation time:46.734 sec
** 3, analyser la vidéo et détecter la lumière rouge, arrêter, trame sans entrée **
① Comment découpez-vous l'image du signe de la photo réelle et l'identifiez-vous avec le modèle formé?
J'ai évoqué ce qui suit. [Python / OpenCV] Détecter les objets en mouvement avec le suivi des couleurs
Obtenez le plus gros blob.ipynb
#Analyse Blob
def analysis_blob(binary_img):
#Processus d'étiquetage d'image binaire
label = cv2.connectedComponentsWithStats(binary_img)
#Extraire les informations sur l'objet blob élément par élément
n = label[0] - 1
data = np.delete(label[2], 0, 0)
center = np.delete(label[3], 0, 0)
if len(center) <= 0:
return
#Index avec la plus grande zone de blob
max_index = np.argmax(data[:, 4])
return center[max_index]
Méthode de prédiction.ipynb (les arguments sont le fichier image et les coordonnées)
def predictWithModel(image_file, x_from, y_from, x_to, y_to):
image_size = 50
X1 = []
#garniture
img_crop = image_file[y_from : y_to, x_from: x_to]
img_crop = cv2.cvtColor(img_crop, cv2.COLOR_BGR2RGB)
img_crop = cv2.resize(img_crop, (image_size,image_size))#Changer la taille de l'image
X1.append(img_crop)#Image en tant que vecteur
X1 = np.array(X1)
x_test = X1.astype('float32')
x_test /= 255
y = model.predict(x_test) #Prévoir
wk = y[0, :]
wk_sort = np.sort(wk)
wk_sort = wk_sort[::-1]
max_indx = -1
max_pcnt = -1
if float(wk_sort[0]) > 0.9 and np.argmax(wk) != 5 and np.argmax(wk) != 0:
max_pcnt = float(wk_sort[0])
max_indx = np.argmax(wk)
#print(max_indx)
#print(max_pcnt)
return max_indx, max_pcnt
Méthode d'ajustement des coordonnées.ipynb (la lumière rouge est rectangulaire, stop et aucune entrée n'est carrée)
def adjustSize(height, width, center_x, center_y, div_size, div_size_w, kbn):
if kbn == 1:
#Rectangle
x_from = center_x - div_size_w*3//4
x_to = x_from + div_size_w
y_from = center_y - div_size//2
y_to = y_from + div_size
else:
#carré
x_from = center_x - div_size//2
x_to = x_from + div_size
y_from = center_y - div_size//2
y_to = y_from + div_size
if x_from < 0:
x_from = 0
if y_from < 0:
y_from = 0
if x_to >= width:
x_to = width
if y_to >= height:
y_to = height
return x_from, y_from, x_to, y_to
Analyse de fichier image.ipynb
def predictImage3(argimg):
#Chargez l'image.
height, width, channels = argimg.shape[:3]
#Recadrage de l'image (le panneau de signalisation se trouve dans la moitié supérieure, analysez donc uniquement la moitié supérieure)
img = argimg[0:height//2,0:width//2,::]
#Conversion en espace colorimétrique HSV.
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
#Extrayez la bordure rouge par binarisation.
binary = cv2.inRange(hsv, (145, 70, 0), (180, 255, 255))
if len(binary) <= 0:
return argimg,-1
#Éteignez le bruit avec OPENING.
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
eroded = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
#Analyse blob de l'image de masque (acquérir des informations blob de la zone maximale)
center = analysis_blob(eroded)
if center is None:
return argimg,-1
#Obtenir les coordonnées du centre
center_x = int(center[0])
center_y = int(center[1])
#Premier rectangulaire
x_from, y_from, x_to, y_to = adjustSize(height, width, center_x, center_y, 60, 100, 1)
max_indx, max_pcnt = predictWithModel(img, x_from, y_from, x_to, y_to)
#Place de la recherche
x_from2, y_from2, x_to2, y_to2 = adjustSize(height, width, center_x, center_y, 50, 100, 0) max_indx2, max_pcnt2 = predictWithModel(img, x_from2, y_from2, x_to2, y_to2)
#Rectangle 2 (ajuster la taille)
x_from3, y_from3, x_to3, y_to3 = adjustSize(height, width, center_x, center_y, 40, 80, 1)
max_indx3, max_pcnt3 = predictWithModel(img, x_from3, y_from3, x_to3, y_to3)
pcnt = [max_pcnt, max_pcnt2, max_pcnt3]
indx = [max_indx, max_indx2, max_indx3]
max = np.argmax(pcnt)
max_index = -1
if indx[max] == 2:
text="Arrêtez"
elif indx[max] == 4:
text="lumière rouge"
elif indx[max] == 3:
text="Entrée interdite"
else:
text=""
if indx[max] > 0:
#Tracez un cercle autour du centre de la goutte maximale sur le cadre
cv2.circle(argimg, (center_x, center_y), 80, (0, 200, 0),thickness=3, lineType=cv2.LINE_AA)
fontpath ='gdrive/My Drive/font/MSMINCHO.TTC' #Police de caractère
font = ImageFont.truetype(fontpath, 128) #taille de police
img_pil = Image.fromarray(argimg) #8 bits chaque valeur du tableau(1byte)Type entier(0~255)Vers l'image PIL.
draw = ImageDraw.Draw(img_pil) #Créer une instance de dessin
position = (center_x, center_y + 100) #Position d'affichage du texte
draw.text(position, text, font = font , fill = (0,0,255,0) ) #Écrire du texte dans le remplissage de dessin:Couleur BGRA(RGB)
max_index = indx[max]
return np.array(img_pil),max_index #Convertir PIL en tableau
return argimg,max_index
Après avoir préparé la méthode ci-dessus, analysez la vidéo préparée
Analyser la vidéo.ipynb
import cv2
from google.colab.patches import cv2_imshow
from PIL import ImageFont, ImageDraw, Image
target_dir = 'gdrive/My Drive/target/Sécurité routière-kun 2/'
files = glob.glob(target_dir+'/src_*.mp4')
target_avi_file = target_dir + "output.avi"
output_file = target_dir + "output.mp4"
#Créez un VideoWriter.
fourcc = cv2.VideoWriter_fourcc(*"DIVX")
writer = cv2.VideoWriter(target_avi_file, fourcc, 30, (1920, 1080))
frame_cnt=0
fame_index_result=np.empty((0,2), int)
for i,f in enumerate(files):
#Créez un VideoCapture.
cap = cv2.VideoCapture(f)
temp=np.empty((0,2), int)
while True:
#Obtenez image par image.
ret, frame = cap.read()
if not ret:
break #Si l'acquisition d'images échoue ou si la fin de la vidéo est atteinte
frame_cnt+=1
frame,index = predictImage3(frame)
if index > 0:
temp = np.append(temp, np.array([[frame_cnt,index]]), axis=0)
writer.write(frame) #Écrivez un cadre.
#Panneau de signalisation Enregistrez la première image reconnue (= moment pour insérer la voix)
index_cnt = [np.count_nonzero(temp[:,1] == 2),np.count_nonzero(temp[:,1] == 3),np.count_nonzero(temp[:,1] == 4)]
max_index = [2,3,4][np.argmax(index_cnt)]
fame_index_result = np.append(fame_index_result, np.array([(temp[temp[:,1] == max_index])[0]]), axis=0)
writer.release()
cap.release()
** 4, placez l'audio dans l'image détectée **
Ajouter de l'audio.ipynb
!pip -q install pydub
!apt install libasound2-dev portaudio19-dev libportaudio2 libportaudiocpp0 ffmpeg
!pip install pyaudio
import cv2
import pyaudio
import sys
import time
import wave
import pydub
from pydub import AudioSegment
import moviepy.editor as mp
import datetime
temp_file = target_dir + "temp.mp4"
# Add audio to output video.
clip_output = mp.VideoFileClip(target_avi_file).subclip()
clip_output.write_videofile(temp_file, audio=mp3_file)
cap = cv2.VideoCapture(target_avi_file)
video_frame = cap.get(cv2.CAP_PROP_FRAME_COUNT) #Obtenez le nombre d'images
video_fps = cap.get(cv2.CAP_PROP_FPS) #Obtenez FPS
video_len_sec = video_frame / video_fps #Calculer la longueur (secondes)
print(video_len_sec)
video = mp.VideoFileClip(temp_file).subclip(0,video_len_sec)
video.write_videofile(output_file)
mp3_stop_file_2="gdrive/My Drive/mp3/stop_2.wav"
mp3_stop_file_3="gdrive/My Drive/mp3/stop_3.wav"
mp3_stop_file_4="gdrive/My Drive/mp3/stop_4.wav"
videos = np.empty((0), mp.VideoFileClip)
startSec=0
temp_file2 = target_dir + "temp2.mp4"
#Insérer une voix pour chaque image de panneau de signalisation
for idx in range(fame_index_result.shape[0]):
if fame_index_result[idx][1] == 2:
mp3_stop_file = mp3_stop_file_2
elif fame_index_result[idx][1] == 3:
mp3_stop_file = mp3_stop_file_3
elif fame_index_result[idx][1] == 4:
mp3_stop_file = mp3_stop_file_4
base_sound = AudioSegment.from_file(mp3_stop_file)
length_seconds = base_sound.duration_seconds #Vérifiez la longueur de la voix
#Tout d'abord, coupez de 0 au cadre du panneau de signalisation
video_len_sec_temp = fame_index_result[idx][0] / video_fps
videos = np.append(videos, np.array([mp.VideoFileClip(temp_file).subclip(startSec,video_len_sec_temp)]), axis=0)
#Faites correspondre la longueur de l'audio, découpez une vidéo de la même longueur et insérez l'audio
clip_output = mp.VideoFileClip(temp_file).subclip(video_len_sec_temp, video_len_sec_temp+length_seconds)
clip_output.write_videofile(temp_file2, audio=mp3_stop_file)
#Vidéo restante
videos = np.append(videos, np.array([mp.VideoFileClip(temp_file2).subclip()]), axis=0)
if idx == fame_index_result.shape[0] - 1:
last_sec = video_len_sec
else:
last_sec = fame_index_result[idx+1][0] / video_fps
if video_len_sec_temp+length_seconds < last_sec:
videos = np.append(videos, np.array([mp.VideoFileClip(temp_file).subclip(video_len_sec_temp+length_seconds, last_sec)]), axis=0)
startSec = last_sec
#Concaténer les vidéos éditées
final_clip = mp.concatenate_videoclips(videos)
final_clip.write_videofile(output_file)
Recommended Posts