Как преобразовать необработанную информацию о глубине Kinect в метры в Matlab?

Я провел некоторое исследование здесь, чтобы понять эту тему, но я не достиг хороших результатов. Я работаю с Kinect для Windows и Kinect SDK 1.7. Я работаю с Matlab для обработки необработанных данных карты глубины.

Во-первых, я использую этот метод ( /questions/725154/neobrabotannyie-dannyie-o-glubine-teksta-kinect-v10-c/725161#725161) для хранения необработанных данных глубины Kinect в текстовом файле. Я получил список с (480x640 = 307200) элементами и данными, подобными этим:

23048
23048
23048
-8
-8
-8
-8
-8
-8
-8
-8
6704
6720
6720
6720
6720
6720
6720
6720
6720
6736
6736
6736
6736
6752
0
0

Затем в Matlab я конвертирую эти значения в двоичные. Итак, я получаю 16-битные числа. Последние три числа, которые соответствуют индексу игрока, это "000", поэтому я их удаляю. Теперь из 13-разрядных чисел я убираю более значимое, которое всегда равно "0".

Итак, я сделал это:

[0,1,1,0,0,0,1,0,0,0,1,1,1,0,0,0] - 16 bits number
[0,1,1,0,0,0,1,0,0,0,1,1,1] - 13 bits number
[1,1,0,0,0,1,0,0,0,1,1,1] - 12 bits number

Затем я следую этой процедуре ( /questions/33276018/kinect-neobrabotannaya-glubina-na-rasstoyanie-v-metrah/33276034#33276034), чтобы преобразовать необработанную информацию о глубине в метры, но я получаю значения в диапазоне от -4,7422 до 0,3055. Что они имеют в виду?

clc
clear all
close all

%Get raw depth data from .txt
fileID = fopen('C:\Example.txt', 'r');
datos = fscanf(fileID, '%i'); % Data in decimal
fclose(fileID);

% If raw depth data is less than 0, set it to 0
for i = 1 : 640*480
 if(datos(i) < 0)
   datos(i) = 0;
 end
end

% Auxiliar arrays
datosBin = zeros(640*480, 16);
realDepth = zeros(640*480, 12);

% Decimal raw depth data to binary
n = 16;
m = 0;
for i = 1 : 640*480
 a = datos(i);
 datosBin(i,:) = fix(rem(a*pow2(-(n-1):m),2));
end

% Remove player index and msb (more significant bit)
for i = 1 : 640*480
 realDepth(i,:) = datosBin(i,2:13);
end

% Auxiliar array to store raw depth data decimal number
realDepthDec = zeros(640*480,1);

% Raw depth data 12 bits to decimal
for i = 1 : 640*480
 realDepthDec(i) = bin2dec(num2str(realDepth(i,:)));
end

% Auxiliar array
rawDepthMapMeters = zeros(480, 640);

% Create array 640*480 to store bit depth info in meters
for j = 1 : 480
 for i = 1 : 640
   if(realDepthDec(i+j) <= 2046)
    rawDepthMapMeters(j, i) = 0.1236 * tan(realDepthDec(i+j)/2842.5 + 1.1863);
   end
 end
end

Где моя ошибка? Что я делаю неправильно? Заранее спасибо.

PS. Извините за мой плохой английский.

1 ответ

Решение

Во второй статье, которую вы прочитали, вы увидите, что используемый вами метод устарел. Прочитайте это.

x = (i - w / 2) * (z + minDistance) * scaleFactor
y = (j - h / 2) * (z + minDistance) * scaleFactor
z = z
Where
minDistance = -10
scaleFactor = .0021.
These values were found by hand.

Также вы можете конвертировать эти точки в миллиметры в вашем первом приложении, как описано во втором вопросе

using (var depthFrame = e.OpenDepthImageFrame())
{
    var depthArray = new short[depthFrame.PixelDataLength];
    depthFrame.CopyPixelDataTo(depthArray);

    for (int i = 0; i < depthArray.Length; i++) {
        int depthInMillimeters = 
            depthArray[i] >> DepthImageFrame.PlayerIndexBitmaskWidth;
        // TADAx2!
}
Другие вопросы по тегам