使用 Python Numpy 将图像投影到球体内部
Project image onto inside of sphere with Python Numpy
问题:
假设我有一张大图片,5000x3000 像素。我想将此图像粘贴到某个任意半径的球体内部。
为此,我会将图像作为数组导入,然后确定数组的中心。我将遍历每个像素,确定它与中心的位移距离,并使用这个 x 和 y 位移,我将使用简单的几何图形来确定它应该被复制到输出数组的哪个位置。
以下是我的输入和输出的一些示例(但规模比我尝试使用的要小得多)。
示例输入
示例输出
如何使用 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
数学:
图像解释 "maths part 1" 代码中提到的。 这将获得结果像素位置,就像从粘贴图像的球体顶部看到的一样。如果半径在另一个维度上保持不变,这在一个维度上有效,但是对于球体,此有效半径会发生变化,因为在球体内部绘制的圆变得越小,您离中心越远。因此,"maths part 2" 找到在 x 中球体内部绘制的圆的有效半径,给定距球体中心 y 的位移。
图像解释代码中提到的 "maths part 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]
我相信我已经根据您的代码正确地重新创建了您的计算,但是没有输入示例我无法确定这是正确的。希望对您有所帮助。
问题:
假设我有一张大图片,5000x3000 像素。我想将此图像粘贴到某个任意半径的球体内部。
为此,我会将图像作为数组导入,然后确定数组的中心。我将遍历每个像素,确定它与中心的位移距离,并使用这个 x 和 y 位移,我将使用简单的几何图形来确定它应该被复制到输出数组的哪个位置。
以下是我的输入和输出的一些示例(但规模比我尝试使用的要小得多)。
示例输入
示例输出
如何使用 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
数学:
我无法理解您共享的代码中的逻辑。如果您显示图像在图表中的位置,并且您可以提供一个小示例,说明原始图像点到新图像点的正确映射(可能是 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]
我相信我已经根据您的代码正确地重新创建了您的计算,但是没有输入示例我无法确定这是正确的。希望对您有所帮助。