J'ai deux images, une avec uniquement un arrière-plan et l'autre avec un arrière-plan + objet détectable (dans mon cas, c'est une voiture). Ci-dessous les images
J'essaie de supprimer le fond tel que je n'ai que voiture dans l'image résultante. Voici le code avec lequel 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 en soustrayant les deux images est
Voici le problème. L'image résultante attendue devrait être uniquement une voiture . En outre, si vous regardez attentivement les deux images, vous verrez qu'elles ne sont pas exactement identiques, c'est-à-dire que l'appareil photo s'est déplacé un peu de manière peu. Ma question est qu'avec ces deux images, comment puis-je soustraire le fond. Je ne veux pas utiliser l’algorithme grabCut ou backgroundSubtractorMOG pour le moment, car je ne sais pas ce qui se passe à l’intérieur de ces algorithmes.
Ce que j'essaie de faire est d'obtenir l'image suivante qui en résulte
Aussi, si possible, merci de me guider avec une manière générale de le faire, non seulement dans ce cas précis, c’est-à-dire que j’ai un fond dans une image et un fond + objet dans la deuxième image. Quel pourrait être le meilleur moyen de le faire? Désolé pour une si longue question.
Le problème est que vous soustrayez des tableaux de unsigned nombres entiers de 8 bits. Cette opération peut déborder.
Démontrer
>>> import numpy as np
>>> a = np.array([[10,10]],dtype=np.uint8)
>>> b = np.array([[11,11]],dtype=np.uint8)
>>> a - b
array([[255, 255]], dtype=uint8)
Puisque vous utilisez OpenCV, le moyen le plus simple d'atteindre votre objectif consiste à utiliser cv2.absdiff()
.
>>> cv2.absdiff(a,b)
array([[1, 1]], dtype=uint8)
Je recommande d'utiliser l'algorithme grabcut d'OpenCV. Commencez par dessiner quelques lignes au premier plan et à l’arrière-plan et continuez ainsi jusqu’à ce que votre premier plan soit suffisamment séparé de l’arrière-plan. Il est couvert ici: https://docs.opencv.org/trunk/d8/d83/tutorial_py_grabcut.html Ainsi que dans cette vidéo: https://www.youtube.com/ regarder? v = kAwxLTDDAwU