python - 在给定索引和半径的 numpy 数组中绘制一个圆,无需外部库

标签 python arrays numpy geometry

我需要在 2D numpy 数组中画一个圆,给定 [i,j] 作为数组的索引,r 作为圆的半径。每次在索引 [i,j] 处满足条件时,应以该点为中心点绘制一个圆,并将圆内的所有值增加 +1。我想避免在画圆的最后出现 for 循环(我使用 p,q 来索引),因为我必须画可能数百万个圆。有没有不用for循环的方法?我也不想仅为一个任务导入另一个库。

这是我当前的实现:

for i in range(array_shape[0]):
    for j in range(array_shape[1]):
        if (condition):  # Draw circle if condition is fulfilled

            # Create a square of pixels with side lengths equal to radius of circle
            x_square_min = i-r
            x_square_max = i+r+1
            y_square_min = j-r
            y_square_max = j+r+1

            # Clamp this square to the edges of the array so circles near edges don't wrap around
            if x_square_min < 0:
                x_square_min = 0
            if y_square_min < 0:
                y_square_min = 0
            if x_square_max > array_shape[0]:
                x_square_max = array_shape[0]
            if y_square_max > array_shape[1]:
                y_square_max = array_shape[1]

            # Now loop over the box and draw circle inside of it
            for p in range(x_square_min , x_square_max):
                for q in range(y_square_min , y_square_max):
                    if (p - i) ** 2 + (q - j) ** 2 <= r ** 2:
                        new_array[p,q] += 1  # Incrementing because need to have possibility of 
                                             # overlapping circles              

最佳答案

添加每个圆都可以矢量化。此解决方案迭代满足条件的坐标。上2-core colab instance每秒可添加约 60k 个半径为 30 的圆。

import numpy as np

np.random.seed(42)
arr = np.random.rand(400,300)
r = 30

xx, yy = np.mgrid[-r:r+1, -r:r+1]
circle = xx**2 + yy**2 <= r**2

condition = np.where(arr > .999) # np.where(arr > .5) to benchmark 60k circles
for x,y in zip(*condition):
    # valid indices of the array
    i = slice(max(x-r,0), min(x+r+1, arr.shape[0]))
    j = slice(max(y-r,0), min(y+r+1, arr.shape[1]))

    # visible slice of the circle
    ci = slice(abs(min(x-r, 0)), circle.shape[0] - abs(min(arr.shape[0]-(x+r+1), 0)))
    cj = slice(abs(min(y-r, 0)), circle.shape[1] - abs(min(arr.shape[1]-(y+r+1), 0)))
    
    arr[i, j] += circle[ci, cj]

可视化np.array arr

import matplotlib.pyplot as plt

plt.figure(figsize=(8,8))
plt.imshow(arr)
plt.show()

result

关于python - 在给定索引和半径的 numpy 数组中绘制一个圆,无需外部库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71875073/

相关文章:

python - 为什么 numpy 本身就是 'slow'?

python - 对象没有属性

python - Django 管理员 : Get logged In users id in django

java - 为什么我的 View 数组返回 null?

python - 修改数组的值,其中相同大小的列表包含另一个列表的值

C char 数组(C 字符串)动态?

python - 将存储的 ndarray 转换为使用 cPickle 创建的二进制文件到 C++ 中的 cv::Mat

python - 在 PyQt5 中显示和隐藏多个窗口

python - 如何在 Python 中对节号列表进行排序?

python - 使用 python 验证 JSON 数据