Python 如何使用 Numpy/OpenCV 屏蔽图像?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25074488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 19:41:53  来源:igfitidea点击:

How to Mask an image using Numpy/OpenCV?

pythonopencvnumpy

提问by Hidden Name

I have an image I load with:

我有一个我加载的图像:

im = cv2.imread(filename)

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

我想保留图像中心的数据。我创建了一个圆圈作为我想要保留的区域的蒙版。

I created the 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 out the data outside of the circle from the original image?

如何从原始图像中屏蔽掉圆圈外的数据?

masked_data = im * circle

does not work.

不起作用。

回答by deinonychusaur

circleis just a 2D array with 1.0s and 0.0s. Numpy needs help to understand what you want to do with the third dimension of your imso you must give it an extra axis and then your line would work.

circle只是一个带有1.0s 和0.0s的二维数组。Numpy 需要帮助来理解你想用你的第三维做什么,im所以你必须给它一个额外的轴,然后你的线才能工作。

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

But note that the masking is simply setting the color to (0, 0, 0)for things outside the circle according to your code if the image lacks an alpha-channel.

但请注意,(0, 0, 0)如果图像缺少 alpha 通道,则遮罩只是根据您的代码将颜色设置为圆圈外的事物。

However you have another potential problem: circlewill be of the default data-type (which probably will be float64or float32. That's not good for your image, so you should change the line where you create circleto

但是,您还有另一个潜在问题:circle将是默认数据类型(可能是float64float32。这对您的图像不利,因此您应该将创建的行更改circle

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

回答by Kasramvd

In this case if you want to have a circular image you must write a new algorithm and first you must be able to access to the coordinates of the pixels. Then you can simply compare pixels that are not within the scope of that circle or not and replace them with some value (or NULL if it's accepted with your image format criteria).

在这种情况下,如果你想要一个圆形图像,你必须编写一个新算法,首先你必须能够访问像素的坐标。然后,您可以简单地比较不在该圆圈范围内的像素,并将它们替换为某个值(如果您的图像格式标准接受,则将其替换为 NULL)。

Here is an example:

下面是一个例子:

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

回答by Froyo

Use cv2.bitwise_andand pass the circle as mask.

使用cv2.bitwise_and并传递圆圈作为掩码。

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)

回答by Delgan

Using NumPy assignment to an indexed array:

使用NumPy 赋值给索引数组

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