2016-12-15 4 views
1

У меня есть массив numpy A, состоящий из изображений одного и того же размера [N_images, width, height, 3].Ошибка трансляции при векторизации misc.imresize()

Я хочу применить misc.imresize() к каждому и каждому из них самый быстрый способ.

Так я определил:

def myfunc(x): 
    return misc.imresize(x,(wanted_width,wanted_height)) 

, а затем я сделал:

vfunc=np.vectorize(my_func) 

, но когда я пытаюсь:

test=vfunc(A) 

я получаю не-подходит-массив-shape- для конвертирования в изображения. я думал, что это было, потому что я не уточнял ось, на которой должны быть векторизованной оп, который вызвал его не транслирует ИЙ массив способа хотел, чтобы я попробовал другую вещь, чтобы сузить ошибку:

test=np.apply_along_axis(my_func,0,A) 

и получил ту же ошибку. Даже если я заставляю np.squeeze() в my_func. Это меня очень удивило.

EDIT: Я также пробовал с map ту же ошибку. Это может быть связано с тем, что вы можете использовать векторизовать со скалярной функцией, как указано @jotasi.

Это должно быть довольно глупо, но я не знаю, что происходит. Может ли кто-нибудь просветить меня? Есть ли способ исправить это?

+0

'np.vectorize' не имеет параметра 'axis', поскольку он предназначен только для функций, которые не знают о нем и принимают скаляры. См. [Этот ответ] (http://stackoverflow.com/a/3379505/6614295) для получения дополнительной информации. – jotasi

+0

Спасибо, я этого не знал! Так что я должен отказаться от попытки его векторизации или есть другие способы? – jean

+0

Я не думаю, что есть простой способ избежать какого-то цикла, так как 'misc.imresize' также не поддерживает векторное приложение вдоль оси. Если ваше изображение достаточно велико, я бы предположил, что цикл не должен представлять собой узкое место в любом случае. – jotasi

ответ

3

Альтернативный вариант vectorized подход с использованием scipy's zoom. Однако это не обязательно быстрее для небольшого количества изображений (например, для N = 100 цикл может быть быстрее).

>>> from skimage import color, util, data 
>>> img = util.img_as_float(color.gray2rgb(data.camera())) # Sample RGB image 

Я просто повторить полутоновое изображение над RGB каналов, так что он все равно будет выглядеть серую шкалу, но это RGB на практике.

Создайте 100 изображений RGB, копируя изображение RGB и его горизонтальный флип (чтобы обеспечить правильную интерполяцию).

>>> data = np.empty((100,) + img.shape, img.dtype) 
>>> data[0::2] = img 
>>> data[1::2] = img[:,::-1] 
>>> plt.imshow(data[50]) 

enter image description here

Найти масштабировании факторы:

>>> from scipy.ndimage import zoom 
>>> new_size = (200, 200) 
>>> fy, fx = np.asarray(new_size, np.float32)/data.shape[1:3] 

Изменение размера изображения, коэффициент 1 означает отсутствие интерполяции по этой оси:

>>> resized = zoom(data, (1, fy, fx, 1), order=0) # order=0 for quicker 
>>> plt.imshow(resized[50]) # resized.shape = (100, 200, 200, 3) 

enter image description here

Опять же, имейте в виду, что хотя это векторизованная версия, она использует интерполяцию NN, чтобы быть быстро, стандартная петля + произвольная интерполяция может быть быстрее. Возьмите это как доказательство концепции и посмотрите, работает ли он для вас.

+0

Спасибо за ваш ответ! Я поддержал это. Я собираюсь сравнить его с моей реализацией и посмотреть, что получится. – jean

+0

Но мне не очень-то нравится такая интерполяция, пока изображения выглядят нормально, и у меня есть около 500000 изображений, поэтому это может быть действительно быстрее. – jean

+0

Я не могу использовать интерполяцию NN, артефакты слишком важны для моего приложения, и когда я нажимаю порядок сплайна на 1, скорость не увеличивается. – jean

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