我面临与这篇文章中提到的相同的问题,但是,我不是用 OpenGL 来面对它,而只是用 MATLAB。深度作为到 GLSL 中相机平面的距离
我有一个从 3ds max 的 Z 缓冲区渲染的深度图像。我无法获得 z 缓冲区的正交表示。为了更好地理解,我将使用与上一篇文章相同的草图:
* |--* / | / | C-----* C-----* \ | \ | * |--*
3 个星号是像素,C 是相机。星号线是“深度”。在第一种情况下,我得到了从像素到相机的距离。第二,我希望得到每个像素到平面的距离。
我的相机设置如下:
WIDTH = 512;
HEIGHT = 424;
FOV = 89.971;
aspect_ratio = WIDTH/HEIGHT;
%clipping planes
near = 500;
far = 5000;
我计算截锥体设置如下:
%calculate frustums settings
top = tan((FOV/2)*5000)
bottom = -top
right = top*aspect_ratio
left = -top*aspect_ratio
并像这样设置投影矩阵:
%Generate matrix
O_p = [2/(right-left) 0 0 -((right+left)/(right-left)); ...
0 2/(top-bottom) 0 -((top+bottom)/(top-bottom));...
0 0 -2/(far-near) -(far+near)/(far-near);...
0 0 0 1];
在此之后,我读入深度图像,该图像被保存为 48 位 RGB 图像,其中每个通道都是相同的,因此只需要使用一个通道。
%Read in image
img = imread('KinectImage.png');
%Throw away, except one channel (all hold the same information)
c1 = img(:,:,1);
像素值必须反转,因为值越接近相机,它们就越亮。如果一个像素为 0(没有可渲染的对象),则将其设置为 2^16,因此,在位补码后,该值仍为 0。
%Inverse bits that are not zero, so that the z-image has the correct values
c1(c1 == 0) = 2^16
c1_cmp = bitcmp(c1);
为了将矩阵应用于每个 z-Buffer 值,我将向量布置为一维并在每个元素上构建一个像 [0 0 z 1] 这样的向量。
c1_cmp1d = squeeze(reshape(c1_cmp,[512*424,1]));
converted = double([zeros(WIDTH*HEIGHT,1) zeros(WIDTH*HEIGHT,1) c1_cmp1d zeros(WIDTH*HEIGHT,1)]) * double(O_p);
之后,我挑选出结果向量的第 4 个元素并将其重塑为图像
img_con = converted(:,4);
img_con = reshape(img_con,[424,512]);
但是,Z-Buffer 不是正交的效果仍然存在,所以我错了吗?我的计算有问题吗?还是我在这里犯了错误?
计算后(白色仍然是“0”,但颜色轴已经改变)用 3ds max 实现这一点会很好,这将解决这个问题,但是我无法找到 z 缓冲区的这个设置. 因此,我想使用 Matlab 解决这个问题。