Point Denoiser vs PointControl

188 views
Skip to first unread message

Asim

unread,
Jan 7, 2011, 5:12:51 AM1/7/11
to OpenNI, lior....@primesense.com
Hey everyone,

Does anyone know the difference between PointDenoiser and PointControl
objects?

I initially thought that "denoising" meant smoothing the hand point
coordinates to give a more stable effect (basically removing the
instability caused by the fine shaking of the hand).

I wrote a small C# app in NITE, to test if this was true. The app was
simple. It had a session manager that was listening to a point
denoiser. I used the PrimaryPointUpdate event to print the coordinate
(X,Y,Z) info.

Next i replaced the denoiser with a simple point control and ran the
test again. There was very little difference between the two. The
deviation of the coordinates in the denoiser and the ordinary point
control were similar. The denoiser didn't seem to offer any remarkable
stability.

So that made me question my understanding of the denoiser... could
anyone please shed more light on this.

As a side note, in the NITE samples, if you run PointViewer, and press
"s" then a 'smoothing' of sorts is imposed. I saw the code for this
app, and this didn't use a denoiser either. Instead it used a
HandsGenerator object and set its "smoothing" attribute.

So if anyone could clear my confusion about this, it would be nice.

Thanks,
Asim

Lior Cohen

unread,
Jan 7, 2011, 5:51:01 AM1/7/11
to openn...@googlegroups.com
Dear Asim,

The HandGenerator has a build in PointDenoiser that is set to "true" by default. One can set it to "false" and use the PointDenoiser on only part of the NITE tree.
The PointControl is the base class for all the hand point classes (also for the PointDenoiser).


BR
Lior Cohen

Sent using BlackBerry

Iker Saint

unread,
Jan 7, 2011, 10:43:59 AM1/7/11
to OpenNI
When you use smothing for hands, it have a little improvement but not
too remarkable, the point denoiser has a lot of functions for gain
more stability "SetDistanceThreshold, SetCloseRatio, SetFarRatio" they
work very well.
If you take a look of the class reference, you can see that the
PointDenoiser doesn't implement any method "OnPrimaryPointUpdate"; in
fact the point that you are tracking is not denoised:

virtual void XnVPointControl::OnPrimaryPointUpdate ( const
XnVHandPointContext * pContext ) [inline, virtual]

Handle an update of the Primary Point

Parameters:
[in] pContext The context of the primary point

Reimplemented in XnVCircleDetector, XnVMultiProcessFlowServer,
XnVPushDetector, XnVSelectableSlider1D, XnVSelectableSlider2D,
XnVSteadyDetector, XnVSwipeDetector, and XnVWaveDetector.

Definition at line 107 of file XnVPointControl.h.

Use a listener to the denoiser ( could be a PointControl ) instead of
catch the update events and you see a big change in the stability.

Best Regards.

Iker

Peter Krakow

unread,
Jan 10, 2011, 4:23:18 AM1/10/11
to OpenNI
Can you explain what the functions "SetDistanceThreshold,
SetCloseRatio, SetFarRatio" actually do? I've tried playing around
with them, but the effects looked kind of random.

BTW, are there any improvements in the current unstable NITE regarding
multiple hand tracking? Is it worth an upgrade?

Peter

Lior Cohen

unread,
Jan 24, 2011, 4:50:44 AM1/24/11
to openn...@googlegroups.com
Dear Peter,

In order to explain those functions I need to explain first how the PointDenoiser mechanism is working (in general terms - not the exact functionality); Imagine there is a radius around the first handpoint, as long as the other points are within the sphere created by the first hand point and the radius, we will use the first hand point as a representative handpoint. If the hand position exceeded the radius distance, we will pick a new representative handpoint (e.g., the first hand position outside of the sphere) and create a new sphere around it. By following this algorithm we will get smoothing of the handpoints.

The "SetDistanceThreshold" function changes distance limit for far and close ratios (the radius)
The "SetCloseRatio, SetFarRatio" functions sets the "denoising" factors in levels that are not explained above. All I can mention at this stage is that they receive a value between 0 and 1 (ratio).

