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.