Supposons que j'ai une image en niveaux de gris ici: 
Et une image masquée binaire ici: 
Avec les mêmes dimensions et forme. Comment générer quelque chose comme ceci: 
Où les valeurs indiquées par le 1 dans le masque binaire sont les valeurs réelles, et les valeurs qui sont 0 dans le masque sont nulles dans l'image finale.
3 Réponses :
Utilisez cv2.bitwise_and pour masquer une image avec un masque binaire. Tous les pixels blancs sur le masque (valeurs avec 1) seront conservés tandis que les pixels noirs (valeur avec 0) seront ignorés. Voici un exemple:
Image d'entrée (gauche), masque (droite)


Résultat après masquage

Code
import cv2
import numpy as np
# Load image, create mask, and draw white circle on mask
image = cv2.imread('1.jpeg')
mask = np.zeros(image.shape, dtype=np.uint8)
mask = cv2.circle(mask, (260, 300), 225, (255,255,255), -1)
# Mask input image with binary mask
result = cv2.bitwise_and(image, mask)
# Color background white
result[mask==0] = 255 # Optional
cv2.imshow('image', image)
cv2.imshow('mask', mask)
cv2.imshow('result', result)
cv2.waitKey()
Voici deux autres façons d'utiliser Python Opencv. Le premier est similaire à celui de @nathancy. Le second utilise la multiplication pour faire le masquage. J'utilise les mêmes images que celles fournies par @nathancy:
import cv2
import numpy as np
# read image
img = cv2.imread('pink_flower.png')
#mask it - method 1:
# read mask as grayscale in range 0 to 255
mask1 = cv2.imread('pink_flower_mask.png',0)
result1 = img.copy()
result1[mask1 == 0] = 0
result1[mask1 != 0] = img[mask1 != 0]
# mask it - method 2:
# read mask normally, but divide by 255.0, so range is 0 to 1 as float
mask2 = cv2.imread('pink_flower_mask.png') / 255.0
# mask by multiplication, clip to range 0 to 255 and make integer
result2 = (img * mask2).clip(0, 255).astype(np.uint8)
cv2.imshow('image', img)
cv2.imshow('mask1', mask1)
cv2.imshow('masked image1', result1)
cv2.imshow('masked image2', result2)
cv2.waitKey(0)
cv2.destroyAllWindows()
# save results
cv2.imwrite('pink_flower_masked1.png', result1)
cv2.imwrite('pink_flower_masked2.png', result2)
Les résultats sont les mêmes pour les deux méthodes:
Les autres réponses n'ont pas fonctionné pour moi. À l'époque, je passais tellement de temps à trouver une bonne fonction de masquage. Voici deux réponses simples avec numpy uniquement.
import numpy as np
arr = np.arange(27).reshape(3,3,3) #3 channel image
mask = np.zeros(shape=(3,3))
mask[1,1] = 1 # binary mask
mask_3d = np.stack((mask,mask,mask),axis=0) #3 channel mask
## Answer 1
# Simply multiply the image array with the mask
masked_arr = arr*mask_3d
## Answer 2
# Use the where function in numpy
masked_arr = np.where(mask_3d==1,arr,mask_3d)
#Both answer gives
print(masked_arr)
array([[[ 0., 0., 0.],
[ 0., 4., 0.],
[ 0., 0., 0.]],
[[ 0., 0., 0.],
[ 0., 13., 0.],
[ 0., 0., 0.]],
[[ 0., 0., 0.],
[ 0., 22., 0.],
[ 0., 0., 0.]]])
les multiplier?
Ce ne sont pas des images en niveaux de gris.
J'utilise matplotlib avec la palette de couleurs viridis pour qu'ils n'apparaissent pas gris, mais ils ne sont pas RVB.
Vos images ne sont pas de la même taille. Veuillez également toujours publier une image correcte sans carte de couleur; sinon, vous confondez les gens et compliquez également la démonstration d'une solution pour les images en niveaux de gris.