/// <summary> /// Computes the similarity between two <see cref="TreeHistogram"/> objects using the pyramid match method of <see href="http://www.cs.utexas.edu/~grauman/research/projects/pmk/pmk_projectpage.htm">Grauman and Darrell</see>. /// </summary> /// <param name="lhs">First histogram</param> /// <param name="rhs">Second histogram</param> /// <returns>A value between 0 and 1 indicating the similarity of the two histograms</returns> public float Similarity(TreeHistogram lhs, TreeHistogram rhs) { setDimensions(_numTrees, _numLevels); if (_normalized) { return(matchNormalized(lhs._nodes.ToArray(), rhs._nodes.ToArray())); } return(match(lhs._nodes.ToArray(), rhs._nodes.ToArray())); }
/// <summary> /// Divides the all nodes in <paramref name="hist"/> by <paramref name="value"/>. Does not alter the arguments. /// </summary> /// <param name="hist">Histogram to divide</param> /// <param name="value">Divisor</param> /// <returns>The resulting histogram</returns> public static TreeHistogram Divide(TreeHistogram hist, float value) { List <TreeNode> nodes = new List <TreeNode>(); foreach (TreeNode node in hist) { nodes.Add(new TreeNode(node, node.Value / value)); } return(new TreeHistogram(nodes)); }
/// <summary> /// Subtracts the values in one histogram from another. /// </summary> /// <param name="lhs">A histogram</param> /// <param name="rhs">The histogram to subtract</param> /// <returns>The difference of the two histograms</returns> public static TreeHistogram Subtract(TreeHistogram lhs, TreeHistogram rhs) { int count0 = lhs._nodes.Count; int count1 = rhs._nodes.Count; int index0 = 0; int index1 = 0; List <TreeNode> nodes = new List <TreeNode>(); while (index0 < count0 && index1 < count1) { TreeNode node0 = lhs._nodes[index0]; TreeNode node1 = rhs._nodes[index1]; if (node0.Tree < node1.Tree) { nodes.Add(node0); index0++; } else if (node1.Tree < node0.Tree) { nodes.Add(new TreeNode(node1, -node1.Value)); index1++; } else if (node0.Index < node1.Index) { nodes.Add(node0); index0++; } else if (node1.Index < node0.Index) { nodes.Add(new TreeNode(node1, -node1.Value)); index1++; } else { nodes.Add(new TreeNode(node0, node0.Value - node1.Value)); index0++; index1++; } } while (index0 < count0) { nodes.Add(lhs._nodes[index0++]); } while (index1 < count1) { TreeNode node1 = rhs._nodes[index1++]; nodes.Add(new TreeNode(node1, -node1.Value)); } return(new TreeHistogram(nodes)); }
/// <summary> /// Writes <paramref name="hist"/> to <paramref name="stream"/>. /// </summary> /// <param name="stream">Stream to use for writing the histogram</param> /// <param name="hist">Histogram to write</param> public static void Write(Stream stream, TreeHistogram hist) { BinaryWriter output = new BinaryWriter(stream); List <TreeNode> nodes = hist._nodes; output.Write(hist._id); output.Write(nodes.Count); for (int i = 0; i < nodes.Count; i++) { TreeNode node = nodes[i]; output.Write(node.Tree); output.Write(node.Index); output.Write(node.LeafIndex); output.Write(node.Value); } }
/// <summary> /// Intersects two histograms. /// </summary> /// <param name="lhs">Histogram</param> /// <param name="rhs">The second histogram</param> /// <returns>The histogram intersection of <paramref name="lhs"/> and <paramref name="rhs"/></returns> public static TreeHistogram Intersect(TreeHistogram lhs, TreeHistogram rhs) { int count0 = lhs._nodes.Count; int count1 = rhs._nodes.Count; int index0 = 0; int index1 = 0; List <TreeNode> nodes = new List <TreeNode>(); while (index0 < count0 && index1 < count1) { TreeNode node0 = lhs._nodes[index0]; TreeNode node1 = rhs._nodes[index1]; if (node0.Tree < node1.Tree) { index0++; } else if (node1.Tree < node0.Tree) { index1++; } else if (node0.Index < node1.Index) { index0++; } else if (node1.Index < node0.Index) { index1++; } else { nodes.Add(new TreeNode(node0, Math.Min(node0.Value, node1.Value))); index0++; index1++; } } return(new TreeHistogram(nodes)); }
private static float dot(TreeHistogram xHist, TreeHistogram yHist) { float sum = 0; TreeNode[] x = (from node in xHist where node.LeafIndex >= 0 select node).ToArray(); TreeNode[] y = (from node in yHist where node.LeafIndex >= 0 select node).ToArray(); int xlen = x.Length; int ylen = y.Length; int i = 0; int j = 0; while (i < xlen && j < ylen) { TreeNode lhs = x[i]; TreeNode rhs = y[j]; if (lhs.LeafIndex < rhs.LeafIndex) { i++; } else if (rhs.LeafIndex < lhs.LeafIndex) { j++; } else { sum += lhs.Value * rhs.Value; i++; j++; } } return(sum); }
/// <summary> /// Computes the similarity between <paramref name="lhs"/> and <paramref name="rhs"/> using /// a radial basis fuction computed on their leaf nodes. /// </summary> /// <param name="lhs">The first histogram</param> /// <param name="rhs">The second histogram</param> /// <returns>A value between 0 and 1 indicating the similarity between these histograms</returns> public float Similarity(TreeHistogram lhs, TreeHistogram rhs) { return((float)Math.Exp(-_gamma * (dot(lhs, lhs) + dot(rhs, rhs) - 2 * dot(lhs, rhs)))); }