Я играю с использованием 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
Здесь нужно понимать две вещи:
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
возникают из-за того, что патч достигает границ изображения (отступов нет).
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)
@user18615293 user18615293 проблема в том, что np.pad()
по умолчанию дополняет каждую ось. Смотрите редактирование моего ответа для решения. Вам нужно указать вручную, какие размеры дополнять. Я положил пример в своем ответе внизу.
большое спасибо ... ваше решение было именно тем, что мне было нужно.
спасибо за ответ... сработало. Я смог применить произвольное ядро изображения, а затем восстановить изображение из патчей ... Я почти достиг своей цели, единственная проблема - проблема с границами. Я удивлен, что экстрактор патчей не создает патчи для каждого пикселя, а просто избегает границы... есть ли простой способ дополнить изображение с помощью numpy, чтобы подушечка «оборачивала» изображение? Я попытался использовать np.pad(arr, 1, 'wrap'), но это дало мне форму (3, 1082, 1082, 5)... не то, что я ожидал.