¿Cómo enmascarar una imagen usando Numpy / OpenCV?

Tengo una imagen que carga con:

im = cv2.imread(filename) 

Quiero mantener los datos que están en el centro de la imagen. Creé un círculo como máscara del área que quiero mantener.

Creé el círculo con:

 height,width,depth = im.shape circle = np.zeros((height,width)) cv2.circle(circle,(width/2,height/2),280,1,thickness=-1) 

¿Cómo puedo enmascarar los datos fuera del círculo de la imagen original?

 masked_data = im * circle 

No funciona.

Usa cv2.bitwise_and y pasa el círculo como máscara.

 im = cv2.imread(filename) height,width,depth = im.shape circle_img = np.zeros((height,width), np.uint8) cv2.circle(circle_img,(width/2,height/2),280,1,thickness=-1) masked_data = cv2.bitwise_and(im, im, mask=circle_img) cv2.imshow("masked", masked_data) cv2.waitKey(0) 

circle es solo una matriz 2D con 1.0 sy 0.0 s. Numpy necesita ayuda para comprender lo que quiere hacer con la tercera dimensión de su im por lo que debe asignarle un eje adicional y luego su línea funcionará.

 masked_data = im * circle[..., np.newaxis] 

Pero tenga en cuenta que el enmascaramiento es simplemente establecer el color en (0, 0, 0) para cosas fuera del círculo de acuerdo con su código si la imagen carece de un canal alfa.

Sin embargo, tiene otro problema potencial: el circle será del tipo de datos predeterminado (que probablemente será float64 o float32 . Eso no es bueno para su imagen, por lo que debe cambiar la línea donde crea el circle para

 circle = np.zeros((height, width), dtype=im.dtype) 

Usando la asignación NumPy a una matriz indexada :

 im[circle == 0] = [0, 0, 0] 

En este caso, si desea tener una imagen circular, debe escribir un nuevo algoritmo y primero debe poder acceder a las coordenadas de los píxeles. Luego, simplemente puede comparar los píxeles que no están dentro del scope de ese círculo o no y reemplazarlos con algún valor (o NULL si se acepta con sus criterios de formato de imagen).

Aquí hay un ejemplo:

 import cv2 import numpy as np im = cv2.imread('sss.png') def facechop(im): height,width,depth = im.shape #circle = np.zeros((height,width)) #print circle x=width/2 y=height/2 circle=cv2.circle(im,(width/2,height/2),180,1,thickness=1) #newcameramtx, roi=cv2.getOptimalNewCameraMatrix(im,10,(w,h),1,(w,h)) cv2.rectangle(im,(x-180,y-180),(x+180,y+180),(0,0,255),2) crop_img = im[y-180:y+180,x-180:x+180] lastim=np.equal(crop_img,circle) #dd=np.logical_and(crop_img,circle) for i in range(len(last_im)) : if last_im[i].all()==False: crop_img[i]=[0,0,0] cv2.imshow('im',crop_img) if __name__ == '__main__': facechop(im) while(True): key = cv2.waitKey(20) if key in [27, ord('Q'), ord('q')]: break