How to mask an image using Numpy / OpenCV?

I have an image that I upload:

im = cv2.imread(filename) 

I want to keep the data in the center of the image. I created a circle as a mask of the area I want to keep.

I created a circle with:

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

How can I mask data outside the circle from the original image?

 masked_data = im * circle 

does not work.

+8
python numpy opencv
source share
4 answers

Use cv2.bitwise_and and pass the circle as a mask.

 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) 
+11
source share

circle is just a 2D array with 1.0 and 0.0 s. Numpy needs help to figure out what you want to do with the third dimension of your im , so you have to give it an extra axis, and then your line will work.

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

But note that masking just sets the color (0, 0, 0) for objects outside the circle according to your code if there is no alpha channel in the image.

However, you have one more potential problem: circle will have a default data type (which is likely to be float64 or float32 . This is not appropriate for your image, so you must change the line in which you create a circle to

 circle = np.zeros((height, width), dtype=im.dtype) 
+4
source share

In this case, if you want to have a circular image, you must write a new algorithm, and first you must have access to the coordinates of the pixels .... then you can compare all the pixels that are not in the area of ​​the circle should get Null, then y you have everything you want! but I don’t know if opencv is null or not? so you can try it!

I am also writing this code and trying in some way, but I could not get the correct result! in this code, I create a rectangle around the circle and try to return pixels outside the circle!

 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 
0
source share

Usage NumPy for an indexed array :

 im[circle == 0] = [0, 0, 0] 
0
source share

All Articles