Sklearn patchextractor... недостающие элементы

Я играю с использованием python для применения различных ядер изображений к изображениям; Я использую sklearn.feature_extraction для создания патчей, однако, когда я это делаю, оказывается, что некоторые данные отсутствуют, что вызовет проблемы, когда я вернусь, чтобы восстановить изображение. Я делаю что-то не так, или мне нужно добавить буфер вокруг изображения при захвате патчей для пограничных случаев?

from PIL import Image
sklearn.feature_extraction import image
import numpy as np

img = Image.open('a.png')
arr = np.array(img)
patches = imagePatchExtractor(patch_size=(3,3)).fit(arr).transform(arr)

>>>arr.shape
(1080, 1080, 3)
>>>patches.shape
(1164240, 3, 3)
>>>1164240/1080
1078.0
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
31
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Здесь нужно понимать две вещи:

  1. image.PatchExtractor извлекает все возможные патчи с шагом 1 в каждом измерении. Например, с патчами формы (3, 3) вы получите arr[0:3, 0:3, 0], затем arr[1:4, 1:4, 0] и так далее. Следовательно, как правило, для размера патча (x, y) и размера изображения (w, h) вы получите (w-x+1)*(h-y+1) много патчей для каждого канала. -x+1 и -y+1 возникают из-за того, что патч достигает границ изображения (отступов нет).

  2. PatchExtractor.transform() ожидает, что первым измерением будет n_samples. Итак, в вашем случае форма должна быть (1, 1080, 1080, 3).

Собрав все это вместе, вот пример с поддельным меньшим изображением с одним каналом:

from sklearn.feature_extraction import image
import numpy as np

# Adding the n_samples dimension with reshape.
arr = np.arange(0, 6*6*1).reshape((1, 6, 6))
print(arr)
array([[[ 0,  1,  2,  3,  4,  5],
        [ 6,  7,  8,  9, 10, 11],
        [12, 13, 14, 15, 16, 17],
        [18, 19, 20, 21, 22, 23],
        [24, 25, 26, 27, 28, 29],
        [30, 31, 32, 33, 34, 35]]])
# Get all possible patches.
patches = image.PatchExtractor(patch_size=(3, 3)).fit(arr).transform(arr)
print(np.shape(patches))
print(patches[0, :])
print(patches[1, :])
shape: 
   # (6-3+1) * (6-3+1) = 16
   (16, 3, 3)

patches[0, :]:
   array([[ 0.,  1.,  2.],
          [ 6.,  7.,  8.],
          [12., 13., 14.]])

patches[1, :]:
   array([[ 1.,  2.,  3.],
          [ 7.,  8.,  9.],
          [13., 14., 15.]])

Как видите, результат соответствует приведенному выше объяснению. Патч 1 смещен на один пиксель вправо относительно патча 2.

Следовательно, в вашем случае с изображением формы (1080, 1080, 3):

# You also need this reshape to add the n_samples dimension.
arr = np.arange(0, 1080*1080*3).reshape((1, 1080, 1080, 3))
patches = image.PatchExtractor(patch_size=(3, 3)).fit(arr).transform(arr)
print(np.shape(patches))
# (1080-3+1)*(1080-3+1) = 1162084
(1162084, 3, 3, 3)

РЕДАКТИРОВАТЬ - патчи с отступами:

Если вы хотите иметь одинаковое количество патчей для каждого пикселя, вы можете заполнить изображение, используя np.pad(). Обратите внимание, что по умолчанию он дополняет все оси, поэтому нам нужно вручную указать количество прокладок для каждой оси:

# Padding amount for each axis. Here: amount should be patch_size-1.
# Here, the format is (pad_before, pad_after) for each dimension.
paddings = ((0, 0), (1, 1), (1, 1), (0, 0))
wrapped_arr = np.pad(arr, pad_width=paddings, mode='wrap')
wrapped_patches = image.PatchExtractor(patch_size=(3, 3)).fit(wrapped_arr).transform(wrapped_arr)

print(np.shape(wrapped_patches))
# 1080*1080 = 1166400
(1166400, 3, 3, 3)

спасибо за ответ... сработало. Я смог применить произвольное ядро ​​изображения, а затем восстановить изображение из патчей ... Я почти достиг своей цели, единственная проблема - проблема с границами. Я удивлен, что экстрактор патчей не создает патчи для каждого пикселя, а просто избегает границы... есть ли простой способ дополнить изображение с помощью numpy, чтобы подушечка «оборачивала» изображение? Я попытался использовать np.pad(arr, 1, 'wrap'), но это дало мне форму (3, 1082, 1082, 5)... не то, что я ожидал.

user18615293 17.05.2022 09:11

@user18615293 user18615293 проблема в том, что np.pad() по умолчанию дополняет каждую ось. Смотрите редактирование моего ответа для решения. Вам нужно указать вручную, какие размеры дополнять. Я положил пример в своем ответе внизу.

user2246849 17.05.2022 09:20

большое спасибо ... ваше решение было именно тем, что мне было нужно.

user18615293 17.05.2022 09:35

Другие вопросы по теме