Supprimer le fond de l'image en utilisant opencv Python
J'ai deux images, l'une avec seulement le fond et l'autre avec fond + détectable objet (dans mon cas sa voiture). Ci-dessous, les images sont
Je suis en train de supprimer l'arrière-plan, que je n'ai que de la voiture dans l'image résultante. Voici le code que j'essaie d'obtenir les résultats souhaités
import numpy as np
import cv2
original_image = cv2.imread('IMG1.jpg', cv2.IMREAD_COLOR)
gray_original = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY)
background_image = cv2.imread('IMG2.jpg', cv2.IMREAD_COLOR)
gray_background = cv2.cvtColor(background_image, cv2.COLOR_BGR2GRAY)
foreground = np.absolute(gray_original - gray_background)
foreground[foreground > 0] = 255
cv2.imshow('Original Image', foreground)
cv2.waitKey(0)
L'image obtenue par soustraction des deux images est
Là est le problème. Les attendus de l'image résultante devrait être une seule voiture.
Aussi, Si vous prenez un regard profond dans les deux images, vous verrez qu'ils ne sont pas exactement les mêmes que est, la caméra est un peu déplacé de sorte d'arrière-plan avait été dérangé un peu. Ma question est que, avec ces deux images comment puis-je soustraire le fond. Je ne veux pas utiliser grabCut ou backgroundSubtractorMOG algorithme dès maintenant, parce que je ne sais pas maintenant ce qui se passe à l'intérieur de ces algorithmes.
Ce que je suis en train de faire est d'obtenir à la suite de l'image résultante de
Aussi, si possible, veuillez me guider avec une façon générale, en faisant cela, non seulement dans ce cas particulier, j'ai un arrière-plan d'une image et d'arrière-plan+objet dans la seconde image. Ce qui pourrait être la meilleure façon possible de le faire. Désolé pour cette longue question.
source d'informationauteur muazfaiz
Vous devez vous connecter pour publier un commentaire.
J'ai résolu le problème en utilisant les OpenCV est bassin versant de la algorithme. Vous pouvez trouver la théorie et des exemples de bassin versant ici.
J'ai d'abord sélectionné plusieurs points (marqueurs) de dicter où est l'objet que je veux garder, et où est l'arrière-plan. Cette étape est manuel, et peut varier beaucoup d'une image à l'autre. Aussi, il exige de la répétition jusqu'à ce que vous obtenez le résultat souhaité. Je vous suggère d'utiliser un outil pour obtenir les coordonnées en pixels.
Puis j'ai créé un vide tableau d'entiers de zéros, avec la taille de l'image de voiture. Et puis j'ai attribué des valeurs (1:contexte, [255,192,128,64]:car_parts) pour les pixels des positions des marqueurs.
REMARQUE: Quand j'ai téléchargé votre image que j'avais de culture afin d'obtenir l'un avec la voiture. Après le recadrage, l'image a la taille de 400x601. Cela peut ne pas être ce que la taille de l'image que vous avez, de sorte que les marqueurs.
Par la suite j'ai utilisé l'algorithme de segmentation. La 1ère entrée est votre image et 2ème entrée est le marqueur de l'image (zéro partout, sauf au marqueur de position). Le résultat est montré dans l'image ci-dessous.
J'ai mis tous les pixels dont la valeur est supérieure à 1 à 255 (de la voiture), et le reste (arrière-plan) à zéro. Ensuite, j'ai dilaté de l'image obtenue avec un 3x3 noyau pour éviter de perdre de l'information sur le contour de la voiture. Enfin, j'ai utilisé la dilatation de l'image comme d'un masque à l'image d'origine, à l'aide de la cv2.bitwise_and() de la fonction, et le résultat se trouve dans l'image suivante:
Voici mon code:
Si vous avez beaucoup d'images, vous aurez probablement besoin de créer un outil pour annoter les marqueurs graphiquement, ou même un algorithme permettant de trouver des repères automatiquement.
Le problème, c'est que vous êtes en soustrayant des tableaux de unsigned 8 bits entiers. Cette opération risque de déborder.
À démontrer
Puisque vous êtes en utilisant OpenCV, de la façon la plus simple pour réaliser votre but est d'utiliser
cv2.absdiff()
.