- Componentes necessários
- YOLO
- Instalando OpenCV no Raspberry Pi
- Instalando outros pacotes necessários no Raspberry Pi
- Explicação do programa
- Testando o Projeto Detector de Distância Social
Na época da Covid-19, o distanciamento social era uma forma eficaz de desacelerar a transmissão de vírus infecciosos. As pessoas são aconselhadas a minimizar o contato umas com as outras para minimizar o risco da doença ser transmitida por contato direto. Manter uma distância segura é um desafio para muitos lugares, como fábricas, bancos, ônibus ou estações ferroviárias, etc.
Portanto, na continuação de nossos projetos anteriores de segurança Corona, como máquina desinfetante automática e monitoramento de temperatura sem contato, aqui vamos construir um sistema de Detector de Distanciamento Social usando OpenCV e Raspberry Pi. Estaremos usando os pesos do Algoritmo de Detecção de Objetos YOLO v3 com o módulo Rede Neural Profunda.
Raspberry Pi é sempre uma boa escolha para projetos de processamento de imagem, pois tem mais memória e velocidade do que outros controladores. Anteriormente, usamos o Raspberry Pi para alguns projetos complexos de processamento de imagem, como detecção facial de pontos de referência e aplicativo de reconhecimento facial.
Componentes necessários
- Raspberry Pi 4
Aqui, só precisamos do RPi 4 com OpenCV instalado. 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.
YOLO
YOLO (You Only Look Once) é uma rede neural de convolução (CNN) inteligente para detecção de objetos em tempo real. YOLOv3, a última variante do algoritmo de detecção de objetos, YOLO pode reconhecer 80 objetos diferentes em imagens e vídeos, e é super rápido e tem excelente precisão. O algoritmo aplica uma única rede neural a toda a imagem, depois separa a imagem em regiões e calcula as caixas de limite e as probabilidades para cada área. O modelo base YOLO pode processar imagens em tempo real a 45 quadros por segundo. O modelo YOLO supera todos os outros métodos de detecção, como SSD e R-CNN.
O modelo YOLOV3 que vamos usar neste projeto pode ser baixado aqui.
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 no Raspberry Pi
Antes de programar o detector de distância Raspberry Pi for Social, vamos instalar os outros pacotes necessários.
Instalando o imutils: o imutils é usado para tornar as funções essenciais de processamento de imagem, como translação, rotação, redimensionamento, esqueletização e exibição de imagens Matplotlib mais fáceis com OpenCV. Use o comando abaixo para instalar os imutils:
pip3 install imutils
Explicação do programa
O código completo é fornecido no final da página. Aqui estamos explicando as seções importantes do código para uma melhor explicação.
Portanto, no início do código, importe todas as bibliotecas necessárias que serão usadas neste projeto.
import numpy as np import cv2 import imutils import os import time
A função Check () é usada para calcular a distância entre dois objetos ou dois pontos em um quadro de vídeo. Os pontos um e b representam os dois objectos no quadro. Esses dois pontos são usados para calcular a distância euclidiana entre os objetos.
def Verificação (a, b): dist = ((a - b) ** 2 + 550 / ((a + b) / 2) * (a - b) ** 2) ** 0,5 calibração = (a + b) / 2 se 0 <dist <0,25 * calibração: retorna Verdadeiro senão: retorna Falso
A função de configuração é usada para definir os caminhos para os pesos YOLO, arquivo cfg, arquivo de nomes COCO. O módulo os.path é usado para manipulação de nomes de caminho comuns. O módulo os.path.join () é um submódulo do os.path e é usado para unir um ou mais componentes do caminho de forma inteligente. O método cv2.dnn.readNetFromDarknet () é usado para carregar os pesos salvos na rede. Depois de carregar os pesos, extraia a lista de todas as camadas utilizadas em uma rede usando um modelo net.getLayerNames .
def Setup (yolo): global neural_net, ln, pesos LABELS = os.path.sep.join () config = os.path.sep.join () labelsPath = os.path.sep.join () LABELS = open (labelsPath).read (). strip (). split ("\ n") neural_net = cv2.dnn.readNetFromDarknet (config, pesos) ln = neural_net.getLayerNames () ln = - 1] para i em neural_net.getUnconnectedOutLayers ()]
Dentro da função de processamento de imagem, pegamos um único quadro de vídeo e então o processamos para detecção de distanciamento social entre cada pessoa na multidão. Nas primeiras duas linhas da função, definimos as dimensões do quadro de vídeo (W, H) como (Nenhum, Nenhum) inicialmente. Na próxima linha, usamos o método cv2.dnn.blobFromImage () para carregar frames em um lote e executá-los pela rede. A função blob realiza subtração média, escala e troca de canal em um quadro.
(H, W) = (Nenhum, Nenhum) frame = image.copy () se W for Nenhum ou H for Nenhum: (H, W) = frame.shape blob = cv2.dnn.blobFromImage (frame, 1 / 255.0, (416, 416), swapRB = True, crop = False) neural_net.setInput (blob) starttime = time.time () layerOutputs = neural_net.forward (ln)
As saídas da camada do YOLO consistem em um conjunto de valores. Esses valores nos ajudam a definir qual objeto pertence a qual classe . Fazemos um loop sobre cada saída em layerOutputs e, conforme detectamos pessoas, definimos o rótulo da classe como "pessoa". De cada detecção, obtemos uma caixa delimitadora que nos fornece o centro X, o centro Y, a largura e a altura da caixa para detecção na saída:
pontuações = detecção maxi_class = np.argmax (pontuações) confiança = pontuações se LABELS == "pessoa": se confiança> 0,5: caixa = detecção * np.array () (centerX, centerY, largura, altura) = box.astype ("int") x = int (centerX - (largura / 2)) y = int (centerY - (altura / 2)) outline.append () confidences.append (float (confiança))
Depois disso, calcule a distância entre o centro da caixa atual com todas as outras caixas detectadas. Se as caixas delimitadoras estiverem fechadas, altere o status para verdadeiro.
for i in range (len (center)): for j in range (len (center)): close = Check (center, center) if close: pairs.append (, center]) status = True status = True index = 0
Nas próximas linhas, desenhe um retângulo ao redor da pessoa usando as dimensões da caixa que recebemos do modelo e, em seguida, verifique se a caixa é segura ou insegura. Se a distância entre as caixas for próxima, a cor da caixa será vermelha, caso contrário, a caixa será verde.
(x, y) = (contorno, contorno) (w, h) = (contorno, contorno) se status == Verdadeiro: cv2.rectangle (quadro, (x, y), (x + w, y + h), (0, 0, 150), 2) status elif == Falso: cv2.rectangle (quadro, (x, y), (x + w, y + h), (0, 255, 0), 2)
Agora, dentro da função de loop , estamos lendo cada quadro do vídeo e, em seguida, processando cada quadro para calcular a distância entre as pessoas.
ret, frame = cap.read () se não ret: break current_img = frame.copy () current_img = imutils.resize (current_img, largura = 480) video = current_img.shape frameno + = 1 if (frameno% 2 == 0 ou frameno == 1): Setup (yolo) ImageProcess (current_img) Frame = processingImg
Nas próximas linhas, use a função cv2.VideoWriter () para armazenar o vídeo de saída no local especificado por opname que definimos anteriormente.
se criar for Nenhum: fourcc = cv2.VideoWriter_fourcc (* 'XVID') create = cv2.VideoWriter (opname, fourcc, 30, (Frame.shape, Frame.shape), True) create.write (Frame)
Testando o Projeto Detector de Distância Social
Quando seu código estiver pronto, abra um terminal Pi e navegue até o diretório do projeto. O código, o modelo Yolo e o vídeo de demonstração devem estar na mesma pasta conforme mostrado abaixo.
Você pode baixar o diretório YoloV3 daqui, vídeos do Pexels e copiar o código Python dado abaixo, e colocá-los no mesmo diretório como mostrado acima.
Uma vez no diretório do projeto, execute o seguinte comando para iniciar o código:
python3 detector.py
Eu tentei esse código em um exemplo de vídeo obtido na Pexels. Para mim, o FPS era muito lento e demorava cerca de 10 a 11 minutos para processar o vídeo inteiro.
Em vez de usar um vídeo, você pode até mesmo testar esse código com uma câmera Raspberry Pi, substituindo o cv2.VideoCapture (entrada) com cv2.VideoCapture (0) em 98 th linha do código. Saiba mais sobre como usar PiCamera com Raspberry Pi seguindo o link.
É assim que você pode usar o OpenCV com Raspberry Pi para detectar as violações de distanciamento social. O vídeo de saída e o código são fornecidos abaixo: