Как выполнить ортографическую проекцию на изображение z-Buffer в Matlab?
Я сталкиваюсь с той же проблемой, о которой говорилось в этом посте, однако я сталкиваюсь не с OpenGL, а просто с MATLAB. Глубина как расстояние до плоскости камеры в GLSL
У меня есть изображение глубины от Z-буфера от 3ds Max. Я не смог получить орфографическое представление 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-буфер не является орфографическим, все еще присутствует, так что я ошибся? Мой расчет ошибочен? Или я здесь ошибся?
Глубина изображения от 3ds Max
После вычисления (белый цвет по-прежнему равен "0", но ось цвета изменилась) Было бы здорово добиться этого с помощью 3ds max, что решило бы эту проблему, однако я не смог найти эту настройку для z-буфера, Таким образом, я хочу решить эту проблему с помощью Matlab.