![1PbxNpY0TzgdD7alejuFjQQ.gif](https://quantinsightsnetwork.com/wp-content/uploads/2024/07/1PbxNpY0TzgdD7alejuFjQQ-678x381.gif)
A comunicação em Libras é vital para milhões de brasileiros surdos, mas a barreira entre surdos e ouvintes ainda é significativa. Este projeto de Reconhecimento de Sinais em Libras com MediaPipe e Redes Neurais foi motivado pelo desejo de promover inclusão e acessibilidade. Usando tecnologias de IA, podemos criar sistemas que interpretam Libras em tempo real, facilitando uma comunicação mais fluida e eficaz. Este guia completo mostra como desenvolvi essa solução e destaca a importância dessas tecnologias para a inclusão social.
Para desenvolver o projeto de Reconhecimento de Sinais em Libras, utilizei um conjunto robusto de ferramentas e bibliotecas. Cada uma desempenhou um papel crucial no processo, desde a coleta de dados até o treinamento da rede neural e a implementação do sistema de reconhecimento em tempo real.
TensorFlow
TensorFlow é uma das bibliotecas mais populares para machine learning e deep learning. Utilizei o TensorFlow para construir e treinar a rede neural artificial responsável pelo reconhecimento dos sinais em Libras. Sua flexibilidade e eficiência permitem o desenvolvimento de modelos complexos de maneira intuitiva e eficaz.
Scikit-Learn
scikit-learn é uma biblioteca essencial para machine learning em Python. Embora seja mais conhecida por algoritmos de aprendizado supervisionado, utilizei o scikit-learn principalmente para a normalização dos dados e a avaliação do desempenho do modelo.
MediaPipe
MediaPipe é uma biblioteca desenvolvida pelo Google que facilita a implementação de pipelines de processamento multimodal. Utilizei o MediaPipe para a detecção e extração de pontos-chave das mãos em imagens.
OpenCV (cv2)
OpenCV é uma biblioteca de visão computacional de código aberto. Utilizei o OpenCV para manipulação de imagens e vídeos, incluindo a captura de frames e a pré-processamento das imagens antes de passá-las para o MediaPipe.
Captura dos vídeos
Utilize a biblioteca OpenCV para coletar imagens de uma webcam da seguinte maneira
import cv2cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# Inverter o vídeo horizontelmente
frame = cv2.flip(frame, 1)
# Converter a imagem de BRG para RGB
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# Mostrar a imagem capturada em tempo real
cv2.imshow('WebCam', frame)
Extração de Pontos-Chave
Após a captura dos vídeos, utilizei o MediaPipe para extrair os pontos-chave das mãos de cada frame do vídeo. o MediaPipe fornece coordenadas dos pontos principais das mãos, como articulações dos dedos e punho.
Este processo foi feito da seguinte forma
import cv2
import mediapipe as mp
import csvcap = cv2.VideoCapture(0)
csv_header = ['y'] + [f'keypoint_{i}_{axis}' for i in range(21) for axis in ['x', 'y', 'z']]
csv_path = "dataset.csv"
# Iniciando o mediapipe
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(min_detection_confidence=0.7, min_tracking_confidence=0.5)
# Iniciando as ferramentas para desenhar os pontos-chave
mp_drawing = mp.solutions.drawing_utils
with open(csv_path, mode='w', newline='') as file:
writer = csv.writer(file)
writer.writerow(csv_header)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# Inverter o vídeo horizontelmente
frame = cv2.flip(frame, 1)
# Converter a imagem de BRG para RGB
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# Processando a imagem obtida com mediapipe
result = hands.process(rgb_frame)
# Checando se alguma mão foi detectada
if result.multi_hand_landmarks:
for hand_landmarks in result.multi_hand_landmarks:
# Desenhando os pontos-chave detectados
mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
# Coletando qual o sinal esta sendo sinalizado
key = cv2.waitKey(1) & 0xFF
] # Checando se é uma letra valida
if key != 255:
key_str = chr(key)
keypoints = [key_str]
# Guardando os pontos-chave da mão detectada em um csv
for landmark in hand_landmarks.landmark:
keypoints.extend([landmark.x,landmark.y,landmark.z])
writer.writerow(keypoints)
# Mostrar a imagem capturada em tempo real
cv2.imshow('WebCam', frame)
# Liberar a WebCam e fechar as janelas criadas
cap.release()
cv2.destroyAllWindows()
A arquitetura da rede neural utilizada para o reconhecimento de sinais em Libras é projetada para processar e interpretar os dados das coordenadas dos pontos-chave das mãos, extraídos com MediaPipe. A arquitetura selecionada utiliza camadas densas (fully connected) para criar um modelo eficiente e preciso.
MediaPipe é capaz de identificar 21 pontos distintos na mão, cada um com coordenadas x, y e z. Isso resulta em 63 entradas para a rede neural. A rede neural conta também com 3 camadas escondidas com 36,39 e 26 neurônios respectivamente. A camada de saida utiliza a função de ativação SoftMax para transformar a camada de saida em uma distribuição de probabilidades de cada classe, todas as outras camadas utilizam a função de ativação ReLU, o modelo foi compilado com o otimizador Adam
Você pode construir um modelo similar em python da seguinte forma
import tensorflow as tf
from keras import layers, models, callbacks
import pandas as pd# Importando os dados
data_frame = pd.read_csv("dataset.csv",sep=",",decimal=".")
# Coletando o numero de classes diferentes
labels = data_frame["y"].unique()
# Criando um modelo
model = models.Sequential()
# Adicionando a camada de entrada
model.add(layers.Dense(63,activation="relu",input_dim = 63))
# Adicionando as camadas escondidas
model.add(layers.Dense(26,activation="relu"))
model.add(layers.Dense(39,activation="relu"))
model.add(layers.Dense(26,activation="relu"))
# Adicionando a camada de saida
model.add(layers.Dense(len(labels),activation="softmax"))
# Compilando o modelo
model.compile(loss = "sparse_categorical_crossentropy", optimizer = "adam", metrics=["accuracy"])
Preparação dos dados
Os dados foram normalizados utilizando LabelEncoder e StandartScaler, em seguida divididos em conjuntos de treinamento e validação da seguinte forma
import tensorflow as tf
import pandas as pd
from sklearn.preprocessing import LabelEncoder,StandardScalerpath = "dataset.csv"
#Crir o dataframe
data_frame = pd.read_csv(path,sep=",",decimal=".")
labels = data_frame["y"].unique() #Colhendo os diferentes labels do data frame
encoder = LabelEncoder() #Criando o codificador
encoder.fit(labels) #Ajustando o codificador
data_frame["target"] = encoder.transform(data_frame["y"]) #Criando uma nova coluna no data frame
#Ajustando o data frame
scaler = StandardScaler()
scaler.fit(data_frame.iloc[:,1:64])
data_frame.iloc[:,1:64] = pd.DataFrame(scaler.fit_transform(data_frame.iloc[:,1:64])) #Normalizando os valores
#Criando os valores de treino, teste e validacao
train = data_frame.sample(frac=0.8,random_state=seed) #Separando 80% do data frame para o treino
data_frame = data_frame.drop(train.index) #Removendo os valores de treino do data frame
valid = data_frame.sample(frac=0.5,random_state=seed) #Separando 50% dos valores para a validacao
data_frame = data_frame.drop(valid.index) #Removendo os valores de validacao do data frame
test = data_frame.sample(frac=1,random_state=seed) #Separando o resto dos valores para o teste
X_train = train.iloc[:,1:64]
y_train = train.iloc[:,64]
X_valid = valid.iloc[:,1:64]
y_valid = valid.iloc[:,64]
X_test = test.iloc[:,1:64]
y_test = test.iloc[:,64]
Treinamento do modelo
Apos criado e compilado o modelo, o processo de treinamento seguiu da seguinte forma
# Adicionando callbacks para medir o treinamento do modelocallback = callbacks.ModelCheckpoint("best.keras",save_best_only=True)
reduce_lr_callback = callbacks.ReduceLROnPlateau(monitor='accuracy', factor=0.2, patience=3, min_lr=1e-6)
#Criando uma condicao para que a rede pare de treinar se nao houver melhoras, ajuda a evitar overfitting
early_stopping_callback = callbacks.EarlyStopping(monitor="accuracy",patience=10,restore_best_weights=True)
#Treinamento
history = model.fit(X_train, y_train,
epochs=epocas,
batch_size=64,
validation_data=(X_valid, y_valid),
shuffle=True,
callbacks=[early_stopping_callback, callback, reduce_lr_callback],
verbose=1)
#Plotando o grafico de acuracia
plt.plot(history.history['accuracy'],color='red',label='training accuracy')
plt.plot(history.history['val_accuracy'],color='blue',label='validation accuracy')
plt.legend()
plt.show()
#Plotando o grafico de loss
plt.plot(history.history['loss'],color='red',label='training loss')
plt.plot(history.history['val_loss'],color='blue',label='validation loss')
plt.legend()
plt.show()
Avaliação do Modelo
Após o treinamento, o modelo é avaliado para verificar seu desempenho e ajustar hiperparâmetros, se necessário.
Os gráficos de desempenho do modelo indicam resultados muito positivos durante o treinamento. O gráfico de acurácia mostra um rápido crescimento no valor da métrica, alcançando e mantendo uma precisão entre 0,99 e 1. Isso sugere que o modelo aprendeu a identificar com alta precisão os sinais em Libras, conseguindo classificar corretamente a maioria dos exemplos.
Simultaneamente, o gráfico de perda (loss) revela uma rápida diminuição na função de perda, que estabilizou em um valor próximo a 0. Isso indica que a rede neural foi eficaz em minimizar a diferença entre as previsões e os sinais verdadeiros durante o treinamento. A perda próxima de 0 reflete uma excelente capacidade do modelo em ajustar seus pesos e melhorar a qualidade das previsões.
Esses resultados demonstram que o modelo está bem treinado e possui uma alta capacidade de generalização, uma vez que a acurácia elevada e a perda baixa indicam uma performance robusta tanto em termos de precisão quanto de capacidade de previsão. A constância nos altos valores de acurácia e baixos valores de perda sugere que o modelo não está apenas se ajustando bem aos dados de treinamento, mas também está mantendo um desempenho sólido e consistente.
Uma matriz de confusão é uma ferramenta essencial para avaliar o desempenho de um modelo de classificação. Ela mostra o número de previsões corretas e incorretas do modelo em relação às classes reais. Ela é capaz de identificar verdadeiros positivos, verdadeiros negativos,falsos positivos, falsos negativos. A matriz de confusão revelou um desempenho impecável, sem erros de classificação, o que demonstra a eficácia do modelo.
Impacto potencial
A aplicação desta tecnologia pode transformar a comunicação para surdos e deficientes auditivos, facilitando a interação em tempo real e promovendo uma inclusão mais eficaz em diversos contextos.
Proximos passos
Para aprimorar ainda mais o sistema, planejo implementar novos sinais, expandir o reconhecimento para sinais feitos com ambas as mãos, e integrar a detecção de expressões faciais e posturas do sinalizador.
MediaPipe : https://mediapipe.dev
TensorFlow: https://www.tensorflow.org/guide
OpenCV : https://docs.opencv.org/
Libras: https://www.libras.org
Be the first to comment