У меня есть функция python, которая принимает трехмерный массив, представляющий изображение RGB, в качестве входных данных и выводит другой трехмерный массив, который представляет уменьшенную версию исходного изображения. Я использую концепцию локального усреднения для вычисления значений пикселей уменьшенной матрицы. Несмотря на то, что моя реализация имеет линейный размер входного массива, ей все равно требуется много времени, чтобы функция достигла конечного значения sh, для немного больших изображений (например, 1536 X 2048). Вот мой код
import numpy as np
import math
def scale_down_image(image, height, width):
'''
Scales down a given image bitmap to new dimensions, provided that
the new dimesions dont exceed those of the image to be
scaled
'''
# determine original image dimensions
image_height = image.shape[0]
image_width = image.shape[1]
assert image_height >= height and image_width >= width
# create row_arr and col_arr arrays which help in querying window sum
image = np.array(image, dtype=np.uint64)
row_arr = np.zeros(image.shape, dtype=np.uint64)
col_arr = np.zeros(image.shape, dtype=np.uint64)
for i in range(image.shape[2]):
for j in range(image.shape[0]):
for k in range(image.shape[1]):
if j == 0 and k == 0:
row_arr[j][k][i] = image[j][k][i]
col_arr[j][k][i] = image[j][k][i]
elif j == 0:
row_arr[j][k][i] = row_arr[j][k - 1][i] + image[j][k][i]
col_arr[j][k][i] = image[j][k][i]
elif k == 0:
row_arr[j][k][i] = image[j][k][i]
col_arr[j][k][i] = col_arr[j - 1][k][i] + image[j][k][i]
else:
row_arr[j][k][i] = row_arr[j][k - 1][i] + image[j][k][i]
col_arr[j][k][i] = col_arr[j - 1][k][i] + image[j][k][i]
# create range_query_arr array, which helps in querying window sum
range_query_arr = np.zeros(image.shape, dtype=np.uint64)
for i in range(image.shape[2]):
for j in range(image.shape[0]):
for k in range(image.shape[1]):
if j == 0 and k == 0:
range_query_arr[j][k][i] = image[j][k][i]
elif j == 0:
range_query_arr[j][k][i] = row_arr[j][k][i]
elif k == 0:
range_query_arr[j][k][i] = col_arr[j][k][i]
else:
range_query_arr[j][k][i] = (range_query_arr[j - 1][k - 1][i] +
row_arr[j][k - 1][i] + col_arr[j - 1][k][i] + image[j][k][i])
# define a recursive function query, which computes the sum of elements in any window
def query(y1, x1, y2, x2, channel):
assert 0 <= channel < image.shape[2]
if not (0 <= y1 < image.shape[0] and 0 <= x1 < image.shape[1] and 0 <= y2 < image.shape[0]
and 0 <= x2 < image.shape[1] and y1 <= y2 and x1 <= x2):
return 0
else:
return (range_query_arr[y2][x2][channel] - query(0, 0, y2, x1 - 1, channel) -
query(0, 0, y1 - 1, x2, channel) + query(0, 0, y1 - 1, x1 - 1, channel))
# determine window dimensions
window_height = int(math.ceil(image_height / height))
window_width = int(math.ceil(image_width / width))
# compute scaled image
scaled_image = np.zeros((height, width, image.shape[2]), dtype=np.uint64)
for i in range(scaled_image.shape[2]):
for j in range(scaled_image.shape[0]):
for k in range(scaled_image.shape[1]):
y1 = max(0, int(((j + 1) / height) * image_height - 1 - window_height / 2))
x1 = max(0, int(((k + 1) / width) * image_width - 1 - window_width / 2))
y2 = min(image_height - 1, y1 + window_height - 1)
x2 = min(image_width - 1, x1 + window_width - 1)
scaled_image[j][k][i] = query(y1, x1, y2, x2, i) // ((y2 - y1 + 1) *
(x2 - x1 + 1))
# return scaled image
return np.array(scaled_image, dtype=np.uint8)
Не могли бы вы предложить что-то, что заставило бы это работать быстрее? Должен ли я использовать другой алгоритм? Поможет ли перемещение моего кода в C ++?