The
cheap Fuji 3D camera has been lots of fun but viewing the pictures is a challenge. I ordered some Red/blue specs on ebay and have been figuring out how to automate conversion of the MPO files from the camera through to good quality anaglyph images. (If you have red/blue glasses this will look good, believe me).
The code is pillaged from a couple of places including
here where it is mangled by the blogging software and doesn't work with the current bumpy. I've fixed it up and here it is for your entertainment:
"""Make a red-blue 3d Anaglyph image from an MPO file
Based on code from:
http://www.velocityreviews.com/forums/t357242-anaglyph-3d-stereo-imaging-with-pil-and-numpy.html
"""
import Image, ImageOps
import numpy
import sys
import os
_magic = [0.299, 0.587, 0.114]
_zero = [0, 0, 0]
_ident = [[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]
# anaglyph methods from here: (fantastic demos)
# http://mitglied.lycos.de/stereo3d/an...comparison.htm
true_anaglyph = ([_magic, _zero, _zero], [_zero, _zero, _magic])
gray_anaglyph = ([_magic, _zero, _zero], [_zero, _magic, _magic])
color_anaglyph = ([_ident[0], _zero, _zero], [_zero, _ident[1], _ident[2]])
half_color_anaglyph = ([_magic, _zero, _zero], [_zero, _ident[1], _ident[2]])
optimized_anaglyph = ([[0, 0.7, 0.3], _zero, _zero], [_zero, _ident[1], _ident[2]])
methods = [true_anaglyph, gray_anaglyph, color_anaglyph, half_color_anaglyph, optimized_anaglyph]
def anaglyph(image1, image2, method=true_anaglyph):
m1, m2 = [numpy.array(m).transpose() for m in method]
im1, im2 = image_to_array(image1), image_to_array(image2)
composite = numpy.dot(im1, m1) + numpy.dot(im2, m2)
result = array_to_image(image1.mode, image1.size, composite)
return result
def image_to_array(im):
s = im.tostring()
dim = len(im.getbands())
return numpy.fromstring(s, 'uint8').reshape(len(s)/dim, dim)
def array_to_image(mode, size, a):
return Image.fromstring(mode, size, a.reshape(len(a)*len(mode), 1).astype('uint8').tostring())
for filename in sys.argv[1:]:
if filename.lower().endswith('.mpo'):
print "reading %s" % filename
basename = os.path.splitext(os.path.basename(filename))[0]
file = open(filename, 'rb')
data = file.read() # read both images
offset = data.find('\xFF\xD8\xFF\xE1', 4)
firstData = data[:offset - 4]
leftFileName = '%s-left.jpg' % basename
left = open(leftFileName, 'wb')
left.write(firstData)
left.close()
rightData = data[offset:]
rightFileName = '%s-right.jpg' % basename
right = open(rightFileName, 'wb')
right.write(rightData)
right.close()
nativeWidth = 3584
nativeHeight = 2016
desiredWidth = 1000
fullHeight = desiredWidth * nativeHeight/ nativeWidth
left = Image.open(leftFileName)
left = ImageOps.autocontrast(left)
right = Image.open(rightFileName)
right = ImageOps.autocontrast(right)
os.remove(leftFileName)
os.remove(rightFileName)
left = left.resize((desiredWidth, fullHeight), Image.ANTIALIAS)
right = right.resize((desiredWidth, fullHeight), Image.ANTIALIAS)
combined = anaglyph(left, right, half_color_anaglyph)
#combined.show()
outFileName = "%s_Anaglyph.jpg" % basename
combined.save(outFileName, "JPEG")
print("Wrote %s" % outFileName)
You run it like this:
$ mpo_anaglyph.py *.MPO
reading DSCF0005.MPO
Wrote DSCF0005_Anaglyph.jpg
reading DSCF0006.MPO
Wrote DSCF0006_Anaglyph.jpg
reading DSCF0007.MPO
Wrote DSCF0007_Anaglyph.jpg
The pics look great, I recently got a cheap pair of anaglyph glasses from deal extreme. Quite comfortable and pretty good build quality, much better than the cheapy cardboard and cellophane ones you once got at the movies.
ReplyDeleteI was surprised how well they work out, even in colour, I'm sure the old movies we used to see were pretty much black & white.
ReplyDeleteThanks for the tip on the proper glasses, I'll order a pair. I've just got cheap cardboard ones that will soon fall apart.
Also you can check "Stereo Master" software if you are using Mac.
ReplyDelete