Резка одного изображения на несколько изображений с помощью библиотеки изображений Python
Мне нужно разрезать это изображение на три части с помощью PIL и выбрать среднюю часть. Как мне это сделать?
http://thedilbertstore.com/images/periodic_content/dilbert/dt110507dhct.jpg
6 ответов
Если коробки не известны раньше, я бы запустил простой фильтр поиска ребер над изображением (как X, так и y), чтобы найти границы коробки.
простой подход был бы:
- запустить горизонтальный фильтр края над изображением. Теперь у вас есть изображение, где каждый пиксель описывает изменения интенсивности слева и справа от этого пикселя. Т. е. он будет" находить " вертикальные линии.
- для каждого столбца в горизонтальном-edge-image получить среднее абсолютное величина его строк. В результирующем массиве размером 1 X WIDTH вы найдете вертикальные линии в позициях наибольшего значения. Поскольку линии имеют ширину более одного пикселя, возможно, здесь нужно быть немного умным.
- сделать то же самое для другой оси, чтобы найти горизонтальные линии.
вы можете выполнить предварительную обработку, сначала извлекая только черные пиксели (или почти черные), Если вы считаете, что границы ящиков всегда будут черный. Но я сомневаюсь, что это будет необходимо, так как вышеуказанный метод должен быть очень стабильным.
скажем, у вас есть очень длинная картина такая.
и теперь вы хотите разрезать его на меньшие вертикальные биты, потому что он такой длинный.
вот скрипт Python, который это сделает. Это было полезно для меня при подготовке очень длинных изображений для LaTeX docs.
from __future__ import division
import Image
import math
import os
def long_slice(image_path, out_name, outdir, slice_size):
"""slice an image into parts slice_size tall"""
img = Image.open(image_path)
width, height = img.size
upper = 0
left = 0
slices = int(math.ceil(height/slice_size))
count = 1
for slice in range(slices):
#if we are at the end, set the lower bound to be the bottom of the image
if count == slices:
lower = height
else:
lower = int(count * slice_size)
#set the bounding box! The important bit
bbox = (left, upper, width, lower)
working_slice = img.crop(bbox)
upper += slice_size
#save the slice
working_slice.save(os.path.join(outdir, "slice_" + out_name + "_" + str(count)+".png"))
count +=1
if __name__ == '__main__':
#slice_size is the max height of the slices in pixels
long_slice("longcat.jpg","longcat", os.getcwd(), 300)
это вывод
Я хотел проголосовать Gourneau это решение, но отсутствие достаточной репутации. Тем не менее, я решил опубликовать код, который я разработал в результате его ответа, на случай, если это может быть полезно кому-то еще. Я также добавил возможность перебирать файловую структуру и выбирать ширину изображения.
import Image
import os
# Set the root directory
rootdir = 'path/to/your/file/directory'
def long_slice(image_path, out_name, outdir, sliceHeight, sliceWidth):
img = Image.open(image_path) # Load image
imageWidth, imageHeight = img.size # Get image dimensions
left = 0 # Set the left-most edge
upper = 0 # Set the top-most edge
while (left < imageWidth):
while (upper < imageHeight):
# If the bottom and right of the cropping box overruns the image.
if (upper + sliceHeight > imageHeight and \
left + sliceWidth > imageWidth):
bbox = (left, upper, imageWidth, imageHeight)
# If the right of the cropping box overruns the image
elif (left + sliceWidth > imageWidth):
bbox = (left, upper, imageWidth, upper + sliceHeight)
# If the bottom of the cropping box overruns the image
elif (upper + sliceHeight > imageHeight):
bbox = (left, upper, left + sliceWidth, imageHeight)
# If the entire cropping box is inside the image,
# proceed normally.
else:
bbox = (left, upper, left + sliceWidth, upper + sliceHeight)
working_slice = img.crop(bbox) # Crop image based on created bounds
# Save your new cropped image.
working_slice.save(os.path.join(outdir, 'slice_' + out_name + \
'_' + str(upper) + '_' + str(left) + '.jpg'))
upper += sliceHeight # Increment the horizontal position
left += sliceWidth # Increment the vertical position
upper = 0
if __name__ == '__main__':
# Iterate through all the files in a set of directories.
for subdir, dirs, files in os.walk(rootdir):
for file in files:
long_slice(subdir + '/' + file, 'longcat', subdir, 128, 128)
для этого конкретного изображения вы могли бы сделать
import Image
i = Image.open('dt110507dhct.jpg')
frame2 = i.crop(((275, 0, 528, 250)))
frame2.save('dt110507dhct_frame2.jpg')
посмотрите на метод crop () PIL
http://effbot.org/imagingbook/image.htm
(требуется знание ограничивающей рамки изображения...предполагая, что изображение имеет одинаковые размеры каждый день, Вы должны иметь возможность определить ограничивающую рамку один раз и использовать ее все время).
- загрузить изображения
- получить размер
- использовать метод
- Сохранить Изображение посередине