How to create 3D streoscopic images using MATLAB with image tool?

Abhishek B. picture Abhishek B. · Jan 18, 2011 · Viewed 12.1k times · Source

How do I create a 3D stereoscopic image from a 2D image using MATLAB?

Answer

mpenkov picture mpenkov · Jan 18, 2011

Either I'm misunderstanding your question (people have already pointed out that it's not clear), or you are misunderstanding the way 3D vision works. You don't "see 2D image using 3D glass". 3D vision is achieved by serving two different images, left image and right image, to the left eye and right eye, respectively. At a fundamental level MATLAB doesn't have anything to do with it.

So, in absence of an easily understandable or coherent question, the best I can do is assume you want something like this: you have is a single 2D image, but you still want to "seen into 3d image format". In that case, you need to somehow split that single image into two new images:

  1. Left image for the left eye
  2. Right image for the right eye

This isn't trivial. Generally, you start by inferring the depth of each pixel in the 2D image. Since you're "guessing" the depth information, the two new images won't be a perfect representation of a 3D scene.

Next, you separate your image into layers using that depth information. It will essentially look like a pop-up cutout from a children's book:

alt text

The more layers you can come up with, and the more accurate your depth estimation is, the more realistic your 3D representation will be.

Finally, you project that layered representation back onto 2D from two different positions -- one for the left eye, and one for the right eye. This gives you the two different images you needed.

EDIT

The second video you linked to describes the simplified creation of what is commonly known as an anaglyph image. It requires 3D red-cyan glasses -- these are not the polarized glasses they use in most 3D theaters now. The reason I say simplified is that it doesn't discriminate between the foreground and background.

For best effect, you'd separate the foreground from the background, and apply the approach only to the foreground. This is because typically background has infinite depth and doesn't change when going from mono to stereo vision. In the case of the piano, everything is more or less foreground, so the approach works.

The algorithm the video describes is:

  • Start with two images, im1 and im2. They are identical
  • Set the green and blue channels of im1 to zero. This will create the red image
  • Set the red channel of im2 to zero. This will create the cyan image.
  • Offset the two images by some specified amount (depending on the depth to subject) such that im1 is on the left and im2 is on the right. You need to get this order correctly because 3D red-cyan glasses have red on the left, and cyan on the right.
  • Perform element-wise addition of the two shifted images. Note that no channels will saturate.

Here's some Python/OpenCV code I wrote:

import cv
SHIFT=8

if __name__ == '__main__':
    import sys
    _, fname = sys.argv
    im  = cv.LoadImage(fname)

    size = cv.GetSize(im)
    width, height = size
    left  = cv.CreateImage(size, im.depth, im.nChannels)
    right = cv.CreateImage(size, im.depth, im.nChannels)
    anaglyph = cv.CreateImage((width - SHIFT, height), im.depth, im.nChannels)

    #
    # This would be easier if we had COI support for cv.Set, but it doesn't
    # work that way.
    # OpenCV uses BGR order (even if input image is greyscale):
    # http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.html
    # red goes on the left, cyan on the right:
    # http://en.wikipedia.org/wiki/Anaglyph_image
    #
    b = cv.CreateImage(size, im.depth, 1)
    g = cv.CreateImage(size, im.depth, 1)
    r = cv.CreateImage(size, im.depth, 1)
    cv.Split(im, b, g, r, None)

    zeros = cv.CreateImage(size, r.depth, 1)
    cv.Merge(zeros, zeros, r, None, left)
    cv.Merge(b, g, zeros, None, right)

    #
    # cvRect is ( x, y, width, height ) and it MUST be a tuple, not a list
    # 
    cv.SetImageROI(left,  ( SHIFT, 0, width - SHIFT, height ))
    cv.SetImageROI(right, ( 0,     0, width - SHIFT, height ))
    cv.Add(left, right, anaglyph, None)

    cv.SaveImage('anaglyph.jpeg', anaglyph)

Here's a similar image to what's used in the video:

alt text

Here's the output:

alt text

Unfortunately I don't have 3D red-cyan glasses to verify that this works. But it seems like it should, at least in theory. Perhaps somebody can correct me if I've made a mistake.