J'ai essayé de créer une caméra de surveillance à détection de mouvement avec OpenCV en utilisant une caméra WEB avec Raspberry Pi

Chose que tu veux faire

Il semble que des personnes suspectes apparaissent à l'entrée de l'appartement où j'habite, j'ai donc attaché une caméra WEB à la porte d'entrée et créé un système d'analyse et d'enregistrement avec Raspberry Pi. Les spécifications sont les suivantes.

--Affichez la vidéo capturée et l'heure à l'écran

Articles référencés

Dans un premier temps, j'ai décidé de faire de la détection de visage en me référant à l'article de PC Kobo-san, mais cela ne convient pas à cette application car il y a beaucoup de faux positifs. C'était.

https://www.pc-koubou.jp/magazine/19205

À la suite de diverses réflexions, j'ai pensé que cela pouvait être réalisé par détection de mouvement (détection qu'il y avait un changement dans l'image prise), et à la suite d'essais et d'erreurs, cela s'est bien passé, je vais donc présenter la méthode.

De plus, je me suis référé à cet article pour savoir comment détecter les mouvements.

https://qiita.com/K_M95/items/4eed79a7da6b3dafa96d

Les choses nécessaires

--Raspberry Pi 3 Model B Plus Rev 1.3 (Un Raspberry Pi avec USB?)

Pour la procédure d'installation d'OpenCV, reportez-vous à l'article ci-dessus PC Studio. Python utilise celui qui est déjà inclus.

Procédure de construction

  1. Configuration du Raspberry Pi
  2. Configurez l'environnement VNC selon vos besoins
  3. Installez OpenCV
  4. Connectez la caméra WEB
  5. Vérifiez si la caméra WEB est reconnue
  6. Ecrivez et exécutez le programme

Confirmation de la reconnaissance de la caméra WEB

Il semble que le pilote soit inclus dans la caméra WEB connectée par USB depuis le début, donc si vous le connectez, il sera reconnu.

$ lsusb
Bus 001 Device 006: ID 0c45:62e0 Microdia MSI Starcam Racer
Bus 001 Device 005: ID 0424:7800 Standard Microsystems Corp. 
Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

C'est OK si le nom comme une caméra USB est affiché dans le résultat de la commande lsusb. Si vous ne savez pas, vérifiez si le nombre d'éléments augmente lorsque vous débranchez et connectez.

Code source

Le code que j'ai écrit est le suivant.

security_cam_motion.py


 # -*- coding: utf-8 -*-
import time
import datetime
import cv2 as cv

#Un programme qui réalise une caméra de surveillance à l'aide d'une caméra WEB
#Détection de mouvement, enregistrez le fichier jpg avec la date et l'heure intégrées à ce moment


#Répertoire pour enregistrer les images
save_dir  = './image/'

#Le nom du fichier doit être une chaîne de caractères comprenant la date et l'heure
#Spécifiez le nom du fichier à ajouter après la date et l'heure
fn_suffix = 'motion_detect.jpg'

#Créez une instance de VideoCapture.
cap = cv.VideoCapture(0) 

#Spécifiez la résolution verticale et horizontale
cap.set(cv.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv.CAP_PROP_FRAME_HEIGHT, 480)

#Valeur de pixel une fois binarisée
DELTA_MAX = 255

#Seuil de détection des changements dans chaque point
DOT_TH = 20

#Facteur de mouvement(Combien de points ont changé)Mais
#Combien ou plus devez-vous enregistrer?
MOTHON_FACTOR_TH = 0.20

#Stocker les données à des fins de comparaison
avg = None

