CV - Extraire les différences entre deux images
Je suis actuellement en train de travailler sur un système anti-intrusion basé sur la vidéo de surveillance. Afin d'accomplir cette tâche, je prendre un instantané de l'arrière-plan de ma scène (supposons qu'elle est totalement propre, pas de personnes ou d'objets en mouvement). Ensuite, je compare l'image que je reçois de l' (statique) de la caméra vidéo et de chercher les différences. Je dois être en mesure de vérifier tout différences, non seulement la forme humaine, ou que ce soit, donc je ne peux pas spécifique à l'extraction des caractéristiques.
Généralement, j'ai:
Je suis en utilisant OpenCV, afin de comparer en gros, je fais:
cv::Mat bg_frame;
cv::Mat cam_frame;
cv::Mat motion;
cv::absdiff(bg_frame, cam_frame, motion);
cv::threshold(motion, motion, 80, 255, cv::THRESH_BINARY);
cv::erode(motion, motion, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3,3)));
Voici le résultat:
Comme vous pouvez le voir, le bras dénudé (en raison de la couleur de différentiel de conflit, je suppose) et ce n'est malheureusement pas ce que je veux.
J'ai pensé à ajouter l'utilisation de cv::Canny()
afin de détecter les bords et remplir la partie manquante du bras, mais malheureusement (encore une fois), elle ne résout le problème en quelques pas de la plupart d'entre eux.
Est-il un algorithme ou une technique que je pourrais utiliser pour obtenir un précis différence de rapport?
PS: Désolé pour les images. En raison de mon nouvel abonnement, je n'ai pas assez de réputation.
MODIFIER
J'utilise des niveaux de gris de l'image ici, mais je suis ouvert à toute solution.
- peut-être essayer de ne pas réinventer la roue
- juste un coup d'oeil, ce qui est déjà intégrée (et si ça fonctionne mieux), oui.
- avez-vous convertir en niveaux de gris? Si vous ne voulez pas utiliser le openCV classes: Essayez le calcul de la différence de chaque canal et de les combiner, essayez de différence de HSV images. Si vous souhaitez utiliser les techniques existantes, essayez de ViBe. Gardez à l'esprit que même les variations de l'éclairage sera "les différences, non seulement la forme humaine, ou que ce soit", ce qui pourrait être un problème pour la plupart de toutes les méthodes de soustraction d'arrière-plan.
- en général, la construction d'un modèle d'arrière-plan au fil du temps, à l'aide de nombreuses images, va battre tous les approche. aussi, Vibe <-- juste être conscient qu'il est breveté.
- eh bien, la question ici est de ne pas construire le modèle d'arrière-plan, mais de trouver les "différences" mieux (ce qui est difficile dans les images en niveaux de gris). @ValentinTrinqué pouvez-vous s'il vous plaît ajouter de l'origine unique des images, j'ai mis en place une stratégie multi-canal de la version de votre code, mais je n'ai pas accès aux images d'origine. Essayé de recadrer votre double image, mais ils ont l'air un peu traduits...
Vous devez vous connecter pour publier un commentaire.
Un problème dans votre code est
cv::threshold
qui utilise seulement 1 canal des images. Trouver le pixelwise "différence" entre les deux images uniquement en niveaux de gris conduit souvent à des résultats non intuitifs.Depuis vos images fournies sont un peu traduits ou la caméra n'était pas stationnaire, j'ai manipulé de votre image d'arrière-plan pour ajouter un peu de premier plan:
image d'arrière-plan:
image de premier plan:
code:
donner ce résultat:
avec cette différence d'image:
en général, il est difficile de calculer un complet de premier plan/arrière-plan de la segmentation de pixel-sage différence des interprétations.
Vous devrez probablement ajouter un post-traitement des trucs pour obtenir une vraie segmentation, d'où vous lancez dans votre premier plan d'un masque. Pas sûr qu'il y a de stable universelle des solutions encore.
Comme berak mentionné, dans la pratique, il ne suffit pas d'utiliser une seule image d'arrière-plan, de sorte que vous aurez à calculer/gérer votre image d'arrière-plan au fil du temps. Il y a beaucoup de papiers traitant de ce sujet, et autant que je sache, pas stable en solution universelle encore.
voici un peu plus de tests. Je me suis converti à
HSV
espace de couleurs:cv::cvtColor(backgroundImage, HSVbackgroundImagebg, CV_BGR2HSV); cv::cvtColor(currentImage, HSV_currentImage, CV_BGR2HSV);
et effectué les mêmes opérations dans cet espace, conduisant à ce résultat:après l'ajout d'un peu de bruit à l'entrée:
J'obtiens ce résultat:
alors peut-être que le seuil est un peu trop élevé. Je vous encourage à toujours avoir un coup d'oeil à l'espace de couleur HSV trop, mais vous pourriez avoir à réinterpréter la "différence " image" et le redimensionner à chaque canal de combiner leurs valeurs de la différence.
J'utilise Python, c'est mon résultat:
Le code:
Mise à jour, voici le code C++:
Des réponses similaires:
CV - Extraire les différences entre deux images
Alors que vous trouver une différence entre les 2 photos OpenCV différence est plus grand qu'il est censé être
threshold the sliding-subtractions with morph-ops
. Avis, aucun des deux images sont identiques, il existe un bruit blanc.C'est bien connu classique de la vision par ordinateur problème appelé soustraction du bruit de fond. Il ya beaucoup d'approches qui peuvent être utilisées pour résoudre ce problème, la plupart d'entre eux sont déjà en place, donc je pense que vous devriez d'abord prendre un coup d'oeil à plusieurs algorithmes existants, ici, est opensource de mise en œuvre de la plupart d'entre eux: https://github.com/andrewssobral/bgslibrary (personnellement, j'ai trouvé SUBSENSE donnent les meilleurs résultats, mais son mortel lent)