/// <summary> /// Discover the proper histogram bounds for the provided skeleton data. /// </summary> /// <param name="skeletonBatch"></param> /// <returns>A mapping of JointType -> BinDefintion defining the boundaries of the bins for each joint's histogram.</returns> public static SortedDictionary <JointType, BinDefinition> binDefinitionsFor(List <List <Skeleton> > skeletonBatch) { SortedDictionary <JointType, BinDefinition> binDefinitions = null; foreach (List <Skeleton> skeletons in skeletonBatch) { SortedDictionary <JointType, BinDefinition> binDefs = new SortedDictionary <JointType, BinDefinition>(); foreach (var dataset in prepareData(skeletons)) { BinDefinition binDef = new BinDefinition(); binDef.lowerBound = dataset.Value.Min(); binDef.upperBound = dataset.Value.Max(); binDef.numBins = HJPDBinCount; binDefs[dataset.Key] = binDef; } if (binDefinitions == null) { binDefinitions = binDefs; } else { binDefinitions = combineDefinitions(binDefinitions, binDefs); } } return(binDefinitions); }
/// <summary> /// Convenience method to combine bin definitions. /// </summary> /// <param name="left"></param> /// <param name="right"></param> /// <returns>A mapping of JointType -> BinDefintion, where the lower and upper bounds of each is the lower and higher for each bin between left and right respectively</returns> public static SortedDictionary <JointType, BinDefinition> combineDefinitions(SortedDictionary <JointType, BinDefinition> left, SortedDictionary <JointType, BinDefinition> right) { if (!left.Keys.SequenceEqual(right.Keys)) { throw new ArgumentException("Bin Definition maps disagree on the included joint types"); } SortedDictionary <JointType, BinDefinition> retval = new SortedDictionary <JointType, BinDefinition>(); foreach (JointType key in left.Keys) { if (left[key].numBins != right[key].numBins) { throw new ArgumentException("Bin Definition maps disagree on the number of bins for " + key); } BinDefinition binDef = new BinDefinition(); binDef.lowerBound = Math.Min(left[key].lowerBound, right[key].lowerBound); binDef.upperBound = Math.Max(left[key].upperBound, right[key].upperBound); binDef.numBins = left[key].numBins; retval[key] = binDef; } return(retval); }
/// <summary> /// Discover the proper boundaries for the eventual histograms of the skeleton data. /// </summary> /// <param name="jointList"></param> /// <param name="skeletonBatch"></param> /// <returns>A list of BinDefinition objects representing the boundaries of the bins of each metric's histogram.</returns> public static List <BinDefinition> binDefinitionsFor(List <JointType> jointList, List <List <Skeleton> > skeletonBatch) { // Bin definitions begin at numeric extremes List <BinDefinition> binDefinitions = new List <BinDefinition>(); for (int i = 0; i < jointList.Count; ++i) { BinDefinition extremeBinDef1 = new BinDefinition() { lowerBound = double.MaxValue, upperBound = double.MinValue, numBins = RADBinCount }; binDefinitions.Add(extremeBinDef1); BinDefinition extremeBinDef2 = new BinDefinition() { lowerBound = double.MaxValue, upperBound = double.MinValue, numBins = RADBinCount }; binDefinitions.Add(extremeBinDef2); } // Look at the preprocessed data for each list of skeletons and update the bin definitions appropriately foreach (List <Skeleton> skeletons in skeletonBatch) { List <List <double> > data = prepareData(jointList, skeletons); for (int i = 0; i < binDefinitions.Count; ++i) { BinDefinition binDef = binDefinitions[i]; binDef.lowerBound = Math.Min(binDef.lowerBound, data[i].Min()); binDef.upperBound = Math.Max(binDef.upperBound, data[i].Max()); binDefinitions[i] = binDef; } } return(binDefinitions); }