1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
/**
@page smpl_simple_view_java SimpleViewer.java - sample program (Java)
<b>Source file:</b> 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.
@section svj_glb_dcl_blk Global Declaration Block
The following declaration block declares the OpenNI objects required for building the OpenNI production graph.
@code
private OutArg<ScriptNode> scriptNode;
private Context context;
private DepthGenerator depthGen;
private byte[] imgbytes;
@endcode
Each of these declarations is described separately in the following paragraphs.
The @ref xn::ScriptNode "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 @ref xn::Context "Context" object is a workspace in which the application builds an OpenNI production graph.
The @ref xn::DepthGenerator "DepthGenerator" node generates a depth map. Each map pixel value represents a distance from the sensor.
The @ref xn::DepthMetaData "DepthMetaData" object provides a @ref glos_frame_object "frame object" for the @ref xn::DepthGenerator "DepthGenerator" node. A @ref dict_gen_node "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 <i>production graph</i> is a network of <i>production nodes</i> and is the principal OpenNI object model. The identifies blobs as hands or human users.
@code
#define SAMPLE_XML_PATH "../../../../Data/SamplesConfig.xml"
@endcode
@section svj_func_main Main Program
@subsection svj_scrpt_sets_up_pg 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 <b>Context.createFromXmlFile()</b> 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.
@code
scriptNode = new OutArg<ScriptNode>();
context = Context.createFromXmlFile(SAMPLE_XML_FILE, scriptNode);
@endcode
@subsection svj_get_dg_node_from_pg Get a DepthGenerator Node from the Production Graph
The following statement creates and returns a reference to a @ref xn::DepthGenerator "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.
@code
depthGen = DepthGenerator.create(context);
@endcode
The following statement gets the latest generated depth @ref glos_frame_object "frame object", saving it as a metadata object.
@code
DepthMetaData depthMD = depthGen.getMetaData();
@endcode
The following sets up the array for the histogram array that is a key part of this sample program. (This is not OpenNI specific.)
@code
histogram = new float[10000];
@endcode
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.
@code
width = depthMD.getFullXRes();
height = depthMD.getFullYRes();
@endcode
The remaining statements in this method are not OpenNI specific.
@code
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);
@endcode
@section svj_calcHist 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 <code>depthMD.DepthMapPtrgetData().createShortBuffer()</code>method returns a buffer that can be easily processed. The depth value is then used as an index into the histogram[] array.
@code
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++;
}
}
...
...
}
@endcode
@section svj_update_depth_fn updateDepth() method - Updating the Depth Map
The following statement sets up the frame object. It is described in the <a href="#getMetaData">HandTracker() method above</a>. For more explanation on this, see @ref conc_meta_data, @ref glos_frame_object, and @ref frame_data.
@code
DepthMetaData depthMD = depthGen.getMetaData();
@endcode
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 <b>WaitXUpdateAll</b> methods, see <i>@ref conc_updating_data__summary_of_wait_fns</i>.
the @ref xn::Context::WaitAnyUpdateAll() "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.
@code
context.waitAnyUpdateAll();
@endcode
The following code block creates a convenient buffer for the depth map and then calls the calcHist() method to calculate the histogram.
@code
calcHist(depthMD);
ShortBuffer depth = depthMD.getData().createShortBuffer();
depth.rewind();
@endcode
The following code block builds an image buffer according to the frequency of each depth value in the histogram.
@code
while(depth.remaining() > 0)
{
int pos = depth.position();
short pixel = depth.get();
imgbytes[pos] = (byte)histogram[pixel];
}
@endcode
@section svj_Dimension Dimension() method
There are no OpenNI-specific declarations in this routine.
@section svj_paint paint() method
There are no OpenNI-specific declarations in this routine.
*/
|