python - 使用 Python Numpy 将图像投影到球体内部

标签 python numpy geometry projection geometry-surface

问题:

假设我有一张大图像,5000x3000 像素。我想将此图像粘贴到任意半径的球体内部。

为此,我将图像导入为数组,并确定数组的中心。我将循环遍历每个像素,确定它距中心的位移距离,并使用此 x 和 y 位移,我将使用简单的几何形状来确定应将其复制到输出数组上的位置。

下面是我的输入和输出的一些示例(但规模比我尝试使用的要小得多)。

输入示例

Example input image

示例输出

Example output image

如何使用 python 和 numpy 加速我的方法,该方法在一个非常大的数组上逐像素进行,需要几分钟?


代码:

(x_d, y_d, z_d) = image.shape #get image dimensions
(x_c, y_c) = (x_d/2.0, y_d/2.0) #determine centre of image
new_image = np.zeros([x_m, y_m, d]) #create empty output image

for x in range(0, x_d): #iterate across pixels
    for y in range(0, y_d): #iterate down pixels
        (x_1, y_1) = (x-x_c, y-y_c) #determine pixel displacement from centre
        (r_x, r_y) = (np.sqrt((rad**2.0)-(y_1**2.0)), np.sqrt((rad**2.0)-(x_1**2.0))) #determine relative radius (maths part 2)
        #determine the relative radius
        x_2 = int(np.round(r_x*np.sin(x_1/r_x), 0)) #determine new x-position (maths part 1)
        y_2 = int(np.round(r_y*np.sin(y_1/r_y), 0)) #determine new y-position (maths part 1)
        x_2 = int(np.round(x_2+x_c, 0)) #convert back to absolute pixel location
        y_2 = int(np.round(y_2+y_c, 0)) #convert back to absolute pixel location
        new_image[x_2, y_2, :] = image[x, y, :] #...place the pixel there

尝试:

我已经搜索了预构建的库来执行此操作,但我对一些特定术语感到困惑,但尚未找到任何内容。

我尝试使用 numpy 的项和项集函数读取和写入数组值,但这实际上似乎会减慢处理速度。

由于我将在多个图像上运行它,因此我尝试首先生成转换数组,但这对运行时间的影响非常小。即:

def generate_array(array, rad):
    """
    Function takes image and returns array that can be used to warp it
    """
    #array generated as code above but saved to 2 dimensional array for resultant x and y locations
    return array

def spherize(image, array):
    """
    Function takes image and warps it up as defined by the array
    """
    #image processed as code above but maths is not performed, instead output x and y locations are read from previously generated array
    return new_image

数学:

Image explaining maths part 1 referred to in the code 解释代码中提到的“数学第 1 部分”的图像。这将获取结果像素位置,就像从粘贴图像的球体顶部看到的一样。如果半径在另一维度中保持相同,则该方法在一个维度中有效,但是对于球体,此有效半径会发生变化,因为距离中心越远,在球体内部绘制的圆就会变得越小。因此,“数学第 2 部分”在给定 y 中距球体中心的位移的情况下,找到在 x 中在球体内部绘制的圆的有效半径。

Image explaining maths part 2 referred to in the code 解释代码中提到的“数学第 2 部分”的图像。这会找到有效半径,用于根据 y 中距球体中心的位移来计算结果 x 位置。

最佳答案

我无法理解您共享的代码中的逻辑。如果您显示图像在图表中的位置,并且您可以提供一个将原始图像点正确映射到新图像点(可能是 10x10 图像)的小示例,将会有所帮助。

话虽如此,我认为您可以使用 universal functions 来加快计算速度。数组。这些函数使用优化的代码对整个数组执行按元素计算。

例如,您可以使用 indices 函数创建一个包含图像中每个像素的索引(x 和 y 坐标)的数组,然后对其进行所有计算。

这是使用数组计算的代码版本。这应该比循环所有像素运行得快得多。

(x_d, y_d, z_d) = (10,10,3) #image.shape #get image dimensions
(x_c, y_c) = (x_d/2.0, y_d/2.0) #determine centre of image
new_image = np.zeros([x_m, y_m, z_d]) #create empty output image

x, y = np.indices( (x_d, y_d) ) #create an array with the x and y coordintes of the pixels

# determine pixel displacement from centre
x1 = x - x_c
y1 = y - y_c

#determine relative radius (maths part 2)
rx = np.sqrt(rad**2 - y1**2)
ry = np.sqrt(rad**2 - x1**2)

#determine new x-position (maths part 1)
x2 = rx*np.sin(x1/rx)+x_c
y2 = ry*np.sin(y1/ry)+y_c

#convert back to absolute pixel location
x2 = (np.round(x2)).astype(int)
y2 = (np.round(y2)).astype(int)

#...place the pixel there
new_image[x2, y2] = image[x,y]

我相信我已经根据您的代码正确地重新创建了您的计算,但如果没有输入示例,我无法确定这是正确的。我希望这会有所帮助。

关于python - 使用 Python Numpy 将图像投影到球体内部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42738077/

相关文章:

python - 如何从 C++ 运行 Python 程序

python - Numpy 挤压 - 'list' 对象没有属性 'squeeze'

python - 试图在一个类中编译内核,得到 "__init__() got an unexpected keyword argument ' kernel'”错误

python - 如何在 python 中绘制多边形?

python - Python Fit圆,其中心位于图像外部

python - 从 df 列的列表中过滤项目

python - 如何在文本文件中搜索字符串?

python - 在python中更改数组的数据类型

python - 如何从品脱数量列表中创建 numpy 数组

algorithm - Intersection of n rectangles - 正好有 k 个矩形相交的区域的最大数量