while True:
    
    ret, frame = cap.read()     #Lire 1 image
    motion_detected = False     #Drapeau indiquant si un mouvement a été détecté

    dt_now = datetime.datetime.now() #Heure à laquelle les données ont été acquises

    #Nom du fichier et date et heure à intégrer dans l'image
    dt_format_string = dt_now.strftime('%Y-%m-%d %H:%M:%S') 
    f_name = dt_now.strftime('%Y%m%d%H%M%S%f') + "_" + fn_suffix


    #Faites-le monochrome
    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    
    #Obtenez un cadre pour comparaison
    if avg is None:
        avg = gray.copy().astype("float")
        continue
        
    
    #Calculez la différence entre l'image actuelle et la moyenne mobile
    cv.accumulateWeighted(gray, avg, 0.6)
    frameDelta = cv.absdiff(gray, cv.convertScaleAbs(avg))

    #Effectuer un traitement de seuil sur les images delta
    thresh = cv.threshold(frameDelta, DOT_TH, DELTA_MAX, cv.THRESH_BINARY)[1]

    #Calculez le facteur de mouvement. Combien a changé dans son ensemble?
    motion_factor = thresh.sum() * 1.0 / thresh.size / DELTA_MAX 
    motion_factor_str = '{:.08f}'.format(motion_factor)
    
    #Écrivez la date et l'heure sur l'image
    cv.putText(frame,dt_format_string,(25,50),cv.FONT_HERSHEY_SIMPLEX, 1.5,(0,0,255), 2)
   #Mouvement à l'image_Écrire la valeur du facteur
    cv.putText(frame,motion_factor_str,(25,470),cv.FONT_HERSHEY_SIMPLEX, 1.5,(0,0,255), 2)
    
    #Si le facteur de mouvement dépasse la valeur de seuil, un mouvement est détecté.
    if motion_factor > MOTHON_FACTOR_TH:
        motion_detected = True
    
    #Enregistrez l'image si un mouvement est détecté
    if motion_detected  == True:
        #save
        cv.imwrite(save_dir + f_name, frame)
        print("DETECTED:" + f_name)
    
    
    #A partir de là, traitement de l'image à afficher à l'écran
    #Ajouter un contour au seuil de l'image
    image, contours, hierarchy = cv.findContours(thresh.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    frame = cv.drawContours(frame, contours, -1, (0, 255, 0), 3)
    
    
    #Afficher l'image résultante
    cv.imshow('camera', frame)


    #Attendez jusqu'à ce qu'une touche soit enfoncée
    k = cv.waitKey(1000)  #L'argument est le temps d'attente(ms)
    if k == 27: #Fin lorsque Esc est entré
        break
    

print("Bye!\n")
#Fermez la fenêtre affichée
cap.release()
cv.destroyAllWindows()

Commande de démarrage

$ sudo python security_cam_motion.py

Résultat d'exécution

À la suite de son exécution, cela ressemble à ceci.

S'il n'y a pas de changement, rien ne se passe. Le nombre en bas est le facteur de mouvement. Puisqu'il n'y a pas de changement, il est de 0,0. image.png

Lorsqu'une personne apparaît devant l'entrée, la modification est reconnue et le fichier jpeg est enregistré. Puisque le facteur de mouvement est supérieur à un certain niveau, vous pouvez voir que le mouvement a été détecté.

image.png

La bordure n'est pas affichée dans le fichier jpeg enregistré. image.png

À propos du facteur de mouvement

Le facteur de mouvement est un mot que j'ai inventé par moi-même. Un coefficient qui indique combien de pixels de l'écran entier ont changé.

Cela s'appelle la détection de mouvement, mais le principe est que vous recherchez des pixels différents de l'image précédente. Un léger changement dans l'environnement peut détecter une légère différence par rapport à l'image précédente. S'il est détecté à chaque fois, la caméra de surveillance ne sera pas utile. En revanche, si une personne se tient devant la caméra, un pourcentage important des pixels devrait changer. Si vous décidez d'enregistrer quand un certain pourcentage change, il semble que vous puissiez atteindre l'objectif «d'enregistrer lorsqu'une personne passe devant l'entrée».

À propos des faux positifs

Pensez aux faux positifs faux positifs. En d'autres termes, comment gérer la "détection quand personne ne vient". Les gens viennent rarement car l'endroit où la caméra de surveillance est installée n'est qu'une pièce d'un appartement. Par conséquent, c'est un problème si les données sont remplies de faux positifs. Pensez aux moyens d'éviter les faux positifs. Il semble que le changement qu'il devrait y avoir ... peut être ajusté par le facteur de mouvement et le deuxième argument de la fonction cv.threshold () (la valeur seuil du changement de chaque point par rapport à l'image précédente). Puisque la variable DOT_TH est le deuxième argument, ajustez avec cette variable. Si la valeur est trop petite, elle sera faussement détectée en raison de changements dans l'environnement ou de fluctuations des pixels. Même ainsi, certains pixels détectent parfois faussement les changements, même sans mouvement réel, de sorte que le facteur de mouvement empêche les faux positifs.

   : 
#Seuil de détection des changements dans chaque point
DOT_TH = 20
#Facteur de mouvement(Combien de points ont changé)Mais
#Combien ou plus devez-vous enregistrer?
MOTHON_FACTOR_TH = 0.20
   :
#Effectuer un traitement de seuil sur les images delta
thresh = cv.threshold(frameDelta, DOT_TH, DELTA_MAX, cv.THRESH_BINARY)[1]
#Calculez le facteur de mouvement. Combien a changé dans son ensemble?
motion_factor = thresh.sum() * 1.0 / thresh.size / DELTA_MAX 
motion_factor_str = '{:.08f}'.format(motion_factor)
   :

À propos des faux positifs (faux négatifs)

Par contre, «il y a une personne mais elle n'est pas enregistrée» n'est pas utile comme caméra de surveillance. Probablement, dans ce système, il y a des gens, mais les cas qui ne sont pas enregistrés sont «porter des vêtements de la même couleur que le mur», «couper au bord de l'écran», «porter un camouflage optique». Je vais. Dans ce cas, j'ai décidé de le tolérer car je ne sais pas ce qu'il y a dans l'image et cela peut ne pas être utile. Il ne sert à rien de rechercher la perfection. L'équilibre est important.


c'est tout

Recommended Posts

J'ai essayé de créer une caméra de surveillance à détection de mouvement avec OpenCV en utilisant une caméra WEB avec Raspberry Pi
Créez une caméra de surveillance WEB avec Raspberry Pi et OpenCV
J'ai essayé de faire un signal avec Raspeye 4 (édition Python)
J'ai essayé d'automatiser [une certaine tâche] à l'aide d'une tarte à la râpe
J'ai fait une caméra de surveillance avec Raspberry PI pour la première fois.
J'ai créé une API Web
J'ai créé un serveur Web avec Razpai pour regarder des anime
Comment créer une caméra de surveillance (caméra de sécurité) avec Opencv et Python
J'ai essayé de créer une application todo en utilisant une bouteille avec python
J'ai essayé de détecter rapidement un mouvement avec OpenCV
J'ai créé un jeu ○ ✕ avec TensorFlow
J'ai essayé de créer un bouton pour Slack avec Raspeye + Tact Switch
Un mémorandum lors de la réalisation d'une caméra de surveillance avec Raspeye
J'ai essayé de connecter Raspeye et conect + avec l'API Web
J'ai fait un chronomètre en utilisant tkinter avec python
J'ai créé un éditeur de texte simple en utilisant PyQt
Utiliser une webcam avec Raspberry Pi
Je voulais faire fonctionner le moteur avec une tarte à la râpe, alors j'ai essayé d'utiliser la carte de commande du moteur de Waveshare
[5e] J'ai essayé de créer un certain outil de type Authenticator avec python
[2nd] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de créer une expression régulière de "montant" en utilisant Python
J'ai essayé de créer une expression régulière de "temps" en utilisant Python
[3ème] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de créer une expression régulière de "date" en utilisant Python
J'ai essayé de créer une application de notification de publication à 2 canaux avec Python
[4th] J'ai essayé de créer un certain outil de type Authenticator avec python
[1er] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de faire une étrange citation pour Jojo avec LSTM
J'ai essayé de créer une fonction de similitude d'image avec Python + OpenCV
J'ai essayé de créer un mécanisme de contrôle exclusif avec Go
Faire une minuterie de lavage-séchage avec Raspberry Pi
J'ai essayé de créer un LINE BOT "Sakurai-san" avec API Gateway + Lambda
J'ai essayé de créer un service de raccourcissement d'url sans serveur avec AWS CDK
Je souhaite créer une application Web en utilisant React et Python flask
J'ai essayé la détection d'objets en utilisant Python et OpenCV
Je veux faire un jeu avec Python
J'ai essayé d'utiliser la base de données (sqlite3) avec kivy
J'ai essayé de faire un processus périodique avec CentOS7, Selenium, Python et Chrome
J'ai fait une application d'envoi de courrier simple avec tkinter de Python
Quand j'ai essayé de créer un VPC avec AWS CDK mais que je n'ai pas pu le faire
[Analyse des brevets] J'ai essayé de créer une carte des brevets avec Python sans dépenser d'argent
J'ai essayé de créer un environnement Ubuntu 20.04 LTS + ROS2 avec Raspberry Pi 4
J'ai essayé de créer un BOT de traduction qui fonctionne avec Discord en utilisant googletrans
[Pour les débutants] J'ai fait un capteur humain avec Raspberry Pi et notifié LINE!
J'ai essayé de faire la reconnaissance de caractères manuscrits de Kana Partie 3/3 Coopération avec l'interface graphique en utilisant Tkinter
J'ai essayé de faire MAP rapidement une personne suspecte en utilisant les données d'adresse Geolonia
J'ai essayé de créer une API de reconnaissance d'image simple avec Fast API et Tensorflow
J'ai essayé de faire un "putain de gros convertisseur de littérature"
Créez un capteur de couleur à l'aide d'une tarte à la râpe et d'une caméra
J'ai essayé d'extraire des fonctionnalités avec SIFT d'OpenCV
J'ai essayé de devenir un Ann Man en utilisant OpenCV
J'ai essayé de créer une application OCR avec PySimpleGUI
Afficher l'image de la caméra USB avec OpenCV de Python avec Raspeye