圆形掩盖使用numpy数组在python中的图像

我试图通过在Web上阅读代码来使用Python修改圆形图像,但在数学中完全丢失了:

我得到了一个类型= numpy.ndarray的图像(image_data),形状=(3725,4797,3)

total_rows, total_cols, total_layers = image_data.shape

X, Y = np.ogrid[:total_rows, :total_cols]

center_row, center_col = total_rows/2, total_cols/2

dist_from_center = (X - total_rows)**2 + (Y - total_cols)**2

radius = (total_rows/2)**2

circular_mask = (dist_from_center > radius)

我知道他应用欧几里德距离计算dist_from_center但我没有得到X – total_rows和Y – total_cols部分

X和Y在圈子上扮演什么角色?

最佳答案
您上网的算法部分错误,至少对您而言.如果我们有以下图像,我们希望它像这样掩盖:

Image to mask Masked image

创建这样的掩码的最简单方法是你的算法如何处理它,但它不是以你想要的方式呈现,也不能让你以简单的方式修改它.我们需要做的是查看图像中每个像素的坐标,并获得该像素是否在半径范围内的真/假值.例如,这是放大的图片,显示圆半径和严格在该半径范围内的像素:

Pixels inside the radius

现在,为了确定哪些像素位于圆内,我们需要图像中每个像素的索引.函数np.ogrid()给出两个向量,每个向量包含像素位置(或索引):列索引的列向量和行索引的行向量:

>>> np.ogrid[:4,:5]
[array([[0],
       [1],
       [2],
       [3]]), array([[0, 1, 2, 3, 4]])]

这种格式对于broadcasting很有用,所以如果我们在某些函数中使用它们,它实际上会创建所有索引的网格,而不仅仅是那两个向量.因此,我们可以使用np.ogrid()来创建图像的索引(或像素坐标),然后检查每个像素坐标以查看它是在圆圈内部还是外部.为了判断它是否在中心内,我们可以简单地找到从中心到每个像素位置的欧几里德距离,然后如果该距离小于圆半径,我们将标记为包含在掩模中,如果它比那更大,我们将它从面具中排除.

现在我们已经拥有了创建这个掩码的函数所需的一切.此外,我们将为它添加一些不错的功能;我们可以发送中心和半径,或者自动计算它们.

def create_circular_mask(h, w, center=None, radius=None):

    if center is None: # use the middle of the image
        center = [int(w/2), int(h/2)]
    if radius is None: # use the smallest distance between the center and image walls
        radius = min(center[0], center[1], w-center[0], h-center[1])

    Y, X = np.ogrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

    mask = dist_from_center <= radius
    return mask

在这种情况下,dist_from_center是指定的高度和宽度相同的矩阵.它将列和行索引向量广播到矩阵中,其中每个位置的值是距中心的距离.如果我们将这个矩阵可视化为一个图像(将其缩放到适当的范围),那么它将是从我们指定的中心辐射的梯度:

Distance gradient

因此,当我们将其与半径进行比较时,它与阈值化此梯度图像相同.

请注意,最终的掩模是布尔矩阵;如果该位置在距指定中心的半径范围内,则为True,否则为False.因此我们可以使用这个掩码作为我们关心的像素区域的指示器,或者我们可以采用与该布尔相反的方式(~in numpy)来选择该区域之外的像素.因此,使用此功能为黑色圆圈外的像素着色,就像我在本文顶部所做的那样,就像下面这样简单:

h, w = img.shape[:2]
mask = create_circular_mask(h, w)
masked_img = img.copy()
masked_img[~mask] = 0

但是如果我们想在与中心不同的点创建一个圆形蒙版,我们可以指定它(注意函数期望[x,y]顺序的中心坐标,而不是索引[row,col] = [y ,x]顺序):

center = [int(w/4), int(h/4)]
mask = create_circular_mask(h, w, center=center)

因为我们没有给出半径,所以会给我们最小的半径,这样圆圈仍然适合图像边界:

Off-center mask

或者我们可以让它计算中心但使用指定的半径:

radius = h/4
mask = create_circular_mask(h, w, radius=radius)

给我们一个中心圆,其半径不能完全延伸到最小尺寸:

Specified radius mask

最后,我们可以指定我们想要的任何半径和中心,包括延伸到图像边界之外的半径(并且中心甚至可以在图像边界之外!):

center = [int(w/4), int(h/4)]
radius = h/2
mask = create_circular_mask(h, w, center=center, radius=radius)

Off-center, larger radius mask

您在网上找到的算法相当于将中心设置为[0,0]并将半径设置为h:

mask = create_circular_mask(h, w, center=[0,0], radius=h)

Quarter-circle mask

转载注明原文:圆形掩盖使用numpy数组在python中的图像 - 代码日志