Уменьшить numpy массив изображений в Python путем усреднения - PullRequest
0 голосов
/ 21 февраля 2020

Как уменьшить изображение любого разрешения до четверти размера путем усреднения пикселей в numpy?

То, что я придумал в ходе исследования, работает только для изображений, имеющих квадратную форму (то есть с 512 х 512 до 128 х 128), но не будет работать с изображениями разных размеров (то есть с 2400 х 1800 до 600 х 450 ). В этих случаях я получаю IndexError: индекс 450 выходит за пределы для оси 1 с размером 450 .

Я пытаюсь выполнить эту задачу с помощью numpy манипулирования массивом и без установки других пакетов и библиотек.

Я исследовал функцию

numpy.mean()

, но я не не знаю, как использовать его для решения этой проблемы.

import cv2
import numpy as np

def quarter_res_avg(im):

    original_width = im.shape[1]
    original_height = im.shape[0]

    width = original_width / 4
    height = original_height / 4

    resized_image = np.zeros(shape=(width, height, 3), dtype=np.uint8)

    scale = 4

    for i in range(width):
        for j in range(height):
            temp = np.array([0, 0, 0])
            for x in range(scale):
                for y in range(scale):
                    temp += im[i*scale+x, j*scale+y]
            resized_image[i, j] = temp/(scale*scale)

    return resized_image

im = cv2.imread('Lenna_test_image.png', 1)
cv2.imwrite('Lenna_test_image_avg.png', quarter_res_avg(im))

Любые идеи очень ценятся.

Спасибо.

Ответы [ 3 ]

2 голосов
/ 21 февраля 2020
import numpy as np
import skimage.measure

your_array = np.random.rand(2400, 800)

new_array = skimage.measure.block_reduce(your_array, (4,4), np.mean)
print(new_array.shape)
Out[18]: (600, 450)
0 голосов
/ 27 февраля 2020

Ответ, который работал для меня с помощью @MarkSetchell в комментариях к вопросу.

Без использования np.mean ()

def quarter_res_avg(im):

    original_width = im.shape[1]
    original_height = im.shape[0]
    width = original_width / 4
    height = original_height / 4

    resized_image = np.zeros(shape=(height, width, 3), dtype=np.uint8)
    scale = 4

    for i in range(height):
        for j in range(width):
            temp = np.array([0, 0, 0])
            for x in range(scale):
                for y in range(scale):
                    temp += im[i*scale + x, j*scale + y]
            resized_image[i, j] = temp/(scale*scale)

return resized_image

im = cv2.imread('Lenna_test_image.png', 1)
cv2.imwrite('Lenna_test_image_resized.png', quarter_res_avg(im))    

Используя np.mean (), замените циклы for на:

for i in range(0, original_height, scale):
    for j in range(0, original_width, scale):
        resized_image[i/scale, j/scale] = np.mean(im[i:i + scale, j:j+scale], axis=(0,1))
0 голосов
/ 21 февраля 2020

Сначала преобразуйте изображение M x N в массив (M // 4) x 4 x (N // 4) x 4, затем используйте np.mean во втором и последнем измерениях.

from typing import Tuple
import numpy as np

def downsample_by_averaging(img: np.ndarray, window_shape: Tuple[int, int]) -> np.ndarray:
    return np.mean(
        img.reshape((
            *img.shape[:-2],
            img.shape[-2] // window_shape[-2], window_shape[-2],
            img.shape[-1] // window_shape[-1], window_shape[-1],
        )),
        axis=(-1, -3),
    )

downsample_by_averaging(img, (4, 4))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...