Monday, July 18, 2011

Digital 3D camera on super special

Pic header 01I have a long interest in 3D photography, and even a couple of old film cameras in the bottom drawer here.

There is a digital 3D camera from Fuji that is basically two 10Mpx cameras in one body with a nifty lenticular LCD panel. These used to sell for over $500, which was a bit much for me, but today I noticed that Harvey Norman Balgowlah has them in the red spot discount bin for $128.

It's a Fuji FinePix Real 3D W3.

Stereo pair

The target market is consumers with 3D TVs (I don't) so viewing is the challenge. The images do look good on the on-camera display, but that's no good for sharing. I purchased some +3.5 reading glasses for $4 and by using a card I can view the images nicely on the computer screen.

I have an old viewer for side by side prints which can work and you used to be able to get one off prints with lenticular screens on the front. The other interesting option is viewing on an iPod/iPhone with the Hasbro my3D viewer.

Wobble2

The camera has a few ergonomic issues, it's really hard to avoid covering the right lens with your finger for example, but seems like a bargain at this price. It also shoots movies and as they say in the store - can be used for 2D as well.

The store I went to had about ten in the bin so be quick if you want one.

Splitting MPO files

The Fuji 3D camera, and others apparently, store 3D images in a .MPO file. This file is simply two Jpegs one after the other. I wrote a little python command line tool to split these files into left and right images.


"""Split an MPO file which is just two JPEGs back to back
"""
import sys
import os

for filename in sys.argv[1:]:
if filename.lower().endswith('.mpo'):
print "reading %s" % filename
basename = os.path.basename(filename)
file = open(filename, 'rb')
data = file.read() # read both images
print "read %d bytes" % len(data)
offset = data.find('\xFF\xD8\xFF\xE1', 4)
print "second image starts at %d" % offset
firstData = data[:offset - 4]
print "first image is %d bytes" % len(firstData)
left = open('%s-left.jpg' % basename, 'wb')
left.write(firstData)
left.close()

rightData = data[offset:]
print "second image is %d bytes" % len(rightData)
right = open('%s-right.jpg' % basename, 'wb')
right.write(rightData)
right.close()


It runs like this:


$ python mposplitter.py sample.MPO
reading sample.MPO
read 3655848 bytes
second image starts at 1799552
first image is 1799548 bytes
second image is 1856296 bytes
done.

2023 Update


Just came back to this and python3 requires some changes:

#!/opt/homebrew/bin/python3
"""Split an MPO file which is just two JPEGs back to back
"""
import sys
import os

for filename in sys.argv[1:]:
    if filename.lower().endswith('.mpo'):
        print("reading %s" % filename)
        basename = os.path.basename(filename)
        file = open(filename, 'rb')
        data = file.read() # read both images
        print("read %d bytes" % len(data))
        offset = data.find(b'\xFF\xD8\xFF\xE1', 4)
        print("second image starts at %d" % offset)
        firstData = data[:offset - 4]
        print("first image is %d bytes" % len(firstData))
        left = open('%s-left.jpg' % basename, 'wb')
        left.write(firstData)
        left.close()

        rightData = data[offset:]
        print("second image is %d bytes" % len(rightData))
        right = open('%s-right.jpg' % basename, 'wb')
        right.write(rightData)
        right.close()
        

To view the images in my old 3D print viewer I need two side by side pictures.

R0014018

The Python Image Library can do what's needed pretty simply:


import sys
import Image

nativeWidth = 3584
nativeHeight = 2016

fullWidth = 400
fullHeight = fullWidth * nativeHeight/ nativeWidth
halfWidth = fullWidth / 2
halfHeight = fullHeight / 2
print halfWidth
print halfHeight

if len(sys.argv) != 3:
print "Usage: %s left.jpg right.jpg" % sys.argv[0]
sys.exit(1)

leftFileName = sys.argv[1]
rightFileName = sys.argv[2]

left = Image.open(leftFileName)
right = Image.open(rightFileName)

combined = Image.new("RGB", (fullWidth, halfHeight))
left = left.resize((halfWidth, halfHeight), Image.ANTIALIAS)
right = right.resize((halfWidth, halfHeight), Image.ANTIALIAS)
combined.paste(left, (0,0))
combined.paste(right, (halfWidth, 0))
combined.save("output.jpg", "JPEG")


Here's the output file:

Output

1 comment:

  1. Wow, I don't think I've seen a stereoscopic viewer like that since I was at uni. That's pretty funky (in a retro nerdy way)

    ReplyDelete