#python #image-processing #sliding-window
Вопрос:
У меня есть изображение, и я хочу разделить его на несколько изображений, используя вертикальные и горизонтальные шаги, такие как скользящее окно, и все полученные изображения будут иметь одинаковое разрешение. Как я могу сделать это эффективно в Python? Я сделал так много:
from PIL import Image
def sliding_window(image, stride, imgSize):
width, height = image.size
img = []
for y in range(0, height-imgSize, stride):
for x in range(0, width-imgSize, stride):
# Setting the points for cropped image
left = x
top = y
right = x imgSize
bottom = y imgSize
im1 = image.crop((left, top, right, bottom))
img.append(im1)
return img
file = "/home/xxxxxx/yyyyyy.png"
im = Image.open(file)
img = sliding_window(im, 1, 838) # Strides of 1 takes too much time
но этот код требует слишком много оперативной памяти и отнимает слишком много времени. Пожалуйста, помогите.
Пример :
Пример кода : img = sliding_window(im, 200, 300)
Следующее изображение имеет размер 800*800.
Выход :
Комментарии:
1. Пожалуйста, покажите минимальный пример того, что вы хотите. Действительно ли код, который вы показываете, работает?
2. вы отображаете его с помощью matplotlib, чтобы вы могли загружать изображение как
numpy.array
и просто использоватьimg[y:y 200, x:x 200]
, чтобы получить часть изображения и отобразить его — и это должно работать быстрее. Он не дублирует изображение, но использует данные из исходного массива. В конечном итоге вы можете скопировать его с помощьюimg[y:y 200, x:x 200].copy()
3. если вы сделали только некоторые clculation без отображения, то, возможно, вам следует сделать это непосредственно внутри
sliding_window
, не сохраняя изображения в списке. Таким образом, он должен использовать меньше памяти4. @furas Я хочу вернуть массив numpy, содержащий все возможные изображения в указанном выше формате, у меня есть несколько изображений для выполнения одного и того же действия. Спасибо за помощь.
Ответ №1:
Как вы правильно догадались, есть способ сделать это с окнами, которые просматривают исходные данные без их копирования. Самый простой способ, вероятно, заключается в использовании относительно новой sliding_window_view
функции:
from numpy.lib.stride_tricks import sliding_window_view
window = sliding_window_view(image, (838, 838), axis=(0, 1))
Вам не нужен явный axis
для 2D-изображений, но это не повредит и избавит вас от некоторых проблем в случае 3D. Если вы хотите скорректировать шаги, вы можете просто подмножествовать результат. Например, для шага (3, 4)
:
window = window[::3, ::4]
Поскольку оси окон должны (должны) располагаться последними в порядке C, на 3D-изображениях каналы будут перемещены на среднюю ось. Чтобы получить доступ к правильной форме, вы можете использовать что-то вроде np.moveaxis
или transpose
:
np.moveaxis(window[80, 70], 0, -1)
или
window[80, 70].transpose(1, 2, 0).shape