I have a method in my class that eats up something like 80% of my processor time while its running. In-fact one line within the method is responsible for the majority of this.
The idea behind this class is to stabilize the depth readings being returned by the Microsoft Kinect device by obtaining the average value of the last 4 frames plus the current one.
This is a the basic layout of the method concerned.
public event EventHandler<DenoisedDepthReadyEventArgs> DenoisedDepthReady;
private const int HistoricFrameCount = 4;
private readonly KinectSensor _KinectSensor;
private List<DepthImagePixel[]> _LastFrames;
private FilteredDepthPixel[] _FilteredDepths;
private bool _ResolutionFilteredDepthsInitialized;
//This is invoked upto 30 times a second
private void KinectSensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
{
if (depthFrame != null)
{
DepthImagePixel[] currentPixels = new DepthImagePixel[depthFrame.PixelDataLength]; //Note this is huge array, usually 307200
depthFrame.CopyDepthImagePixelDataTo(currentPixels);
this._LastFrames.Add(currentPixels);
this.ReduceNoiseAndInvokeIfRequired(currentPixels, depthFrame.PixelDataLength, depthFrame.MaxDepth, depthFrame.MinDepth);
}
}
}
private void ReduceNoiseAndInvokeIfRequired(DepthImagePixel[] currentPixels, int totalPixels, int maxDepth, int minDepth)
{
if (this._LastFrames.Count == HistoricFrameCount)
{
if (!this._ResolutionFilteredDepthsInitialized)
{
this._FilteredDepths = new FilteredDepthPixel[totalPixels];
for (int i = 0; i < totalPixels; i++)
{
this._FilteredDepths[i] = new FilteredDepthPixel();
}
this._ResolutionFilteredDepthsInitialized = true;
}
for (int i = 0; i < this._LastFrames.Count; i++)
{
DepthImagePixel[] currentFrame = this._LastFrames[i];
for (int p = 0; p < totalPixels; p++)
{
this._FilteredDepths[p].Depth = (this._FilteredDepths[p].Depth + currentFrame[p].Depth) / 2;
}
}
for (int i = 0; i < currentPixels.Length; i++)
{
this._FilteredDepths[i].Depth = (this._FilteredDepths[i].Depth + currentPixels[i].Depth) / 2;
this._FilteredDepths[i].IsKnownDepth = currentPixels[i].IsKnownDepth;
this._FilteredDepths[i].PlayerIndex = currentPixels[i].PlayerIndex;
}
this._LastFrames.RemoveAt(this._LastFrames.Count - 1);
RaiseOnDenoisedDepthEvent(this._FilteredDepths, maxDepth, minDepth);
}
}
and here is what the performance profiler says about what I'm doing.
I'm trying to avoid threading and parallelization for the time being. I am also conscious that building a new collection each frame is probably silly too but not sure how to improve this given the immutability of the type I want to return.
Any input or guidance on alternative approaches would be highly appreciated.