简体   繁体   English

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

[英]How to Mask an image using Numpy/OpenCV?

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. 不起作用。

Use cv2.bitwise_and and 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)

circle is just a 2D array with 1.0 s and 0.0 s. circle只是一个1.0 s和0.0 s的2D数组。 Numpy needs help to understand what you want to do with the third dimension of your im so you must give it an extra axis and then your line would work. 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. 但请注意,如果图像缺少alpha通道,则屏蔽只是根据代码将颜色设置为(0, 0, 0)

However you have another potential problem: circle will be of the default data-type (which probably will be float64 or float32 . That's not good for your image, so you should change the line where you create circle to 但是你有另一个潜在的问题: circle将是默认的数据类型(可能是float64float32 。这对你的图像不好,所以你应该改变你创建circle

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

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

使用NumPy赋值给索引数组

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM