private static void LearnRotations(List<Patch> patches, Tree tree) { for (int iters = 0; iters < 2; iters++) { // Loop over the patches foreach (var p in patches) { int bestCount = 0; int bestAngle = 0; var oldnd = p.NodeIndex; var newnd = -1; // Loop over rotations for (int angle = 0; angle < 360; angle += 5) { p.Angle = angle; // Apply the tree to the patch var leaf = tree.Apply(p); // See if bigger, if so store best rotation if (leaf.Count > bestCount) { bestCount = leaf.Count; bestAngle = angle; newnd = leaf.Index; } } // Move to node for best rotation p.NodeIndex = newnd; p.Angle = bestAngle; tree.Nodes[oldnd].Count--; tree.Nodes[newnd].Count++; } } }
public void AddLayer(Tree tree, List<Patch> patches) { // Get a set of possible features var features = GetFeatures(patches[0],100); var leafNodes = tree.Nodes.Where(nd => nd.IsLeaf).ToList(); // For each feature, apply to all patches + count trues and falses, compute metric foreach (var f in features) { int[] trueCount = new int[tree.Nodes.Count]; foreach (var p in patches) { if (f.ComputeFeature(p)) { trueCount[p.NodeIndex]++; } } foreach (var nd in leafNodes) { double metric = Math.Abs(trueCount[nd.Index] - (nd.Count - trueCount[nd.Index])); if (metric < nd.bestMetric) { nd.Feature = f; nd.bestMetric = metric; } } } // Split leaf nodes using best feature foreach(var nd in leafNodes) { //Console.WriteLine("Feature for node " + nd.Index + ": " + nd.Feature); nd.Left = tree.AddNode(); nd.Right = tree.AddNode(); } // Update which node each patch is at foreach (var p in patches) { var nd = tree.Nodes[p.NodeIndex]; if (nd.Feature.ComputeFeature(p)) { p.NodeIndex = nd.Right.Index; nd.Right.Count++; } else { p.NodeIndex= nd.Left.Index; nd.Left.Count++; } } }
public Tree Learn(int depth, List<Patch> patches) { var tree = new Tree(); tree.Root.Count = patches.Count; Console.Write("Training tree on "+patches.Count+" patches."); foreach (var p in patches) p.NodeIndex = 0; for (int d = 0; d < depth; d++) { Console.Write("."); AddLayer(tree, patches); } Console.WriteLine(); return tree; }
private static void LearnTranslations(List<Patch> patches, Tree tree) { int max = 16; int step = 2; // Loop over the patches foreach (var p in patches) { int bestCount = 0; int bestX = 0; int bestY = 0; var oldnd = p.NodeIndex; var newnd = -1; // Loop over rotations for (int y = -max; y <= max; y += step) { for (int x = -max; x <= max; x += step) { p.NudgeX = x; p.NudgeY = y; if ((x + p.Left < 0) || (x + p.Left + p.Width >= p.Image.Bitmap.PixelWidth)) continue; if ((y + p.Top < 0) || (y + p.Top + p.Height >= p.Image.Bitmap.PixelHeight)) continue; // Apply the tree to the patch var leaf = tree.Apply(p); // See if bigger, if so store best rotation if (leaf.Count > bestCount) { bestCount = leaf.Count; bestX = x; bestY = y; newnd = leaf.Index; } } } // Move to node for best rotation p.NodeIndex = newnd; p.NudgeX = bestX; p.NudgeY = bestY; tree.Nodes[oldnd].Count--; tree.Nodes[newnd].Count++; } }