Search code examples
algorithmmatlabkinectangledepth-buffer

Calculate the angles of a pixel to a camera plane in a depth-image


I have a z-image from a ToF Camera (Kinect V2). I do not have the pixel size, but I know that the depth image has a resolution of 512x424. I also know that I have a fov of 70.6x60 degrees.

I asked how to get the Pixel size before here. In Matlab this code looks like the following.

The brighter the pixel, the closer the object.

close all
clear all

%Load image
depth = imread('depth_0_30_0_0.5.png');
frame_width = 512;
frame_height = 424;

horizontal_scaling = tan((70.6 / 2) * (pi/180));
vertical_scaling = tan((60 / 2) * (pi/180));

%pixel size
with_size = horizontal_scaling * 2 .* (double(depth)/frame_width);
height_size = vertical_scaling * 2 .* (double(depth)/frame_height);

The image itself is a cube rotated by 30 degree, and can be seen here: enter image description here.

What I want to do now is calculate the horizontal angle of a pixel to the camera-plane and the vertical angle to the camera plane.

I tried to do this with triangulation, I calculate the z-distance from one pixel to another, first in the horizontal direction and then in the vertical direction. I do this with a convolution:

%get the horizontal errors
dx = abs(conv2(depth,[1 -1],'same'));
%get the vertical errors
dy = abs(conv2(depth,[1 -1]','same'));

After this I calculate it via the atan, like this:

horizontal_angle = rad2deg(atan(with_size ./ dx));
vertical_angle = rad2deg(atan(height_size ./ dy));
horizontal_angle(horizontal_angle == NaN) = 0;
vertical_angle(vertical_angle == NaN) = 0;

Which gives back promising results, like these:

Vertical angle enter image description here

However, using a little bit more complex image like this, which is turned by 60° and 30°.

enter image description here

Gives back the same angle images for horizontal and vertical angles, which look like this:

vertical3060 horizontal3060

After subtracting both images from each other, I get the following image - which shows that there is a difference between those two.

enter image description here

So, I have the following questions: How can I proof this concept? Is the math correct, and the test case is just poorly chosen? Is the angle difference from horizontal to vertical angles in the two images too close? Are there any errors in the calculation ?


Solution

  • While my previous code may looks good, it had a flaw. I tested it with smaller images (5x5,3x3 and so on) and saw, that there is an offset created by the difference picture (dx,dy) made by the convolution. It is simple not possible to map the difference picture (which holds the difference between two pixels) to the pixels itself, since the difference picture is smaller than the original one.

    For a fast fix, I do a downsampling. So I changed the filter mask to:

    %get the horizontal differences
    dx = abs(conv2(depth,[1 0 -1],'valid'));
    %get the vertical differences
    dy = abs(conv2(depth,[1 0 -1]','valid'));
    

    And changed the angle function to:

    %get the angles by the tangent
    horizontal_angle = rad2deg(atan(with_size(2:end-1,2:end-1)...
        ./ dx(2:end-1,:)))
    vertical_angle = rad2deg(atan(height_size(2:end-1,2:end-1)...
        ./ dy(:,2:end-1)))
    

    Also I used a padding function to get the angle map to the same size as the original images.

    horizontal_angle = padarray(horizontal_angle,[1 1],0);
    vertical_angle = padarray(vertical_angle[1 1],0);