我正在尝试用 Python 对图像进行圆形遮罩。我在网上找到了一些示例代码,但我不确定如何更改数学以使我的圆圈位于正确的位置。
我有一个图像 image_data
类型 numpy.ndarray
形状 (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
part这会生成一个四分之一圆的蒙版,以图像的左上角为中心。
X
和 Y
在圆圈上扮演什么角色?我如何修改此代码以生成一个位于图像中其他位置中心的蒙版?
原文由 user7469692 发布,翻译遵循 CC BY-SA 4.0 许可协议
您在线获得的算法部分错误,至少对于您的目的而言。如果我们有以下图像,我们希望它像这样被屏蔽:
创建像这样的掩码的最简单方法是你的算法如何处理它,但它没有以你想要的方式呈现,也没有让你能够以简单的方式修改它。我们需要做的是查看图像中每个像素的坐标,并获得该像素是否在半径内的真/假值。例如,这是一张放大的图片,显示了圆半径和严格在该半径内的像素:
现在,要找出哪些像素位于圆圈内,我们需要图像中每个像素的索引。函数
np.ogrid()
给出两个向量,每个包含像素位置(或索引):列索引有一个列向量,行索引有一个行向量:这种格式对于 广播 很有用,因此如果我们在某些函数中使用它们,它实际上会创建一个包含所有索引的网格,而不仅仅是这两个向量。因此,我们可以使用
np.ogrid()
创建图像的索引(或像素坐标),然后检查每个像素坐标以查看它是在圆内还是圆外。为了判断它是否在中心内,我们可以简单地找到从中心到每个像素位置的欧几里德距离,然后如果该距离小于圆半径,我们将标记为 包含 在掩码中,如果它比那个大,我们将把它从面具中 _排除_。现在我们已经拥有了创建这个掩码的函数所需的一切。此外,我们将向它添加一些不错的功能;我们可以发送中心和半径,或者让它自动计算它们。
在这种情况下,
dist_from_center
是一个具有相同高度和指定宽度的矩阵。它将列和行索引向量广播到一个矩阵中,其中每个位置的值是到中心的距离。如果我们将这个矩阵可视化为图像(将其缩放到适当的范围内),那么它将是一个从我们指定的中心辐射的梯度:因此,当我们将它与
radius
进行比较时,它与对该梯度图像进行阈值处理是相同的。请注意,最终掩码是布尔矩阵;
True
如果该位置在指定中心的半径范围内,False
否则。所以我们可以使用这个掩码作为我们关心的像素区域的指示器,或者我们可以取该布尔值的相反值(~
innumpy
)来选择外部的像素那个地区。因此,使用此函数将圆圈外的像素着色为黑色,就像我在本文顶部所做的那样,非常简单:但是如果我们想在与中心不同的点创建一个圆形掩码,我们可以指定它(请注意,该函数期望中心坐标
x, y
顺序,而不是索引row, col = y, x
订单):其中,因为我们没有给出半径,所以会给我们最大的半径,这样圆仍然适合图像边界:
或者我们可以让它计算中心但使用指定的半径:
给我们一个半径不完全延伸到最小尺寸的圆心圆:
最后,我们可以指定我们想要的任何半径和中心,包括延伸到图像边界之外的半径(中心甚至可以在图像边界之外!):
您在网上找到的算法的作用相当于将中心设置为
(0, 0)
并将半径设置为h
: