Comment nous utilisons les algorithmes de vision par ordinateur: traitement vidéo dans un navigateur mobile utilisant OpenCV.js

Il existe déjà toutes les possibilités d'identifier une personne en ligne, mais jusqu'à présent, elles sont rarement utilisées. Nous avons peut-être été l'un des premiers à mettre en œuvre le scénario optimal pour l'utilisateur - connectez-vous au site à partir d'un smartphone, prenez une photo de votre permis de conduire ou de votre passeport et envoyez des données au système.

Voyons comment les algorithmes de vision par ordinateur aident à reconnaître les documents dans un flux vidéo directement dans les navigateurs mobiles. Dans cet article, nous partageons notre expérience de la façon dont nous avons utilisé OpenCV.js pour cela chez SimbirSoft, quelles difficultés sont possibles, comment garantir la vitesse et obtenir une UX «fluide» sans ralentir.




Quelle était la tâche


Le scénario commercial de l'algorithme en cours de développement est le suivant. Un utilisateur accédant au site à partir d'un téléphone portable doit pouvoir photographier ses documents et les envoyer au système pour un traitement ultérieur. Cela peut faire partie du processus d'identité lors de la demande d'utilisation de tout service.

Dans ce scénario, une application Web est préférable à une application mobile en raison de sa disponibilité et du temps réduit pour terminer l'opération. La page Web n'a pas besoin d'installation et est prête à fonctionner immédiatement après le chargement. L'utilisateur peut procéder aux actions dont il a besoin - soumettre une demande - immédiatement après avoir reçu le lien, sans se laisser distraire par des actions supplémentaires. D'un point de vue commercial, ces facteurs augmentent la conversion et l'efficacité commerciale du processus.

D'un point de vue architectural, l'algorithme est nécessaire pour détecter directement les limites du document et recadrer le fond en excès dans l'image. La vérification de l'identité, l'authentification et les contrôles de fraude seront mis en œuvre par d'autres composants. Cependant, il est conseillé d'effectuer au moins des vérifications minimales pour exclure l'envoi de cartes de visite, de rectangles de papier vides et d'autres images manifestement non pertinentes pour le traitement des images.

Exigences


Dans le cadre de notre projet, il y avait les exigences supplémentaires suivantes pour l'algorithme:

  • la possibilité de travailler en temps réel: le flux vidéo de la caméra ne doit pas "ralentir" pendant le fonctionnement de l'algorithme;
  • la capacité de travailler dans un large éventail de contrastes et de textures de fond: contraste et contraste faibles, fond homogène et hétérogène;
  • Prise en charge d'une large gamme de modèles de smartphones, y compris les modèles économiques publiés il y a plusieurs années.

Enfin, il n'y avait aucun ensemble de données pour la formation d'algorithmes d'apprentissage automatique dans le projet, et il n'y avait aucun moyen de le collecter et de le baliser. Nous n'avons eu que quelques échantillons de test dans les résultats de recherche de Google.

Compte tenu de cet énoncé du problème, nous avons décidé de développer sur la base des algorithmes classiques de vision par ordinateur de la bibliothèque opencv. Une autre possibilité était l'utilisation d'algorithmes d'apprentissage automatique et de réseaux de neurones, mais elle a déjà été écartée au début des travaux en raison d'exigences de performances: une fois appliqués, il ne serait pas possible de fournir un traitement de trame en temps réel sur tous les appareils cibles.

Approche générale et structure de l'algorithme


L'idée principale de l'algorithme est un cadre de référence, le long duquel il est nécessaire d'aligner le document. Son utilisation poursuit plusieurs objectifs à la fois. Premièrement, il fournira une taille d'image appropriée, suffisante pour un traitement ultérieur des documents. Deuxièmement, comme nous le verrons plus loin, il peut être utilisé comme l'un des filtres candidats lors de la recherche de bordures de document. Troisièmement, il peut être utilisé pour capturer et recadrer l'image si les bordures du document sont introuvables.



Figure. 1. La structure générale de l'algorithme

La structure générale de l'algorithme est représentée sur la Fig. 1. Les images du flux vidéo sont traitées dans un cycle, entre les itérations dont un délai est défini pour se conformer au FPS souhaité - nous nous sommes arrêtés à 30 images par seconde. Cela vous permet d'éviter les «ralentissements» et de réduire la charge sur le processeur et la consommation d'énergie de l'appareil.