As regards to the hand tracking between the NITE versions (the stable and un-stabled); There is no change. But there is an improvement as regards to the full body NITE / skeleton output - if one wishes to create a multiple hands tracking on top of that.

Best Regards,
Lior Cohen

Peter

--
You received this message because you are subscribed to the Google Groups "OpenNI" group.
To post to this group, send email to openn...@googlegroups.com.
To unsubscribe from this group, send email to openni-dev+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/openni-dev?hl=en.

Iker Saint

unread,
Jan 24, 2011, 10:48:21 AM1/24/11
to OpenNI
Sorry, I forgot answer the rest of the questions, thanks Lior.

Lior do you have a paper ( Or link ) to the algorithm for denoising or
something that describe it a little more specific?.

Thanks in Advice.

Iker.

Lior Cohen

unread,
Jan 25, 2011, 6:31:33 AM1/25/11
to openn...@googlegroups.com
Sorry Iker, I do not have such a link/paper.

Videomap

unread,
Jan 27, 2011, 8:06:33 AM1/27/11
to OpenNI
Can this code work for pointdenoise ?

XnPoint3D DenoiseHandLeft(int NewLX, int NewLY, int NewLZ)
{

XnPoint3D pt[1];

static double PrevLX = (double)NewLX, PrevLY = (double)NewLY, PrevLZ =
(double)NewLZ;
double dx = (double)NewLX - PrevLX;
double dy = (double)NewLY - PrevLY;
double dz = (double)NewLZ - PrevLZ;
double distanza;

distanza = sqrt(dx*dx + dy*dy + dz*dz);

printf("distanza sinistra:%lf\n", distanza);

if (distanza > 10){

pt[0].X = NewLX;
pt[0].Y = NewLY;
pt[0].Z = NewLZ;
PrevLX = NewLX;
PrevLY = NewLY;
PrevLZ = NewLZ;
} else {
pt[0].X = PrevLX;
pt[0].Y = PrevLY;
pt[0].Z = PrevLZ;
}

return pt[0];
> > > too remarkable, the pointdenoiserhas a lot of functions for gain
> > > more stability "SetDistanceThreshold, SetCloseRatio, SetFarRatio" they
> > > work very well.
> > > If you take a look of the class reference, you can see that the
> > > PointDenoiser doesn't implement any method "OnPrimaryPointUpdate"; in
> > > fact the point that you are tracking is not denoised:
>
> > > virtual void XnVPointControl::OnPrimaryPointUpdate  ( const
> > > XnVHandPointContext *  pContext  )  [inline, virtual]
>
> > > Handle an update of the Primary Point
>
> > > Parameters:
> > > [in]  pContext  The context of the primary point
>
> > > Reimplemented in XnVCircleDetector, XnVMultiProcessFlowServer,
> > > XnVPushDetector, XnVSelectableSlider1D, XnVSelectableSlider2D,
> > > XnVSteadyDetector, XnVSwipeDetector, and XnVWaveDetector.
>
> > > Definition at line 107 of file XnVPointControl.h.
>
> > > Use a listener to thedenoiser( could be a PointControl ) instead of
> > > catch the update events and you see a big change in the stability.
>
> > > Best Regards.
>
> > > Iker
>
> > > On 7 ene, 05:51, Lior Cohen <Lior.Co...@PrimeSense.com> wrote:
>
> > > > Dear Asim,
>
> > > > The HandGenerator has a build in PointDenoiser that is set to "true" by default. One can set it to "false" and use the PointDenoiser on only part of the NITE tree.
> > > > The PointControl is the base class for all the hand point classes (also for the PointDenoiser).
>
> > > > BR
> > > > Lior Cohen
>
> > > > Sent using BlackBerry
>
> > > > ----- Original Message -----
> > > > From: Asim [mailto:asim.mit...@gmail.com]
> > > > Sent: Friday, January 07, 2011 12:12 PM
> > > > To: OpenNI <openn...@googlegroups.com>
>
> > > > Cc: Lior Cohen
> > > > Subject: PointDenoiservs PointControl
>
> > > > Hey everyone,
>
> > > > Does anyone know the difference between PointDenoiser and PointControl
> > > > objects?
>
> > > > I initially thought that "denoising" meant smoothing the hand point
> > > > coordinates to give a more stable effect (basically removing the
> > > > instability caused by the fine shaking of the hand).
>
> > > > I wrote a small C# app in NITE, to test if this was true. The app was
> > > > simple. It had a session manager that was listening to a point
> > > >denoiser. I used the PrimaryPointUpdate event to print the coordinate
> > > > (X,Y,Z) info.
>
> > > > Next i replaced thedenoiserwith a simple point control and ran the
> > > > test again. There was very little difference between the two. The
> > > > deviation of the coordinates in thedenoiserand the ordinary point
> > > > control were similar. Thedenoiserdidn't seem to offer any remarkable
> > > > stability.
>
> > > > So that made me question my understanding of thedenoiser... could
> > > > anyone please shed more light on this.
>
> > > > As a side note, in the NITE samples, if you run PointViewer, and press
> > > > "s"  then a 'smoothing' of sorts is imposed. I saw the code for this
> > > > app, and this didn't use adenoisereither. Instead it used a

Iker Saint

unread,
Jan 27, 2011, 8:06:26 PM1/27/11
to OpenNI
Is a little basic for the purpouses, you have to be in mind that is
not maintain the point static, is more that be fluid in movements
( this code not works for there ), you have to count with how much is
far and how much you have to let it move. You can achieve a algorithm
well based with the statistics of erratics movements ( just dump it
with your point static ).

Iker.

Videomap

unread,
Jan 29, 2011, 1:04:21 PM1/29/11
to OpenNI
The base algorithm is Double Exponential Smoothing
the implementation of activate3d.com is:

#pragma once
#ifndef A3D_DOUBLE_EXPONENTIAL_FILTER_H
#define A3D_DOUBLE_EXPONENTIAL_FILTER_H

#include "A3DMath.h"

class A3DDoubleExponentialFilter : public A3DObject
{
private:

A3DDoubleExponentialFilter(){};

public:

static A3D_INLINE void Predict(
const A3DVector3& position,
const A3DVector3& oldSmoothingStat1,
const A3DVector3& oldSmoothingStat2,
const A3DFloat32 alpha,
const A3DInt32 framesAheadToPredict,
A3DVector3& predictedPosition,
A3DVector3& newSmoothingStat1,
A3DVector3& newSmoothingStat2)
{
// Implementation derived from:
// http://www.cs.brown.edu/~jjl/pubs/kfvsexp_final_laviola.pdf

newSmoothingStat1 = alpha * position + (1.0f - alpha) *
oldSmoothingStat1;
newSmoothingStat2 = alpha * newSmoothingStat1 + (1.0f -
alpha) * oldSmoothingStat2;

predictedPosition = (2.0f + ((alpha * framesAheadToPredict) /
(1.0f - alpha))) * newSmoothingStat1 - (1.0f + ((alpha *
framesAheadToPredict) / (1.0f - alpha))) * newSmoothingStat2;
}
};

#endif // A3D_DOUBLE_EXPONENTIAL_FILTER_H


position The current position of the input vector.
oldSmoothingStat1 The smoothing stat SP1 from the previous
invocation of the filter.
oldSmoothingStat2 The smoothing stat SP2 from the previous
invocation of the filter.
alpha Alpha controls the decay. A value of 1.0f will give no weight
to the previous position. Values near 0.0 will cause the prediction to
take a very long time to correct to changes in velocity. Valid range
of inputs is (0.0, 1.0].
framesAheadToPredict The number of frames ahead to predict. This
should be a non-zero, positive integer value.
[in,out] predictedPosition The predicted position.
[in,out] newSmoothingStat1 The new value of the smoothing stat SP1.
Applications should store this value for subsequent invocations of the
filter.
[in,out] newSmoothingStat2 The new value of the smoothing stat SP2.
Applications should store this value for subsequent invocations of the
filter.

please Iker help me to implemente this in scenedrawer.cpp
(NiuserTracker openni example);

i have an app that send hand skeleton points to tuio working with
multitouch vista but not maintain the points static
Reply all
Reply to author
Forward
0 new messages