Sistema de detecção de sonolência do motorista usando Raspberry Pi e OpenCV
Os motoristas de caminhão que transportam cargas e materiais pesados por longas distâncias durante o dia e a noite, muitas vezes sofrem de falta de sono. fadiga e sonolência são algumas das principais causas de acidentes graves em rodovias. As indústrias automobilísticas estão trabalhando em algumas tecnologias que possam detectar a sonolência e alertar o motorista sobre ela.
Neste projeto, vamos construir um sistema de detecção e alerta de sono para motoristas usando o módulo de câmera Raspberry Pi, OpenCV e Pi. O objetivo básico deste sistema é rastrear a condição facial do motorista e os movimentos dos olhos e se o motorista estiver se sentindo sonolento, o sistema irá disparar uma mensagem de aviso. Esta é a extensão do nosso aplicativo anterior de detecção de pontos de referência facial e reconhecimento de rosto.
Componentes necessários
Componentes de hardware
Raspberry Pi 3
Módulo de câmera Pi
Cabo Micro USB
Campainha
Software e serviços online
OpenCV
Dlib
Python3
Antes de prosseguir com este projeto de detecção de sonolência do motorista, primeiro, precisamos instalar OpenCV, imutils, dlib, Numpy e algumas outras dependências neste projeto. OpenCV é usado aqui para processamento de imagem digital. As aplicações mais comuns de processamento digital de imagens são detecção de objetos, reconhecimento facial e contador de pessoas.
Aqui, estamos usando apenas Raspberry Pi, Pi Camera e uma campainha para construir este sistema de detecção de sono.
Instalando OpenCV no Raspberry Pi
Antes de instalar o OpenCV e outras dependências, o Raspberry Pi precisa ser totalmente atualizado. Use os comandos abaixo para atualizar o Raspberry Pi para sua versão mais recente:
sudo apt-get update
Em seguida, use os seguintes comandos para instalar as dependências necessárias para instalar o OpenCV em seu Raspberry Pi.
sudo apt-get install libhdf5-dev -y
sudo apt-get install libhdf5-serial-dev –y
sudo apt-get install libatlas-base-dev –y
sudo apt-get install libjasper-dev -y
sudo apt-get install libqtgui4 –y
sudo apt-get install libqt4-test –y
Finalmente, instale o OpenCV no Raspberry Pi usando os comandos abaixo.
pip3 install opencv-contrib-python==4.1.0.25
Se você é novo no OpenCV, verifique nossos tutoriais anteriores do OpenCV com Raspberry pi:
Instalando OpenCV no Raspberry Pi usando CMake
Reconhecimento facial em tempo real com Raspberry Pi e OpenCV
Reconhecimento de matrículas usando Raspberry Pi e OpenCV
Estimativa do tamanho da multidão usando OpenCV e Raspberry Pi
Também criamos uma série de tutoriais OpenCV começando no nível iniciante.
Instalando outros pacotes necessários
Antes de programar o Raspberry Pi para detecção de sonolência, vamos instalar os outros pacotes necessários.
Instalando dlib: dlib é o kit de ferramentas moderno que contém algoritmos e ferramentas de aprendizado de máquina para problemas do mundo real. Use o comando abaixo para instalar o dlib.
pip3 install dlib
Instalando NumPy: NumPy é a biblioteca central para computação científica que contém um poderoso objeto de matriz n-dimensional, fornece ferramentas para integrar C, C ++, etc.
pip3 install numpy
Instalando o módulo face_recognition: esta biblioteca é usada para reconhecer e manipular faces do Python ou da linha de comando. Use o comando abaixo para instalar a biblioteca de reconhecimento facial.
Pip3 install face_recognition
E por último, instale a biblioteca eye_game usando o comando abaixo:
pip3 install eye-game
Programando o Raspberry Pi
O código completo para detecção de sonolência do motorista usando OpenCV é fornecido no final da página. Aqui estamos explicando algumas partes importantes do código para melhor compreensão.
Portanto, como de costume, inicie o código incluindo todas as bibliotecas necessárias.
import face_recognition
import cv2
import numpy as np
import time
import cv2
import RPi.GPIO as GPIO
import eye_game
Depois disso, crie uma instância para obter o feed de vídeo da câmera pi. Se você estiver usando mais de uma câmera, substitua zero por um na função cv2.VideoCapture (0).
video_capture = cv2.VideoCapture(0)
Agora, nas próximas linhas, insira o nome e o caminho do arquivo. No meu caso, o código e o arquivo estão na mesma pasta. Em seguida, use as codificações de rosto para obter a localização do rosto na imagem.
img_image = face_recognition.load_image_file("img.jpg")
img_face_encoding = face_recognition.face_encodings(img_image)[0]
Depois disso, crie dois arrays para salvar os rostos e seus nomes. Estou usando apenas uma imagem. você pode adicionar mais imagens e seus caminhos no código.
known_face_encodings = [
img_face_encoding ]
known_face_names = [
"Ashish"
]
Em seguida, crie algumas variáveis para armazenar as localizações das partes da face, nomes das faces e codificações.
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True
Dentro da função while, capture os quadros de vídeo do streaming e redimensione os quadros para um tamanho menor e também converta o quadro capturado para a cor RGB para reconhecimento de rosto.
ret, frame = video_capture.read()
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
rgb_small_frame = small_frame[:, :, ::-1]
Depois disso, execute o processo de reconhecimento de rosto para comparar os rostos no vídeo com a imagem. E também obter as localizações das peças faciais.
if process_this_frame:
face_locations = face_recognition.face_locations(rgb_small_frame)
face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
cv2.imwrite(file, small_frame)
Se o rosto reconhecido corresponder ao rosto na imagem, chame a função eyegame para rastrear os movimentos dos olhos. O código rastreará repetidamente a posição do olho e do globo ocular.
face_distances = face_recognition.face_distance(known_face_encodings,
face_encoding)
best_match_index = np.argmin(face_distances)
if matches[best_match_index]:
name = known_face_names[best_match_index]
direction= eye_game.get_eyeball_direction(file)
print(direction)
Se o código não detectar nenhum movimento dos olhos por 10 segundos, ele acionará o alarme para acordar a pessoa.
else:
count=1+count
print(count)
if (count>=10):
GPIO.output(BUZZER, GPIO.HIGH)
time.sleep(2)
GPIO.output(BUZZER, GPIO.LOW)
print("Alert!! Alert!! Driver Drowsiness Detected ")
Em seguida, use as funções OpenCV para desenhar um retângulo ao redor do rosto e colocar um texto nele. Além disso, mostre os quadros de vídeo usando a função cv2.imshow.
cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 255, 0),
cv2.FILLED)
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (0, 0, 255),
1)
cv2.imshow('Video', frame)
Set the Key ‘S’ to stop the code.
if cv2.waitKey(1) & 0xFF == ord('s'):
break
Teste do sistema de detecção de sonolência do motorista
Quando o código estiver pronto, conecte a câmera Pi e a campainha ao Raspberry Pi e execute o código. Após aproximadamente 10 segundos, uma janela aparecerá com a transmissão ao vivo de sua câmera Raspberry Pi. Quando o dispositivo reconhecer o rosto, ele imprimirá seu nome na moldura e começará a rastrear o movimento dos olhos. Agora feche os olhos por 7 a 8 segundos para testar o alarme. Quando a contagem chegar a mais de 10, será acionado um alarme, alertando sobre a situação.
É assim que você pode construir a detecção de sonolência usando OpenCV e Raspberry Pi. Role para baixo para ver o vídeo de trabalho e o código.
import face_recognition
import cv2
import numpy as np
import time
import cv2
import eye_game
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
BUZZER= 23
GPIO.setup(BUZZER, GPIO.OUT)
previous ="Unknown"
count=0
video_capture = cv2.VideoCapture(0)
#frame = (video_capture, file)
file = 'image_data/image.jpg'
# Load a sample picture and learn how to recognize it.
img_image = face_recognition.load_image_file("img.jpg")
img_face_encoding = face_recognition.face_encodings(img_image)[0]
# Create arrays of known face encodings and their names
known_face_encodings = [
img_face_encoding
]
known_face_names = [
"Ashish"
]
# Initialize some variables
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True
while True:
# Grab a single frame of video
ret, frame = video_capture.read()
# Resize frame of video to 1/4 size for faster face recognition processing
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
# Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
rgb_small_frame = small_frame[:, :, ::-1]
# Only process every other frame of video to save time
if process_this_frame:
# Find all the faces and face encodings in the current frame of video
face_locations = face_recognition.face_locations(rgb_small_frame)
face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
cv2.imwrite(file, small_frame)
face_names = []
for face_encoding in face_encodings:
# See if the face is a match for the known face(s)
matches = face_recognition.compare_faces(known_face_encodings, face_encoding)
name = "Unknown"
face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
best_match_index = np.argmin(face_distances)
if matches[best_match_index]:
name = known_face_names[best_match_index]
direction= eye_game.get_eyeball_direction(file)
print(direction)
#eye_game.api.get_eyeball_direction(cv_image_array)
if previous != direction:
previous=direction
else:
print("old same")
count=1+count
print(count)
if (count>=10):
GPIO.output(BUZZER, GPIO.HIGH)
time.sleep(2)
GPIO.output(BUZZER, GPIO.LOW)
print("Alert!! Alert!! Driver Drowsiness Detected")
cv2.putText(frame, "DROWSINESS ALERT!", (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
face_names.append(name)
process_this_frame = not process_this_frame
# Display the results
for (top, right, bottom, left), name in zip(face_locations, face_names):
# Scale back up face locations since the frame we detected in was scaled to 1/4 size
top *= 4
right *= 4
bottom *= 4
left *= 4
# Draw a box around the face
cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
# Draw a label with a name below the face
cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (0, 0, 255), 1)
#cv2.putText(frame, frame_string, (left + 10, top - 10), font, 1.0, (255, 255, 255), 1)
# Display the resulting image
cv2.imshow('Video', frame)
# Hit 'q' on the keyboard to quit!
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Release handle to the webcam
video_capture.release()
cv2.destroyAllWindows()