Chaque trame traitée subit un prétraitement, au cours duquel deux opérations principales sont effectuées. Tout d'abord, une copie d'une trame d'une taille fixe de 640x480 est créée, avec laquelle les autres étapes de l'algorithme fonctionnent. L'image d'origine reste également, le document détecté sera découpé. Cela permettra d'économiser la qualité de l'image finale. Deuxièmement, la copie créée est traduite en nuances de gris. La couleur du document en cours de traitement est ignorée par l'algorithme, car elle peut varier d'un pays à l'autre et même dans différentes régions du pays - un exemple est un permis de conduire aux États-Unis.

La première étape de la détection d'un document consiste à rechercher le visage dans l'image. L'utilisation de cette heuristique élimine la capture de cartes de visite et d'autres images manifestement non pertinentes. La recherche est effectuée en utilisant le standard opencv'shash CascadeClassifier.detectMultiScale () et la cascade pré- formée haarcascade_frontalface_default . Les tailles minimales et maximales des visages détectés sont limitées, ce qui permet de réduire les coûts de calcul, et limite encore davantage l'échelle du document dans l'image. Un visage est considéré comme détecté dans l'image lorsqu'il se trouve dans la partie gauche - ou inférieure gauche, pour les passeports - de la zone à l'intérieur du cadre de référence (Fig. 2). Il s'agit d'une mesure supplémentaire pour assurer l'alignement correct du document dans l'image.

Les exemples de cet article ne contiennent pas de données personnelles.



Figure. 2. La zone de la position attendue du visage dans l'image. Le cadre de support est affiché en rouge, les bordures de la zone de l'emplacement attendu du visage sont affichées en vert.

Après la détection des visages, nous procédons à la détection des bordures. FindContours () est souvent utilisé ici . Cependant, cette approche ne fonctionne bien que dans des cas contrastés, par exemple pour une feuille de papier posée sur un bureau sombre. Si le contraste est plus faible, ou l'éclairage est pire, ou si quelqu'un tient une feuille dans ses mains, couvrant une partie de la bordure avec ses doigts, les contours détectés se décomposent en composants séparés, «perdent» des sections importantes ou ne sont pas détectés du tout.

Par conséquent, nous avons adopté une approche différente. Après la binarisation, nous passons d'abord l'image à travers le filtre de bordure en utilisant Canny () , puis regardons l'image résultante pour la ligne en utilisant la HoughLines de transformation Huff () . Le paramètre de seuil est immédiatement réglé suffisamment grand, égal à 30 - pour filtrer les segments courts et autres non pertinents détectés.

L'ensemble de lignes résultant est en outre filtré, ne laissant que des lignes proches du cadre de référence. Pour ce faire, nous traduisons d'abord les équations des lignes de trame en points dans le système de coordonnées polaires (rho, thêta) - thêta sera toujours 0 ou pi / 2, et rho sera unique pour chaque ligne. Après cela, nous sélectionnons dans les lignes obtenues à partir de la transformation de Huff uniquement celles qui se trouvent au voisinage des points de contrôle - selon la métrique euclidienne, en tenant compte de la différence dans l'échelle des valeurs.

Nous répartissons l'ensemble des lignes obtenues après filtrage en quatre groupes correspondant aux quatre lignes du référentiel, trouvons les intersections des lignes par paires entre les groupes, calculons la moyenne et obtenons les coordonnées des quatre points - les coins du document détecté (Fig.3).



Figure. 3. Filtrer les lignes et définir les coins du document. Des lignes vertes - résultat du filtrage, des points jaunes - ont détecté les coins du document.

Ensuite, vous devez vous assurer de la qualité du cadre. Pour ce faire, nous vérifions que le cadre est resté immobile pour la dernière fois. Pour ce faire, soustrayez la trame au début de la période de la trame actuelle à l'aide de absdiff () et comparez-la avec le seuil. Avant la soustraction, nous lissons en outre les images avec un filtre gaussien GaussianBlur () pour réduire l'influence du bruit et d'autres facteurs aléatoires. Nous évaluons également la focalisation du cadre en calculant son laplacien Laplacien () , en estimant sa variance et en comparant la valeur obtenue avec un seuil.

Si toutes les vérifications réussissent, vous pouvez passer à la dernière partie. Nous recalculons les coordonnées détectées des angles dans le système de coordonnées de l'image originale sous-exposée et découpons la région résultante à l'aide de la méthode roi () . Le document a été détecté avec succès.

Caractéristiques d'implémentation


Au cours du développement de l'algorithme, ses principaux composants ont été assemblés dans un script python. Après cela, l'algorithme a été porté sur opencv.js et javascript, puis sur wasm. Cette approche est dictée par des considérations de commodité à toutes les étapes. Sur python, il était plus pratique pour notre équipe d'expérimenter différentes variantes de l'algorithme et d'effectuer des réglages de paramètres approximatifs. Le portage en javascript a permis de tester le fonctionnement de l'algorithme sur la plateforme cible, notamment sur différents appareils et navigateurs. Sur la base des résultats de ces vérifications, un réglage fin des paramètres de l'algorithme a été effectué. Enfin, la réécriture de sections critiques de code sur wasm nous a permis d'obtenir une amélioration supplémentaire des performances.

Au cours de la migration, un certain nombre de différences ont été découvertes dans l'API OpenCV, ce qui a entraîné des changements mineurs dans l'implémentation. Par exemple, la variance d'un Laplacien en python est simplement considérée comme Laplacian (). Var () . Avec OpenCV.js, il n'y a aucun moyen d'utiliser NumPy, mais aucune implémentation alternative de la méthode var () n'a été fournie. Solution: comptez la fonction meanStdDev () comme l' écart type (Listing 1).

private isImageBlurry(image: cv.Mat): boolean {
		const laplacian = new cv.Mat();
		cv.Laplacian(image, laplacian, cv.CV_64F);
		const s_mat = new cv.Mat();
		cv.meanStdDev(laplacian, new cv.Mat(), s_mat);
		const s = s_mat.data64F[0];
		const v = Math.pow(s, 2);
		return (v < this.laplacianVarianceThreshold);
	}

Liste 1. Évaluation de la concentration sur l'image à travers la variance du laplacien dans opencv.js (TypeScript)

Une autre caractéristique était la nécessité de réduire la taille de la bibliothèque. Dans sa forme originale, OpenCV.js a une capacité de 7,9 Mo. Son téléchargement via Internet ralentit l'initialisation de l'algorithme. La solution à ce problème est de «rogner» les modules inutilisés pendant le processus d'assemblage de la bibliothèque, ce qui peut réduire considérablement la taille du fichier de sortie: nous avons réussi à atteindre une taille de 1,8 Mo. La liste des composants inclus dans l'assemblage peut être configurée dans le fichier de configuration plates-formes / js / opencv_js.config.py (Listing 2).

white_list = makeWhiteList([core, imgproc, objdetect, video, dnn, features2d, photo, aruco, calib3d])

Listing 2. La liste blanche d'origine des modules opencv inclus dans l'assembly pour javascript

Enfin, une contribution importante pour garantir les performances requises de l'algorithme a été apportée en le déplaçant vers Web Worker. Cette étape, associée à la restriction du FPS, nous a permis de nous débarrasser des «ralentissements» du flux vidéo lors du fonctionnement de l'algorithme, ce qui a eu un effet positif sur l'UX.

résultats


Des exemples de capture et de recadrage d'images sont présentés sur la Fig. 4. On peut voir que le recadrage de la plus haute qualité est obtenu sur un fond uniforme sombre et la qualité la plus basse est obtenue avec un fond inhomogène clair. Il s'agit de l'effet attendu associé aux dégradés obtenus sur différents arrière-plans et utilisé pour détecter les bordures d'un document. Sur un fond sombre, les dégradés sont plus grands que sur un fond clair, un fond uniforme conduit à moins de variabilité des valeurs de gradient. Cela conduit à une détection fiable des limites et, par conséquent, à un meilleur recadrage.




Figure. 4. Exemples de recadrage de documents à l'aide d'un algorithme

Conclusion


L'article présente un algorithme pour détecter des documents sur des images à partir d'un flux vidéo adapté à une utilisation dans les navigateurs mobiles, et examine également les caractéristiques de sa mise en œuvre à l'aide de la bibliothèque opencv.js. L'algorithme vous permet d'obtenir l'image de sortie des documents dans une qualité suffisante pour une utilisation ultérieure par des algorithmes d'authentification, de vérification d'identité, etc. La vitesse de l'implémentation résultante vous permet d'obtenir une UX «fluide» sans «ralentissements» et perte de trame.

Merci pour l'attention! Nous espérons que cet article vous sera utile.

All Articles