Python 根据圆的面积更改numpy数组中的值

Python 根据圆的面积更改numpy数组中的值,python,algorithm,numpy,computational-geometry,Python,Algorithm,Numpy,Computational Geometry,上下文 我需要测量python中组合圆的面积。我想出了使用numpy数组的方法。首先,我用零填充一个网格(numpy数组),网格中的每个位置对应于0.5cm的长度。然后将圆心放在网格上,并在网格中将该值更改为1。我知道圆的半径,所以我可以计算圆的面积,因为我知道圆的面积,我改变了网格中的零,这些零落在圆的面积内。然后我计算网格中的频率,并使用它来计算组合圆的面积,因为我知道网格中每个位置的长度,我可以计算面积。这是目前一种非常粗粒度的方法,我计划在确定算法后将其更改为更细的粒度 示例 class

上下文

我需要测量python中组合圆的面积。我想出了使用numpy数组的方法。首先,我用零填充一个网格(numpy数组),网格中的每个位置对应于0.5cm的长度。然后将圆心放在网格上,并在网格中将该值更改为1。我知道圆的半径,所以我可以计算圆的面积,因为我知道圆的面积,我改变了网格中的零,这些零落在圆的面积内。然后我计算网格中的频率,并使用它来计算组合圆的面积,因为我知道网格中每个位置的长度,我可以计算面积。这是目前一种非常粗粒度的方法,我计划在确定算法后将其更改为更细的粒度

示例

class area():

    def make_grid(self):
        '''
        Each square in the grid represents 0.5 cm
        '''
        import numpy as np
        grid = np.zeros((10,10))
        square_length = 0.5
        circles = {'c1':[[4,2],1.5],'c2':[[5,6],2.0]}

        print grid
        for key,val in circles.iteritems():
            grid[val[0][0]][val[0][1]] = 1
            area = int((val[1] - square_length)/0.5)            
            for i in xrange(1,area+1):
                grid[val[0][0]][val[0][1]+i] = 1 # Change column vals in +ve direction
                grid[val[0][0]][val[0][1]-i] = 1 # Chnage column vals in -ve direction
                grid[val[0][0]+i][val[0][1]] = 1 # Chnage row vals in +ve direction 
                grid[val[0][0]-i][val[0][1]] = 1 # Chnage row vals in -ve direction

        print ''
        print grid
如果你看看我贴在下面的图片,它更好地描述了我的想法。在我的网格上有两个圆圈(红线),圆圈的中心用蓝色正方形标记,圆圈占据的区域用浅橙色表示。我想把标有橙色的区域改为1。目前,我可以将橙色正方形水平和垂直于圆心进行更改,但中心的对角线框给我带来了麻烦

当前代码

class area():

    def make_grid(self):
        '''
        Each square in the grid represents 0.5 cm
        '''
        import numpy as np
        grid = np.zeros((10,10))
        square_length = 0.5
        circles = {'c1':[[4,2],1.5],'c2':[[5,6],2.0]}

        print grid
        for key,val in circles.iteritems():
            grid[val[0][0]][val[0][1]] = 1
            area = int((val[1] - square_length)/0.5)            
            for i in xrange(1,area+1):
                grid[val[0][0]][val[0][1]+i] = 1 # Change column vals in +ve direction
                grid[val[0][0]][val[0][1]-i] = 1 # Chnage column vals in -ve direction
                grid[val[0][0]+i][val[0][1]] = 1 # Chnage row vals in +ve direction 
                grid[val[0][0]-i][val[0][1]] = 1 # Chnage row vals in -ve direction

        print ''
        print grid
在上面的字典中,关键是圆的名称,值中的第一个元素是圆心坐标,第二个元素是圆的半径

import numpy as np
import matplotlib.pyplot as plt

grid = np.zeros((10,10), dtype=np.bool)
square_length = 0.5
circles = {'c1':[[4,2],1.5],'c2':[[5,6],2.0]}

# Generate arrays of indices/coordiates so we can do the
# calculations the Numpy way, without resorting to loops
# I always get the index order wrong so double check...
xx = np.arange(grid.shape[0])
yy = np.arange(grid.shape[1])

for val in circles.itervalues():
    radius = val[1]
    # same index caveat here
    # Calling Mr Pythagoras: Find the pixels that lie inside this circle
    inside = (xx[:,None] - val[0][0]) ** 2 + (yy[None, :] - val[0][1]) ** 2 <= (radius ** 2)
    # do grid & inside and initialize grid with ones for intersection instead of union
    grid = grid | inside 

plt.imshow(grid)
plt.show()
if (np.sqrt((xx - val[0][0]) ** 2 + (yy - val[0][1]) ** 2) <= radius) :inside=inside+1
代码输出:

[[ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  1.  0.  0.  0.  1.  0.  0.  0.]
 [ 0.  0.  1.  0.  0.  0.  1.  0.  0.  0.]
 [ 1.  1.  1.  1.  1.  0.  1.  0.  0.  0.]
 [ 0.  0.  1.  1.  1.  1.  1.  1.  1.  1.]
 [ 0.  0.  1.  0.  0.  0.  1.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  1.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  1.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]]

