OpenNI 1.5.4: SimpleViewer.java - sample program (Java)

OpenNI

SimpleViewer.java - sample program (Java)

Source file: Click the following link to view the source code file:

  • SimpleViewer.java

This section describes the SimpleViewer sample program in the Java language. This sample program uses a DepthGenerator node to build an accumulative histogram from depth values.

The documentation describes the sample program's code from the top of the program file(s) to bottom.

Every OpenNI feature is described the first time it appears in this sample program. Further appearances of the same feature are not decribed again.

Global Declaration Block

The following declaration block declares the OpenNI objects required for building the OpenNI production graph.

            private OutArg<ScriptNode> scriptNode;
            private Context context;
            private DepthGenerator depthGen;
            private byte[] imgbytes;

Each of these declarations is described separately in the following paragraphs.

The ScriptNode object loads an XML script from a file or string, and then runs the XML script to build a production graph . . The ScriptNode object keeps references to all nodes created from the script, so they will not be destroyed. (This is since OpenNI will delete a node that has no remaining references to it.)

A Context object is a workspace in which the application builds an OpenNI production graph.

The DepthGenerator node generates a depth map. Each map pixel value represents a distance from the sensor.

The DepthMetaData object provides a frame object for the DepthGenerator node. A generator node's frame object contains the generated data frame and all its associated properties. This frame object, comprising the data frame and its properties, is accessible through the node's metadata object.

The following definition is for the path to an OpenNI XML script file for inputting and building a stored production graph. The production graph is a network of production nodes and is the principal OpenNI object model. The identifies blobs as hands or human users.

            #define SAMPLE_XML_PATH "../../../../Data/SamplesConfig.xml"

Main Program

Uses a Script to Set up a Context and Production Graph

The following code block uses a script to set up a context and a production graph. The Context.createFromXmlFile() method is a shorthand combination of two other initialization methods, which initializes the context object and then creates a production graph from an XML file. The XML script file describes all the nodes you want to create. For each node description in the XML file, this method creates a node in the production graph.

                scriptNode = new OutArg<ScriptNode>();
                context = Context.createFromXmlFile(SAMPLE_XML_FILE, scriptNode);               

Get a DepthGenerator Node from the Production Graph

The following statement creates and returns a reference to a DepthGenerator node. The create() method can return a reference to an existing DepthGenerator node if one already exists in the production graph created from the XML. If no DepthGenerator node already exists, this method creates a new DepthGenerator node and returns a reference to the new node.

                depthGen = DepthGenerator.create(context);

The following statement gets the latest generated depth frame object, saving it as a metadata object.

                DepthMetaData depthMD = depthGen.getMetaData();

The following sets up the array for the histogram array that is a key part of this sample program. (This is not OpenNI specific.)

                histogram = new float[10000];

The following code accesses some attributes of the frame data's associated configuration properties: getFullXRes() and getFullYRes() are the full frame resolution, i.e., the entire field-of-view, ignoring cropping of the FOV in the scene.

                width = depthMD.getFullXRes();
                height = depthMD.getFullYRes();

The remaining statements in this method are not OpenNI specific.

                imgbytes = new byte[width*height];
                
                DataBufferByte dataBuffer = new DataBufferByte(imgbytes, width*height);
                Raster raster = Raster.createPackedRaster(dataBuffer, width, height, 8, null);
                bimg = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
                bimg.setData(raster);

CalcHist() - Using the Depth Values to Build an Accumulative Histogram

The following code block uses the depth values to build an accumulative histogram of frequency of occurrence of each depth value. The depthMD.DepthMapPtrgetData().createShortBuffer()method returns a buffer that can be easily processed. The depth value is then used as an index into the histogram[] array.

            private void calcHist(DepthMetaData depthMD)
            {
                ...         
                ShortBuffer depth = depthMD.getData().createShortBuffer();
                depth.rewind();
                
                int points = 0;
                while(depth.remaining() > 0)
                {
                    short depthVal = depth.get();
                    if (depthVal != 0)
                    {
                        histogram[depthVal]++;
                        points++;
                    }
                }   
                ...
                ...
            } 

updateDepth() method - Updating the Depth Map

The following statement sets up the frame object. It is described in the HandTracker() method above. For more explanation on this, see Frame Objects and Metadata Objects, Frame Objects, and Frame Data (Data Frame).

            DepthMetaData depthMD = depthGen.getMetaData();

The following method call waits for any node to have generated new data. This method then 'updates' each and every node in the entire production graph. For an overview to reading data and the WaitXUpdateAll methods, see 'Wait and Update' Methods.

the waitAnyUpdateAll() method in the following statement updates all generator nodes in the context that have new data available, first waiting for any of the nodes to have new data available. The application can then get the data (for example, using a metadata GetData() method). This method has a timeout.

            context.waitAnyUpdateAll();

The following code block creates a convenient buffer for the depth map and then calls the calcHist() method to calculate the histogram.

            calcHist(depthMD);
            ShortBuffer depth = depthMD.getData().createShortBuffer();              
            depth.rewind();     

The following code block builds an image buffer according to the frequency of each depth value in the histogram.

        while(depth.remaining() > 0)
            {
                int pos = depth.position();
                short pixel = depth.get();
                imgbytes[pos] = (byte)histogram[pixel];
            }       

Dimension() method

There are no OpenNI-specific declarations in this routine.

paint() method

There are no OpenNI-specific declarations in this routine.

Generated on Wed May 16 2012 10:16:06 for OpenNI 1.5.4 by   doxygen 1.7.5.1