裸眼3D小实验

July 2, 2018 最近偶然看到篇3D显示的论文,感觉挺有意思,决定动手实现一下。 常见的一种裸眼3D是通过全息投影来实现,如: 即通过图像在半透明薄片上的投影来产生立体感,由于投影面是标准的平面,如果又正好是45°角,投影图像不需要做任何形变,实现起来比较简单,而这篇论文作者采用的是圆锥体: 圆锥相比凌锥可以适应更大的观察角度,另外还可以放到旋转平台上,那么问题来了,对于圆锥,投影图像需要做怎样的形变呢? 如果按数学公式算会相对复杂,特别是,DIY的圆锥不能保证是标准形状,很可能会扁一点,也不能保证正好垂直摆放,因而实际上我们需要假设它就是不标准的形状、不标准的姿态,那如何得到图像在这样曲面上投影的形变关系呢?结构光是一种不错的方法。 Kinect和iPhoneX的人脸ID都用到了结构光技术,其主要用于3D重建,获取物体表面形状信息。原理不难理解,向物体表面投射已知结构的光,然后拍摄图像,根据图像上结构的形变来计算物体表面(深度)信息,在这个实验里,我用的比较简单的格雷码结构光。 结构光 基本思路:将像素点的坐标(x,y)编码进光的结构,投影后拍摄图像,解码每个像素点(X, Y)的值,从而得到(x, y) -> (X, Y)的映射关系图。格雷码结构光是时间编码方式,即投射多张图案,每张代表一个二进制bit,假如1024分辨率,就需要log2(1024)=10张图案来编码,而且对于x、y两个轴,需要在横纵方向投影两次。格雷码相比普通二进制码有一定优势,具体可参看 https://en.wikipedia.org/wiki/Gray_code 比如上图,Line1的码字就是00000,Line2是01110,解码后将格雷码转为二进制码,就得到该像素点的坐标值 格雷码结构光生成的伪代码(x轴): encodePattern(idx) { for (y = 0 : height – 1) { for (x = 0 : width -1) { int gray = binaryToGray(x); // 坐标x转为格雷码 bool one = (gray >> idx) & 1; // 第idx位是否是1 image[x,Continue reading “裸眼3D小实验”