首页 > 解决方案 > 在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++ 有帮助吗?

标签: pythonimage-processingimage-scaling

解决方案


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

这里有更多例子(在其他地方)


推荐阅读