2017-01-22 5 views
2

У меня есть несколько изображений, которые я хочу обрезать, а затем переформатируйте. Для того, чтобы помочь мне с этим я написал две вспомогательные функции:Векторизация изменения и обрезки изображений с использованием PIL

def crop_images(images_data): 
    cropped_images = [] 
    for image_data in images_data: 
     image = Image.fromarray(image_data) 
     cropped_image = np.asarray(image.crop((25,40,275,120))) 
     cropped_images.append(cropped_image) 
    return(np.array(cropped_images)) 

def resize_images(images_data): 
    resized_images = [] 
    width, height = images_data.shape[2], images_data.shape[1] 
    resized_width, resized_height = int(width/2), int(height/2) 
    for image_data in images_data: 
     image = Image.fromarray(image_data) 
     image = image.resize((resized_width, resized_height), Image.ANTIALIAS) 
     resized_images.append(np.asarray(image)) 
    return(np.array(resized_images)) 

Тогда я бы просто цепь две функции вместе, чтобы обработать мои изображения как: resize_images(crop_images(images_data))

Но мне было интересно, есть ли способ векторизовать эту операцию, поскольку я знаю, что numpy в идеале должен быть векторизованными операциями, поскольку он быстрее.

+0

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

+0

Кажется, что в этом случае более оптимальным является обрезка с использованием numpy вместо обрезки с использованием библиотеки изображений. – physicalattraction

ответ

1

Это более высокий уровень итерации - над массивами изображений, где обычные разговоры о «векторизации» не применимы.

Изображения массивов, как правило, имеют размер (400,400,3) или больше. Вы не хотите повторять одну из этих 400 сторон, если вам это не нужно. Таким образом, операции «векторизации» на массивах изображений имеют большой смысл.

Но если обработка 100 этих изображений, петля над изображениями не так уж плоха. Единственный способ «векторизации» - собрать их в более крупный массив (N, 400, 400, 3) и найти выражения, которые работают на 4d, или фрагменты этого большого. Заманчиво идти по этому маршруту, если N 1000 или более, но для большого массива, подобного проблемам управления памятью, начинают пережевываться в любой рост скорости.

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

alist = [] 
for arr in source: 
    <process arr> 
    alist.append(arr) 
bigarr = np.array(alist) 

против

bigarr = np.zeros((N,..) 
for i in range(N): 
    arr = source[i,...] 
    <process arr> 
    bigarr[i,...] = arr 

Код осветление может также пострадать при попытке пакетных операций 'векторизации'.

+0

Спасибо, что имеет большой смысл – YellowPillow

1

Для обрезки, если вы поместите все изображения в один 3-D массив, то вы можете обрезать их все в одном кадре (третье измерение изображения оси):

cropped = images[top:bottom, left:right, :] 

Не уверен, что если бы быстрее - стоимость памяти при одновременном использовании всех изображений в памяти может замедлить ее.

+0

Кроме того, это были бы виды, так что должно быть намного лучше. Однако он не знаком с обрезкой PIL. – Divakar

+0

Правильно! забыл, что это взгляды :) – lolopop