Python Imaging Library: Difference between revisions
From charlesreid1
| (13 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
=Installing= | |||
==Pip== | |||
The python imaging library can be installed with pip: | |||
<source lang="bash"> | |||
$ pip install PIL | |||
</source> | |||
==Importing== | |||
Sometimes you can import the PIL like this: | |||
<source lang="python"> | |||
import PIL as ThePIL | |||
</source> | |||
with other installations though, you have to import it like this: | |||
<source lang="python"> | |||
import Image | |||
</source> | |||
here is a link with some notes on how to use the PIL when you import it as <code>import Image</code>: | |||
http://effbot.org/imagingbook/introduction.htm | |||
=Averaging= | =Averaging= | ||
| Line 10: | Line 37: | ||
Average two images, like this: | Average two images, like this: | ||
The average of | The average of these two images: | ||
[[Image:Hipstamatic_0380.JPG| | [[Image:Hipstamatic_0380.JPG|300px]] and [[Image:Hipstamatic_0390.JPG|300px]] | ||
is: | |||
[[Image: | [[Image:HipstamaticAverage_0380_0390.png|450px]] | ||
===Image Averaging for Time Lapses: 2 Images=== | |||
===Image Averaging for Time Lapses=== | |||
Why I want to take the average of two images: | Why I want to take the average of two images: | ||
| Line 33: | Line 56: | ||
The average of | The average of | ||
[[Image:ClocktowerA.jpg]] | [[Image:ClocktowerA.jpg|350px]] and [[Image:ClocktowerB.jpg|350px]] | ||
is | |||
[[Image:ClocktowerAvgAB.jpg|400px]] | |||
the code to do this is as follows here: | |||
<source lang="python"> | |||
import os, numpy, Image | |||
imgA = "ClocktowerA.JPG" | |||
imgB = "ClocktowerB.JPG" | |||
imlist = [imgA,imgB] | |||
# Assuming all images are the same size, get dimensions of first image | |||
w,h=Image.open(imlist[0]).size | |||
N=len(imlist) | |||
# Create a numpy array of floats to store the average (assume RGB images) | |||
arr=numpy.zeros((h,w,3),numpy.float) | |||
# Build up average pixel intensities, casting each image as an array of floats | |||
for im in imlist: | |||
imarr=numpy.array(Image.open(im),dtype=numpy.float) | |||
arr=arr+imarr/N | |||
# Round values in array and cast as 8-bit integer | |||
arr=numpy.array(numpy.round(arr),dtype=numpy.uint8) | |||
# Generate, save and preview final image | |||
out=Image.fromarray(arr,mode="RGB") | |||
out.save("ClocktowerAverageAB.jpg") | |||
out.show() | |||
</source> | |||
===Image Averaging for Time Lapses: Many Images=== | |||
Having multiple images, and adding an average of each pair, is slightly more involved than the two-image case. | |||
For my application, I'm interested in stitching a large number of images together, with average images in between each. | |||
This looks for a set of images with the extension <code>.JPG</code>. It then blends them together, and renames the files so they are in-sequence images, with the first image placed first, the blended image placed second, and the third image placed third. | |||
<source lang="python"> | |||
import os, numpy, Image | |||
from subprocess import call | |||
allfiles=os.listdir(os.getcwd()) | |||
imlist=[filename for filename in allfiles if filename[-4:] in [".JPG"]] | |||
Nlist = len(imlist) | |||
ii = 0 | |||
jj = 0 | |||
for ii in range(1,Nlist): | |||
################################### | |||
# Step 0: Prep | |||
impair = [imlist[ii-1],imlist[ii]] | |||
N=len(impair) | |||
# Assuming all images are the same size, get dimensions of first image | |||
w,h=Image.open(impair[1]).size | |||
# Create a numpy array of floats to store the average (assume RGB images) | |||
arr=numpy.zeros((h,w,3),numpy.float) | |||
################################## | |||
# Step 1: Save first picture | |||
outname = "processed_%d.jpg"%(jj) | |||
call(["cp",impair[0],outname]) | |||
jj = jj + 1 | |||
print outname,"=",impair[0] | |||
################################## | |||
# Step 2: Save average picture | |||
# Build up average pixel intensities, casting each image as an array of floats | |||
for im in impair: | |||
imarr = numpy.array(Image.open(im),dtype=numpy.float) | |||
arr = arr + imarr/N | |||
# Round values in array and cast as 8-bit integer | |||
arr=numpy.array(numpy.round(arr),dtype=numpy.uint8) | |||
# Generate, save and preview final image | |||
outname = "processed_%d.jpg"%(jj) | |||
out=Image.fromarray(arr,mode="RGB").rotate(90) | |||
out.save(outname) | |||
jj = jj + 1 | |||
print outname,"=",impair[0],"+",impair[1],"..." | |||
################################## | |||
# Step 3: Save last picture | |||
call(["cp",imlist[N-1],"processed_%d.jpg"%(jj)]) | |||
jj = jj + 1 | |||
</source> | |||
Here is the video with the smoothing applied: | |||
{{#ev:vimeo|84492003}} | |||
Compare this to the video without: | |||
{{#ev:vimeo|84490917}} | |||
Dunno if there's a difference, or if this effect needs to be exaggerated more by making the blended image last for two frames instead of one. | |||
<!-- | |||
{{#ev:vimeo|}} | |||
{{#ev:vimeo|10792824}} | |||
--> | |||
Latest revision as of 00:47, 19 January 2014
Installing
Pip
The python imaging library can be installed with pip:
$ pip install PIL
Importing
Sometimes you can import the PIL like this:
import PIL as ThePIL
with other installations though, you have to import it like this:
import Image
here is a link with some notes on how to use the PIL when you import it as import Image:
http://effbot.org/imagingbook/introduction.htm
Averaging
Color Averaging
See http://charlesmartinreid.com/wordpress/2012/08/python-image-averaging-and-color-averaging/
Image Averaging
Average two images, like this:
The average of these two images:
is:
Image Averaging for Time Lapses: 2 Images
Why I want to take the average of two images:
I'm taking a timelapse photo, and want to stretch out my frames per second without the video seeming too choppy. So I wanted to add an image between each photo pair that averages the two images, doubling the number of frames and smoothing image transitions in the final timelapse.
Here, image averaging is used for more subtle image differences:
The average of
is
the code to do this is as follows here:
import os, numpy, Image
imgA = "ClocktowerA.JPG"
imgB = "ClocktowerB.JPG"
imlist = [imgA,imgB]
# Assuming all images are the same size, get dimensions of first image
w,h=Image.open(imlist[0]).size
N=len(imlist)
# Create a numpy array of floats to store the average (assume RGB images)
arr=numpy.zeros((h,w,3),numpy.float)
# Build up average pixel intensities, casting each image as an array of floats
for im in imlist:
imarr=numpy.array(Image.open(im),dtype=numpy.float)
arr=arr+imarr/N
# Round values in array and cast as 8-bit integer
arr=numpy.array(numpy.round(arr),dtype=numpy.uint8)
# Generate, save and preview final image
out=Image.fromarray(arr,mode="RGB")
out.save("ClocktowerAverageAB.jpg")
out.show()
Image Averaging for Time Lapses: Many Images
Having multiple images, and adding an average of each pair, is slightly more involved than the two-image case.
For my application, I'm interested in stitching a large number of images together, with average images in between each.
This looks for a set of images with the extension .JPG. It then blends them together, and renames the files so they are in-sequence images, with the first image placed first, the blended image placed second, and the third image placed third.
import os, numpy, Image
from subprocess import call
allfiles=os.listdir(os.getcwd())
imlist=[filename for filename in allfiles if filename[-4:] in [".JPG"]]
Nlist = len(imlist)
ii = 0
jj = 0
for ii in range(1,Nlist):
###################################
# Step 0: Prep
impair = [imlist[ii-1],imlist[ii]]
N=len(impair)
# Assuming all images are the same size, get dimensions of first image
w,h=Image.open(impair[1]).size
# Create a numpy array of floats to store the average (assume RGB images)
arr=numpy.zeros((h,w,3),numpy.float)
##################################
# Step 1: Save first picture
outname = "processed_%d.jpg"%(jj)
call(["cp",impair[0],outname])
jj = jj + 1
print outname,"=",impair[0]
##################################
# Step 2: Save average picture
# Build up average pixel intensities, casting each image as an array of floats
for im in impair:
imarr = numpy.array(Image.open(im),dtype=numpy.float)
arr = arr + imarr/N
# Round values in array and cast as 8-bit integer
arr=numpy.array(numpy.round(arr),dtype=numpy.uint8)
# Generate, save and preview final image
outname = "processed_%d.jpg"%(jj)
out=Image.fromarray(arr,mode="RGB").rotate(90)
out.save(outname)
jj = jj + 1
print outname,"=",impair[0],"+",impair[1],"..."
##################################
# Step 3: Save last picture
call(["cp",imlist[N-1],"processed_%d.jpg"%(jj)])
jj = jj + 1
Here is the video with the smoothing applied:
{{#ev:vimeo|84492003}}
Compare this to the video without:
{{#ev:vimeo|84490917}}
Dunno if there's a difference, or if this effect needs to be exaggerated more by making the blended image last for two frames instead of one.