您仅从中心直接向左和向右搜索。为了得到从中心到对角线的正方形,您可能必须使用。根据这个定理,你可以用相对于圆心的水平和垂直偏移量作为边长来求正方形的斜边。然后,可以将斜边与半径进行比较,如果斜边是两者中较短的,则将平方值增加1


半径的用法也有点奇怪,因为它没有使用正方形的中间作为中心。这使得半径为2的圆的直径为3.5

根据@Jaime的评论更新

我可能会从这样的事情开始。重点是正确计算圆内的像素

import numpy as np
import matplotlib.pyplot as plt

grid = np.zeros((10,10), dtype=np.bool)
square_length = 0.5
circles = {'c1':[[4,2],1.5],'c2':[[5,6],2.0]}

# Generate arrays of indices/coordiates so we can do the
# calculations the Numpy way, without resorting to loops
# I always get the index order wrong so double check...
xx = np.arange(grid.shape[0])
yy = np.arange(grid.shape[1])

for val in circles.itervalues():
    radius = val[1]
    # same index caveat here
    # Calling Mr Pythagoras: Find the pixels that lie inside this circle
    inside = (xx[:,None] - val[0][0]) ** 2 + (yy[None, :] - val[0][1]) ** 2 <= (radius ** 2)
    # do grid & inside and initialize grid with ones for intersection instead of union
    grid = grid | inside 

plt.imshow(grid)
plt.show()
if (np.sqrt((xx - val[0][0]) ** 2 + (yy - val[0][1]) ** 2) <= radius) :inside=inside+1
将numpy导入为np
将matplotlib.pyplot作为plt导入
grid=np.zero((10,10),dtype=np.bool)
方形长度=0.5
圆圈={'c1':[[4,2],1.5],'c2':[[5,6],2.0]}
#生成索引/坐标的数组,这样我们就可以
#以Numpy方式计算,无需使用循环
#我总是把索引顺序弄错,所以仔细检查。。。
xx=np.arange(grid.shape[0])
yy=np.arange(grid.shape[1])
对于圆中的val.itervalues():
半径=val[1]
#这里也有相同的索引警告
#给毕达哥拉斯先生打电话:找到这个圆圈里的像素
inside=(xx[:,None]-val[0][0])**2+(yy[None,:]-val[0][1])**2您可以在稍微修改停止条件的情况下使用:同时考虑颜色和到圆心的距离


p.S.低尺寸区域的Hack方法:绘制填充圆并计算颜色像素…

您可以使用蒙特卡罗方法来查找重叠区域的面积。这样会更准确。

找到正方形的边界,然后用随机数填充,对于每个随机数,检查随机数是否在圆内

import numpy as np
import matplotlib.pyplot as plt

grid = np.zeros((10,10), dtype=np.bool)
square_length = 0.5
circles = {'c1':[[4,2],1.5],'c2':[[5,6],2.0]}

# Generate arrays of indices/coordiates so we can do the
# calculations the Numpy way, without resorting to loops
# I always get the index order wrong so double check...
xx = np.arange(grid.shape[0])
yy = np.arange(grid.shape[1])

for val in circles.itervalues():
    radius = val[1]
    # same index caveat here
    # Calling Mr Pythagoras: Find the pixels that lie inside this circle
    inside = (xx[:,None] - val[0][0]) ** 2 + (yy[None, :] - val[0][1]) ** 2 <= (radius ** 2)
    # do grid & inside and initialize grid with ones for intersection instead of union
    grid = grid | inside 

plt.imshow(grid)
plt.show()
if (np.sqrt((xx - val[0][0]) ** 2 + (yy - val[0][1]) ** 2) <= radius) :inside=inside+1

if(np.sqrt((xx-val[0][0])**2+(yy-val[0][1])**2)你是不是应该跨过整个网格,计算每个网格点到每个圆心的距离,然后查看它是否在圆内,并将网格点计数器增加一个?这样,一些点将有2个而不是1个,但至少是圆内的所有点(舍入问题除外)已经计算过了。它比较慢,因为你必须把所有的点都看完,但是它可能更简单。你考虑几何解来测量面积吗??我曾考虑过几何解决方案,但如果我有多个圆圈,如问题中所述的“缺失区域”,则会出现问题:+1我认为这是解决问题的方法。我将去掉
np.sqrt
,并与
半径**2
进行比较。此外,通过使用
,我认为您正在确定所有圆圈重叠的点s、 使用
网格
零网格
网格
来获取任何圆内的点。您也可以不使用
网格
,而是使用
xx=np.arange(grid.shape[0])
yy=np.arange(grid.shape[1])
,然后使用广播作为
内=(xx[:,None]-val[0][0]**2+(yy-val[0][1])**2啊,是的,我理解“组合圆”是指交叉点,但有联合是有意义的。谢谢你的评论-将更新我的答案。