La vision par ordinateur protège la confidentialité





La prévention est notre tout. Une protection compétente contre les fuites de données aidera à prévenir les conséquences négatives pouvant entraîner des pertes de plusieurs millions de dollars. Dans le monde moderne, chacune des organisations traite et stocke des informations confidentielles. Lorsqu'il s'agit de grandes organisations, les volumes d'informations confidentielles sont énormes. L'état de «sécurité» d'un ordinateur est un idéal conceptuel atteint lorsque chaque utilisateur observe toutes les règles de sécurité de l'information.



Au bureau, tout employé quitte de temps en temps son ordinateur, puis l'ordinateur allumé est sans surveillance, souvent avec des fichiers et des dossiers ouverts, car de nombreux employés oublient simplement de verrouiller leur PC, ou ils ne le font pas exprès, guidés par une phrase similaire - "J'ai reculé de cinq mètres, pourquoi le bloquer!?" Malheureusement, de tels moments peuvent être utilisés par d'autres employés intéressés par les matériaux.







Comment pouvez-vous garantir la sécurité des données dans de telles situations? L'un des moyens pourrait être l'utilisation de technologies d'authentification biométrique qui permettent de reconnaître les utilisateurs par leur visage.



La reconnaissance faciale n'est pas un concept nouveau et il existe actuellement de nombreux outils pour accomplir cette tâche. Si vous n'êtes pas particulièrement familiarisé avec les méthodes et les outils de reconnaissance faciale, alors utiliser la bibliothèque de vision par ordinateur Open source (bibliothèque de vision par ordinateur Open source) et le langage de programmation Python sera une excellente solution qui vous permettra d'atteindre votre objectif le plus rapidement possible.







Nous avons décidé du logiciel, nous avons besoin d'un autre matériel - une webcam. Comment configurez-vous la reconnaissance faciale maintenant? Tout d'abord, vous devez détecter le visage dans le cadre. L'une des méthodes de détection des visages est la méthode Viola-Jones, déjà décrite en 2001. Comme nous nous intéressons plus à la pratique, nous n'entrerons pas dans les détails théoriques, nous mentionnerons seulement que la méthode est basée sur des principes de base tels que la transformation d'une image en représentation intégrale, la méthode de la fenêtre de balayage et l'utilisation des fonctionnalités de Haar. Vous pouvez lire la description de la méthode et voir les informations sur l'installation d'OpenCV sur le site officiel . Voici le code Python qui nous permettra de détecter les visages à partir du flux vidéo de la webcam:



import cv2 as cv
import numpy as np

face_cascade = 'haarcascade_frontalface_default.xml'
cam = 1

classifier = cv.CascadeClassifier(face_cascade)

video_stream = cv.VideoCapture(cam)
while True:
    retval, frame = video_stream.read()
    gray_frame = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    found_faces = classifier.detectMultiScale(gray_frame, 1.2, 5, minSize=(197, 197))

    for x, y, w, h in found_faces:
        cv.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)

    cv.namedWindow('Stream', cv.WINDOW_NORMAL)
    cv.imshow('Stream', frame)

    k = cv.waitKey(30) & 0xFF
    if k == 27:
        break

video_stream.release()
cv.destroyAllWindows()


Dans le code ci-dessus, nous importons d'abord les deux modules nécessaires au fonctionnement: cv2 (vision par ordinateur) et numpy (travail avec des matrices). Dans la variable face_cascade, enregistrez le chemin vers le fichier xml avec les cascades Haar. Ce fichier, ainsi que d'autres, par exemple pour la détection des yeux, peuvent être trouvés sur la page github.



Dans la variable cam, nous écrivons le numéro de la webcam, si plusieurs sont connectées, le numéro de la seule caméra connectée par défaut est 0. Ensuite, un objet classificateur est créé en utilisant la méthode CascadeClassifier et la connexion à la caméra est cv.VideoCapture (cam). Ensuite, en boucle, nous lisons les images image par image dans la variable frame en utilisant la méthode read (). Le classificateur traite une image en niveaux de gris, par conséquent, en utilisant la méthode cvtColor, nous transformons l'image dans la forme souhaitée. La méthode detectMultiScale renvoie une liste avec les paramètres de toutes les faces détectées, qui est un rectangle - la coordonnée du sommet (x, y) et la largeur et la hauteur du rectangle (w, h). Les lignes suivantes sont facultatives pour que le programme fonctionne, mais utiles pour le débogage - la méthode du rectangle ajoute une image à l'image source à la place du visage détecté et imshow affiche une fenêtre avec un flux vidéo.



Tout est assez simple ici, mais plus intéressant encore. Maintenant, nous devons reconnaître le visage. Comment faire? OpenCV contient plusieurs méthodes de reconnaissance faciale, parmi lesquelles la méthode LBPH (Local Binary Patterns Histograms). Ici, nous allons nous attarder plus en détail et comprendre un peu comment cela fonctionne.



En général, les valeurs de luminosité du pixel d'image et de huit pixels supplémentaires entourant l'original sont prises. Il s'agit d'un tableau 3x3 avec des valeurs de luminosité en pixels. Ensuite, 0 ou 1 sont écrits dans le même tableau. Si la valeur de luminosité du pixel le plus à l'extérieur dépasse la valeur de luminosité du pixel central, 1 est défini, sinon - 0. Ensuite, le code résultant est lu dans le sens des aiguilles d'une montre à partir de la cellule supérieure gauche, converti en nombre décimal, et ce nombre est écrit dans une matrice de taille d'image à la position appropriée. Et donc pour chaque pixel.







La matrice est divisée en un certain nombre de segments (il s'agit par défaut d'une grille 8 × 8), un histogramme est construit pour chaque segment, et à la fin, en concaténant les histogrammes, une résultante caractérisant l'image entière est obtenue. Lors de la reconnaissance, le même histogramme est construit pour l'image étudiée, qui est ensuite comparée aux données d'apprentissage.







Nous utiliserons cette méthode particulière, mais vous devez d'abord faire une autre étape importante - créer une base avec des faces. En général, la structure de la base de données ressemble à ceci:



--Storage\\
	--Person_1\\
		--img_1.jpg
		--img_2.jpg
		--img_n.jpg
	--Person_m\\
                --img_1.jpg
		--img_2.jpg
		--img_n.jpg


Ok, nous avons une base avec des images de visages. Vous devez maintenant traiter en quelque sorte la base pour entraîner ou entraîner l'algorithme. Le traitement se résume à générer une liste de toutes les images et une liste d'identifiants ou de balises pour chaque personne. Le code le plus simple pour cette action pourrait ressembler à ceci:



storage = 'storage'
images = []
labels = []
names = {}
id = 0

for subdir in os.scandir(storage):
    names[id] = subdir.name
    subdir_path = os.path.join(storage, subdir.name)

    for file in os.scandir(subdir_path):
        if file.name.split('.')[-1].lower() not in ['png', 'bmp', 'jpeg', 'gif']:
            continue
        file_path = os.path.join(subdir_path, file.name)
        image = cv.imread(file_path, 0)
        label = id
        images.append(image)
        labels.append(label)
    id += 1


Ici aussi, tout est assez simple. La variable de stockage stocke le chemin vers le dossier contenant les dossiers avec les images des visages des individus, puis une liste pour les images, une liste pour les étiquettes et un dictionnaire avec les noms. Comment ça marche: toutes les images du dossier d'une certaine personne sont ajoutées à la liste des images, par exemple, il y en a 15. S'il s'agit du premier dossier du stockage, le libellé sera égal à 0, ainsi, 0 jusqu'à 15 fois sont ajoutés à la liste des libellés, en même temps Dans le dictionnaire des noms, un enregistrement est créé dans lequel la clé est l'étiquette et la valeur est le nom de la personne (le nom du dossier avec les images d'une personne en particulier). Et ainsi pour tout le stockage. Dans le code ci-dessus, faites attention à la ligne avec la méthode imread - ici l'image est lue et représentée comme une matrice de luminosité de pixel, et écrite dans la variable image.



Maintenant, la partie amusante consiste à entraîner l'algorithme:



recognizer = cv.face.LBPHFaceRecognizer_create(1, 8, 8, 8, 130) 
recognizer.train(images, np.array(labels))


Dans la première ligne de code, nous initialisons l'algorithme à l'aide de la méthode LBPHFaceRecognizer_create. Vous vous souvenez de la description de l'algorithme LBPH? Les paramètres de la fonction mentionnée contiennent juste ce dont nous avons parlé: le rayon le long de la bordure duquel les pixels seront pris autour de celui souhaité, le nombre de pixels du "cercle" formé par le rayon, le nombre de segments horizontalement et verticalement, et le seuil qui affecte la décision de reconnaissance personnes, c'est-à-dire que plus les exigences sont strictes, plus le seuil est bas. Ensuite, nous appelons la méthode train pour l'entraînement, en passant des listes d'images et d'étiquettes comme arguments. Maintenant, l'algorithme a mémorisé les visages de la base de données et pourra les reconnaître. Le problème est petit, il reste à ajouter quelques lignes au premier morceau de code de la boucle (pour x, y, w, h dans found_faces): après avoir détecté un visage, il faut le reconnaître, et si le visage n'est pas reconnu,ou une autre personne est reconnue, puis verrouillez immédiatement l'ordinateur!



roi = gray_frame[y:y+h, x:x+w]
name, dist = recognizer.predict(roi)
cv.putText(frame, '%s - %.0f' % (names[name], dist), (x, y), cv.FONT_HERSHEY_DUPLEX, 1, (0, 255, 0), 3)
if names[name] != "Ivan Petrov":
    ctypes.windll.user32.LockWorkStation()


Dans la première ligne, le ROI (de la région d'intérêt) est une variable dans laquelle nous écrivons un fragment de l'image contenant le visage détecté. La ligne suivante reconnaît directement le visage lors de l'appel de la méthode prédire. Cette méthode renvoie une étiquette correspondant au visage qui a été reconnu et une valeur caractérisant le degré d'écart entre le visage détecté et le visage reconnu (plus il est petit, plus le degré de confiance dans la reconnaissance du bon visage est élevé). Ensuite, toujours à des fins de débogage, ajoutez du texte au cadre avec le nom de la personne reconnue à l'aide de la méthode putText. Et enfin, nous vérifions la condition la plus simple: si un non-propriétaire du PC a été reconnu (c'est là qu'un dictionnaire avec des noms était nécessaire), alors verrouillez l'ordinateur. La ligne ctypes.windll.user32.LockWorkStation () est responsable du blocage, comme vous pouvez le voir. Pour que ça marchedevra importer le module ctypes en plus de cv2 et numpy.



En conséquence, le PC est bloqué dès que le visage d'une autre personne a été reconnu, ou il n'a pas été reconnu en principe. Après avoir déverrouillé le PC, le programme continue de s'exécuter. Vous pouvez également ajouter un verrouillage PC en cas de départ d'un employé de son lieu de travail. Vous n'avez pas besoin de réfléchir longtemps pour comprendre qu'il y a pas mal de nuances ici. Par exemple, que se passe-t-il si un autre visage est reconnu en arrière-plan? Dans cette situation, vous pouvez définir la taille minimale d'un objet qui ressemble à un visage, puis les visages en arrière-plan seront ignorés (pour cela, il existe un paramètre minSize dans la méthode detectMultiScale). Dans d'autres situations, de bonnes solutions peuvent également être trouvées si vous le souhaitez.



L'un des facteurs les plus importants pour que le blocage fonctionne correctement est la qualité des images dans la base de données de photos. Premièrement, il est souhaitable qu'il y en ait beaucoup pour une personne en particulier, avec des angles et des expressions faciales différents. Deuxièmement, l'éclairage fait ses propres ajustements, il vaut donc la peine de considérer ce point et d'utiliser des images prises sous différentes conditions d'éclairage. Et troisièmement, vous devez enregistrer des images de la webcam qui se trouve sur le lieu de travail de l'employé; il existe également une méthode pour enregistrer des images dans OpenCV. Quant au code, il est certain qu'il sera développé, des fonctionnalités supplémentaires seront ajoutées, afin qu'il puisse être «enveloppé» dans des fonctions, en utilisant des classes. Il n'y a pas de limite à la perfection! L'essentiel est de se souvenir de l'ordre des actions du programme: traitement de la base de données avec des photographies, formation, détection, reconnaissance.



Lors du webinaire du 03.09.2020 à 10h00, heure de Moscou, les intervenants présenteront une méthode pratique pour former un réseau de neurones à la détection d'objets avec le code source et les technologies utilisées, et répondront également à vos questions. Vous pouvez vous inscrire sur le lien: newtechaudit.ru/vebinar-computer-vision






All Articles