cropping a random part of an image

Robin Koch robin.koch at t-online.de
Tue Aug 9 16:30:11 EDT 2016


Am 09.08.2016 um 14:40 schrieb drewes.mil at gmail.com:

> I'm new to python and I have 30.000 pictures.
> I need to crop, let's say 100, parts of 256x256, randomly out of every picture.

Interessting task. May I ask for the purose of this?

> I cant find an answer in the net, would be nice if someone could help me out!

Although I think you should follow Peters advise I have put something 
together, out of curiousity, that should do the trick.

There are several ways to improve it.
First I'm using os.listdir() instead of os.walk().
In my example scenario that's ok. If your files are spread over 
different subfolders, os.walk() is the better way to do it.

You could add a counter (see: enumerate()) to have a better overview 
over the progress.

Also you might have other preferences for the location of the tiles. 
(e.g. one folder per image).

# Cuts random tiles from pictures
#
# This version works with approx. 270 tiles per second on my machine
# (on 13.5MPx images). So 3 million tiles should take about 3 hours.

import random, os, time
from PIL import Image

INPATH = r".../images"
OUTPATH = r".../tiles"

dx = dy = 256
tilesPerImage = 100

files = os.listdir(INPATH)
numOfImages = len(files)

t = time.time()
for file in files:
   with Image.open(os.path.join(INPATH, file)) as im:
     for i in range(1, tilesPerImage+1):
       newname = file.replace('.', '_{:03d}.'.format(i))
       w, h = im.size
       x = random.randint(0, w-dx-1)
       y = random.randint(0, h-dy-1)
       print("Cropping {}: {},{} -> {},{}".format(file, x,y, x+dx, y+dy))
       im.crop((x,y, x+dx, y+dy))\
         .save(os.path.join(OUTPATH, newname))

t = time.time()-t
print("Done {} images in {:.2f}s".format(numOfImages, t))
print("({:.1f} images per second)".format(numOfImages/t))
print("({:.1f} tiles per second)".format(tilesPerImage*numOfImages/t))



-- 
Robin Koch



More information about the Python-list mailing list