Cutting one image into multiple images using the Python Image Library

限于喜欢 提交于 2019-11-29 03:44:21

If the boxes are not known on before hand I would run a simple edge finding filter over the image (both x and y directions) to find the boundaries of the box.

A simple approach would be:

  1. Run horizontal edge filter over image. You now have an image where each pixel describes the changes in intensity left and right of that pixel. I.e. it will "find" vertical lines.
  2. For each column in the horizontal-edge-image get the average absolute magnitude of its rows. In the resulting 1 x WIDTH sized array you will find the vertical lines at the positions of highest value. Since the lines are more than one pixel wide yo might have to be a bit clever here.
  3. Do the same for the other axis to find the horizontal lines.

You could do some pre processing by first extracting only pixels that are black (or near black) if you believe that the borders of the boxes will always be black. But I doubt it'd be necessary since the above method should be very stable.

Say you have a really long picture like this.

And now you want to slice it up into smaller vertical bits, because it is so long.

Here is a Python script that will do that. This was useful to me for in preparing very long images for 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) 

This is is the output



BBQ Singular

I wanted to up-vote Gourneau's solution, but lack the sufficient reputation. However, I figured I would post the code that I developed as a result of his answer just in case it might be helpful to somebody else. I also added the ability to iterate through a file structure, and choose an image width.

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) 

For this particular image you would do

import Image i = Image.open('dt110507dhct.jpg') frame2 = i.crop(((275, 0, 528, 250))) frame2.save('dt110507dhct_frame2.jpg') 
Andreas Jung

Look at the crop() method of PIL

http://effbot.org/imagingbook/image.htm

(requires knowledge of the bounding box of the image...assuming that the image has the same dimensions every day you should be able to determine the bounding box once and use it for all the time).

Andrew
  1. Load the Image
  2. Get the Size
  3. Use the Crop method
  4. Save the middle image
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!