如何使用MATLAB和图像工具创建3D立体图像?

6

我该如何使用MATLAB从2D图像创建3D立体图像?


3
什么问题?你尝试过什么? - carlosdc
1
我认为如果您拥有3D数据,创建它将会更容易,因为那样您只需要使用不同视角创建2个投影。 - Itamar Katz
@carlosdc @Itamar Katz:如果我想使用3D眼镜查看2D图像,它会以3D图像格式显示。还有其他方法可以以三维方式查看吗? - Abhishek B.
2个回答

12
我可能误解了你的问题(人们已经指出它不清楚),或者你误解了3D视觉的工作方式。你不能“使用3D眼镜看2D图像”。实现3D视觉是通过向左眼和右眼分别提供两个不同的图像,左图像和右图像来实现的。从根本上讲,MATLAB与此无关。
因此,在没有易于理解或连贯的问题的情况下,我能做的最好的就是假设你想要类似于this这样的东西:你有一个单独的2D图像,但你仍然希望将其“转换为3D图像格式”。在这种情况下,你需要以某种方式将该单个图像分成两个新图像:
1.左眼的左图像 2.右眼的右图像
这并不容易。通常,你首先需要通过推断2D图像中每个像素的深度来开始。由于你正在“猜测”深度信息,所以两个新图像不会完美地表示3D场景。
接下来,你可以使用该深度信息将图像分成多个层。它看起来基本上像是儿童书籍中的弹出式剪纸。

alt text

你能提出更多层次,并且深度估计越准确,你的3D表示就会更加真实。

最后,你将分层表示投影回两个不同位置的2D图像--一个用于左眼,一个用于右眼。这给了你需要的两个不同的图像。

编辑

你链接的第二个video描述了常被称为anaglyph image的简化创建过程。它需要3D红青眼镜--这些不是现在大多数3D电影院使用的偏振眼镜。我之所以说简化,是因为它没有区分前景和背景。

为了达到最佳效果,你应该将前景与背景分开,并仅对前景应用此方法。这是因为通常背景具有无限深度,在从单眼视觉转换为立体视觉时不会改变。对于钢琴的情况,几乎所有东西都是前景,所以这种方法有效。

视频描述的算法是:

  • 首先准备两张图片,im1im2。它们是相同的。
  • im1的绿色和蓝色通道设为零。这将创建红色图像。
  • im2的红色通道设为零。这将创建青色图像。
  • 通过某个指定的量(取决于物体到相机的距离)偏移这两张图片,使得im1在左侧,im2在右侧。你需要正确地排列这个顺序,因为3D红青眼镜左边是红色,右边是青色。
  • 对两个平移后的图像执行逐元素加法。请注意,没有通道会饱和。

这是我编写的Python/OpenCV代码:

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)

这是一个与视频中使用的类似图片:

alt text

这是输出结果:

alt text

很遗憾我没有3D红青眼镜来验证这是否有效。但在理论上看起来应该是有效的。如果我犯了错误,也许有人可以纠正我。


非常感谢 @misha,但是我想要像这样的视频链接 http://www.youtube.com/watch?v=3r4M_KHt6aw,http://www.youtube.com/watch?v=g_JRHtHpuSY,http://www.youtube.com/watch?v=zdXxS2KHXlo。- 谢谢 Abhi。 - Abhishek B.
1
基本上,第一个链接描述了我所做的事情。计算深度图,制作第二张图片。我不确定实际的位移滤镜实现方式。第二个链接并不是非常相关--它不是立体图像,只是实现了伪3D效果。如果这是你想要的,那么实现起来相当简单,只需按照那个孩子在视频中说的那样做即可。我可能会稍后观看第三个视频--它有点长,而且现在已经很晚了。将相关链接放在你的原始问题中,以便清楚地表明你想要什么。 - mpenkov
谢谢@misha,是的,你理解了我的意思。我想在2D图像上添加伪3D效果。我只能按照视频链接中的简单3D效果来实现。如果你有相关的代码,请回复我。- Abhi - Abhishek B.
1
你想要的在第二个视频里,链接是youtube.com/watch?v=g_JRHtHpuSY吗?我已经更新了我的答案,并提供了一些OpenCV源代码。将其移植到Matlab应该不难,这部分就留给你了。 - mpenkov
@misha,我是Matlab的新手,你能告诉我如何在Matlab中执行你的代码吗? - Naveen.S
你好!脚本很棒。你能提供一种在OPENCV 3中实现它的方法吗? - sUP

0

谢谢您的回答。如果我们只有一张图片,那么我们能制作立体图像吗? - Abhishek B.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接