python - 在python中通过局部平均实现图像缩小太慢
问题描述
我有一个 python 函数,它将表示 RGB 图像的三维数组作为输入,并输出另一个表示原始图像缩小版本的三维数组。我使用局部平均的概念来计算缩小矩阵的像素值。即使我的实现在输入数组的大小上是线性的,但对于稍微大的图像(例如 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++ 有帮助吗?
解决方案
import numpy as np
import cv2
# blah blah your code here
small_image = cv2.resize(image, (width, height), cv2.INTER_AREA)
# blah blah enjoy small image
这里有更多例子(在其他地方)
推荐阅读
- c - 控制台 I/O:printf 和 scanf 未按预期顺序发生
- python - Python中函数的输出
- visual-studio-code - Ctrl + 单击 VS Code 终端,在新窗口中显示打开的文件夹
- python - 如何访问 GridSearchCV 的 SGDClassifier 参数?
- h3 - 更好的五边形/六边形面积比
- python - python通过QuickFix连接到多个会话
- python - 无法在 ubuntu 18.04 中安装 python3-pip(python 版本 -> python3.7)
- python - 将变量的值从一个文件导入另一个文件而不在python中执行函数
- android - 来自普通函数的 Flutter 调用构建器函数
- c# - 如何在 c# 中使用 AES 128 位加密字符串?