2017-01-25 7 views
1

новеллы:памяти эффективное извлечение перекрывающихся заплаты из матрицы

Это прослеживание вопрос: Fast Way to slice image into overlapping patches and merge patches to image

Как я должен адаптировать код, предоставленный в ответе на работу не только на изображениях размер x, y, где пиксель описывается поплавком, но описывается матрицей размера 3,3?

Далее, как адаптировать код так, чтобы он возвращал генератор, позволяющий мне перебирать все патчи без необходимости сохранять их все в памяти?

длинная история:

Учитывая образ формы (х, у), где каждый пиксель описывается матрицей (3,3). Это можно описать как матрицу формы (x, y, 3,3). Дальше заданный патчмент цели, такой как (11,11), я хочу извлечь все перекрывающиеся патчи из изображения (x, y).

Обратите внимание, что я не хочу получать все исправления из матрицы x, y, 3,3, но из изображения x, y, где каждый пиксель является матрицей.

Я хочу использовать эти исправления для алгоритма классификации патчей, эффективно повторяя все патчи, извлекая функции и изучая классификатор. Тем не менее, учитывая огромное изображение и большой размер патчей, нет возможности выполнить эту операцию без ущерба для ограничения памяти.

Возможные решения:

  • sklearn.feature_extraction.image.extract_patches_2d обеспечивает целевую функцию, но не применимо, так как он терпит неудачу из-за ограничений памяти. (но отлично работает для данного изображения с небольшим количеством патчей)
  • Fast Way to slice image into overlapping patches and merge patches to image. Отличный ответ, кажется, ведет к лучшему, используя шаги и фактически не создавая копию входного изображения. Но я не смог адаптировать ответ в соответствии с моими потребностями.

Поэтому возникает вопрос: как я могу адаптировать этот код для соответствия новым входным данным?

def patchify(img, patch_shape): 
    img = np.ascontiguousarray(img) # won't make a copy if not needed 
    X, Y = img.shape 
    x, y = patch_shape 
    shape = ((X-x+1), (Y-y+1), x, y) # number of patches, patch_shape 
    # The right strides can be thought by: 
    # 1) Thinking of `img` as a chunk of memory in C order 
    # 2) Asking how many items through that chunk of memory are needed when indices 
    # i,j,k,l are incremented by one 
    strides = img.itemsize*np.array([Y, 1, Y, 1]) 
    return np.lib.stride_tricks.as_strided(img, shape=shape, strides=strides) 

ответ

3

Хотя ответ вы связываете не неправильно, я бы утверждать, что лучше не делать предположений над махов массива и просто повторно использовать любые шаги у него уже есть. Он обладает дополнительным преимуществом: никогда не требуется копия исходного массива, даже если он не является непрерывным. Для вашей расширенной формы изображения вы могли бы сделать:

def patchify(img, patch_shape): 
    X, Y, a, b = img.shape 
    x, y = patch_shape 
    shape = (X - x + 1, Y - y + 1, x, y, a, b) 
    X_str, Y_str, a_str, b_str = img.strides 
    strides = (X_str, Y_str, X_str, Y_str, a_str, b_str) 
    return np.lib.stride_tricks.as_strided(img, shape=shape, strides=strides) 

Легко увлечься и хотите написать более общую функцию, которая не требует специализаций для определенной размерности массива. Если вы чувствуете необходимость туда, вы можете найти вдохновение в this gist.

+0

Если я правильно понял, эта функция возвращает представление и не выделяет память. Однако, когда начинается работа над этим массивом, может быть создана копия. Как я могу это предотвратить? Возможно, вместо этого вместо генератора? –

+1

Если вы перебираете патчи, например. 'X, Y = img.shape [: 2]; для x в диапазоне (X): для y в диапазоне (Y): patch = img [x, y]; ... ', то все, что вы делаете с' patch', не сможет скопировать только этот патч. Это замедлит работу, но это не займет огромного объема памяти, как это произошло бы, если бы весь патч-просмотр был скопирован сразу.Помимо этого, можно ли избежать копирования, сильно зависит от того, что вы хотите делать с патчами. – Jaime

+0

@NikolasRieble Итак, наилучший возможный случай использования использует какое-то сокращение для этого массива '6D', но, вообще говоря, будет зависеть от самого использования. – Divakar

 Смежные вопросы

  • Нет связанных вопросов^_^