Обрезка несимметричной области изображения с помощью Python / PIL - PullRequest
5 голосов
/ 14 сентября 2010

Есть ли способ вырезать не прямоугольные области изображения с помощью Python PIL?

например, на этом снимке я хочу исключить все черные области, а также башни, крыши иполюсы.
http://img153.imageshack.us/img153/5330/skybig.jpg

Я думаю, что модуль ImagePath может это сделать, но, кроме того, как я могу прочитать данные, например, из файла SVG, и преобразовать их в путь?

Любая помощь будет оценена.


(Мой подвопрос, вероятно, является более простой задачей: как вырезать хотя бы круг изображения?)

1 Ответ

7 голосов
/ 26 марта 2011

Если я правильно понял, вы хотите сделать некоторые области прозрачными внутри изображения. И эти области имеют произвольную форму. Самый простой способ (который я могу придумать) - создать маску и поместить ее в альфа-канал изображения. Ниже приведен код, который показывает, как это сделать.

Если ваш вопрос был «Как создать маску многоугольника», я перенаправлю вас на:

SciPy Create 2D Polygon Mask

и посмотрите принятый ответ.

ш

Юха

import numpy
import Image

# read image as RGB and add alpha (transparency)
im = Image.open("lena.png").convert("RGBA")

# convert to numpy (for convenience)
imArray = numpy.asarray(im)

# create mask (zeros + circle with ones)
center = (200,200)
radius = 100
mask = numpy.zeros((imArray.shape[0],imArray.shape[1]))
for i in range(imArray.shape[0]):
    for j in range(imArray.shape[1]):
        if (i-center[0])**2 + (j-center[0])**2 < radius**2:
            mask[i,j] = 1

# assemble new image (uint8: 0-255)
newImArray = numpy.empty(imArray.shape,dtype='uint8')

# colors (three first columns, RGB)
newImArray[:,:,:3] = imArray[:,:,:3]

# transparency (4th column)
newImArray[:,:,3] = mask*255          

# back to Image from numpy
newIm = Image.fromarray(newImArray, "RGBA")
newIm.save("lena3.png")

Редактировать

На самом деле, я не смог устоять ... решение с использованием многоугольной маски было таким элегантным (замените приведенный выше круг следующим):

# create mask
polygon = [(100,100), (200,100), (150,150)]
maskIm = Image.new('L', (imArray.shape[0], imArray.shape[1]), 0)
ImageDraw.Draw(maskIm).polygon(polygon, outline=1, fill=1)
mask = numpy.array(maskIm)

Edit2

Теперь, когда я думаю об этом. Если у вас есть черно-белый svg, вы можете загрузить svg напрямую как маску (при условии, что белый - это ваша маска). У меня нет образцов изображений SVG, поэтому я не могу проверить это. Я не уверен, что PIL может открывать изображения SVG.

...