JosephFTaylor
JosephFTaylor

Reputation: 99

Convert an existing Kinect RGB infrared image to an array of distances

I have a screenshot of the infrared output of a Kinect using OpenKinect on a Mac.

Infrared test image

I would like to calculate the distance of the green wall and the orange posts. I'm only bothered about a single dimension array, say y = 240 (along the horizontal center of the image).

I have tried using MarvinJ to convert the image to greyscale and save the colour value to an array, but I quickly found that this is not the way to go about this, due to the integer colour values of the greyscale image are very similar and do not represent the depth well enough.

<!doctype html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Greyscale Test</title>
</head>

<body>

    <script src="https://www.marvinj.org/releases/marvinj-0.9.js"></script>
<script>
    image = new MarvinImage();
    image.load("ir_test.png", imageLoaded);


function imageLoaded() {
    var imageOut = new MarvinImage(image.getWidth(), image.getHeight());
    var image2 = new MarvinImage(image.getWidth(), image.getHeight());
    Marvin.invertColors(image, image2);
    Marvin.invertColors(image2, imageOut);
    var y = 240;
    var colour_array = [];
    for (var x = 0; x < imageOut.getWidth(); x++) { // For loop to loop through the x-axis

        var colour = imageOut.getIntComponent0(x, y);
        colour_array.push(colour);

    }

    document.getElementById('colour_array_div').innerHTML = colour_array;
}
</script>
    <div id="colour_array_div"></div>

</body>
</html>

What I'm trying to work out is how to convert the colour to a distance, preferably in millimeters.

Upvotes: 0

Views: 179

Answers (1)

JosephFTaylor
JosephFTaylor

Reputation: 99

I ended up converting each pixel to their RGB hex values and then converted the hex value to a decimal number.

This gave me a range of values between 0 and 16777215.

I copied the output to a CSV file then processed the value of each pixel in Excel. I converted the decimal colour value to a distance in meters.

I found the range of the Kinect's depth sensor to be 0.8m-3.5m [https://openkinect.org/wiki/Imaging_Information]

I converted the decimal value to a meter value using an answer from this question: Excel Function name to map one ratio to another

value/(inhi-inlo)*(outhi-outlo)+outlo

Here is a graph of the output:

Output graph

The code I used to generate the array of decimal colour values is:

<!doctype html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Colour Test</title>
</head>

<body>

    <script src="https://www.marvinj.org/releases/marvinj-0.9.js"></script>
<script>
    image = new MarvinImage();
    image.load("ir_test.png", imageLoaded);


function imageLoaded() {
    var imageOut = new MarvinImage(image.getWidth(), image.getHeight());
    var image2 = new MarvinImage(image.getWidth(), image.getHeight());
    Marvin.invertColors(image, image2);
    Marvin.invertColors(image2, imageOut);
    var y = 240;
    var colour_array = [];
    for (var x = 0; x < imageOut.getWidth(); x++) { // For loop to loop through the x-axis

        var red = imageOut.getIntComponent0(x, y);
        var green = imageOut.getIntComponent1(x, y);
        var blue = imageOut.getIntComponent2(x, y);
        var hex_colour = rgbToHex(red,green,blue);
        var colour = parseInt(hex_colour, 16); //https://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hexadecimal-in-javascript
        colour_array.push(colour);

    }

    document.getElementById('colour_array_div').innerHTML = colour_array;
}

//https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
function componentToHex(c) {
    var hex = c.toString(16);
    return hex.length == 1 ? "0" + hex : hex;
}

function rgbToHex(r, g, b) {
    return componentToHex(r) + componentToHex(g) + componentToHex(b);
}



</script>
    <div id="colour_array_div"></div>

</body>
</html>

Upvotes: 0

Related Questions