public static DirectionGraph BuildSuperGraph(Image image) { DirectionalImage dirimage = CreateDirections(image); DirectionGraph graph = CreateGraph(dirimage); DirectionGraph supergraph = CreateSuperGraph(graph); return(supergraph); }
private static void FindNeighbours(DirectionGraph graph, DirectionNode[,] nodes) { int count = graph.Nodes.Count; int[,] adjmatrix = new int[count, count]; Dictionary <DirectionNode, int> dict = new Dictionary <DirectionNode, int>(40); int k = 0; foreach (DirectionNode node in graph.Nodes) { dict.Add(node, k); ++k; } int width = nodes.GetLength(0); int height = nodes.GetLength(1); for (int j = 1; j < height; j++) { for (int i = 1; i < width; i++) { DirectionNode curr = nodes[i, j]; if (curr == null || curr.Weight < MINNOISECOUNT) { continue; } DirectionNode l = nodes[i - 1, j]; DirectionNode u = nodes[i, j - 1]; int num1, num2; if (l != null && l != curr && l.Weight >= MINNOISECOUNT) { dict.TryGetValue(l, out num1); dict.TryGetValue(curr, out num2); adjmatrix[num1, num2]++; adjmatrix[num2, num1]++; } if (u != null && u != curr && u.Weight >= MINNOISECOUNT) { dict.TryGetValue(u, out num1); dict.TryGetValue(curr, out num2); adjmatrix[num1, num2]++; adjmatrix[num2, num1]++; } } } graph.perimeterarray = adjmatrix; }
/// <summary> /// selects image with the lowest cost function value /// </summary> /// <param name="fprint">image we want to identify</param> /// <param name="printarray">array of fingerprints</param> /// <returns>index of the most appropriate image</returns> public static int MatchGraphPrint(DirectionGraph fprint, DirectionGraph[] printarray) { int minindex = 0; double minvalue = CostFunction(fprint, printarray[0]); for (int i = 1; i < printarray.Length; i++) { double value = CostFunction(fprint, printarray[i]); if (value < minvalue) { minindex = i; minvalue = value; } } return(minindex); }
public static bool Compare(DirectionGraph g1, DirectionGraph g2) { const double q = 0.3; int simnodecount = 0; for (int i = 0; i <= 3; i++) { if (Math.Abs(g1.Nodes[i].Weight - g2.Nodes[i].Weight) <= q * Math.Max(g1.Nodes[i].Weight, g2.Nodes[i].Weight)) { simnodecount++; } } if (simnodecount < 3) { return(false); } int simcount = 0; for (int i = 1; i <= 3; i++) { for (int j = 0; j <= i - 1; j++) { if (Math.Abs(g1.weightarray[i, j] - g2.weightarray[i, j]) <= q * Math.Max(g1.weightarray[i, j], g2.weightarray[i, j])) { simcount++; } } } if (simcount < 3) { return(false); } return(true); }
public static double CostFunction(DirectionGraph gr1, DirectionGraph gr2) { if (gr1.Nodes.Count != gr2.Nodes.Count) { return(-1); } int count = gr1.Nodes.Count; int nodesum = 0; for (int i = 0; i < count; ++i) { nodesum += Math.Abs(gr1.Nodes[i].Weight - gr2.Nodes[i].Weight); //? Abs? } double weightsum = 0; for (int i = 1; i <= 3; i++) { for (int j = 0; j <= i - 1; j++) { weightsum += Math.Abs(gr1.weightarray[i, j] - gr2.weightarray[i, j]); } } return(nodesum * weightsum); }
/// <summary> /// selects image with the lowest cost function value /// </summary> /// <param name="fprint">image we want to identify</param> /// <param name="printarray">array of fingerprints</param> /// <returns>index of the most appropriate image</returns> public static int MatchGraphPrint(DirectionGraph fprint, DirectionGraph[] printarray) { int minindex = 0; double minvalue = CostFunction(fprint, printarray[0]); for (int i = 1; i < printarray.Length; i++) { double value = CostFunction(fprint, printarray[i]); if (value < minvalue) { minindex = i; minvalue = value; } } return minindex; }
public static double CostFunction(DirectionGraph gr1, DirectionGraph gr2) { if (gr1.Nodes.Count != gr2.Nodes.Count) return -1; int count = gr1.Nodes.Count; int nodesum = 0; for (int i = 0; i < count; ++i) { nodesum += Math.Abs(gr1.Nodes[i].Weight - gr2.Nodes[i].Weight); //? Abs? } double weightsum = 0; for (int i = 1; i <= 3; i++) { for (int j = 0; j <= i - 1; j++) { weightsum += Math.Abs(gr1.weightarray[i, j] - gr2.weightarray[i, j]); } } return nodesum * weightsum; }
public static bool Compare(DirectionGraph g1, DirectionGraph g2) { const double q = 0.3; int simnodecount = 0; for (int i = 0; i <= 3; i++) { if (Math.Abs(g1.Nodes[i].Weight - g2.Nodes[i].Weight) <= q * Math.Max(g1.Nodes[i].Weight, g2.Nodes[i].Weight)) simnodecount++; } if (simnodecount < 3) return false; int simcount = 0; for (int i = 1; i <= 3; i++) { for (int j = 0; j <= i - 1; j++) { if (Math.Abs(g1.weightarray[i, j] - g2.weightarray[i, j]) <= q * Math.Max(g1.weightarray[i, j], g2.weightarray[i, j])) simcount++; } } if (simcount < 3) return false; return true; }
private static void FindNeighbours(DirectionGraph graph, DirectionNode[,] nodes) { int count = graph.Nodes.Count; int[,] adjmatrix = new int[count, count]; Dictionary<DirectionNode, int> dict = new Dictionary<DirectionNode, int>(40); int k = 0; foreach (DirectionNode node in graph.Nodes) { dict.Add(node, k); ++k; } int width = nodes.GetLength(0); int height = nodes.GetLength(1); for (int j = 1; j < height; j++) { for (int i = 1; i < width; i++) { DirectionNode curr = nodes[i, j]; if (curr == null || curr.Weight < MINNOISECOUNT) continue; DirectionNode l = nodes[i - 1, j]; DirectionNode u = nodes[i, j - 1]; int num1, num2; if (l != null && l != curr && l.Weight >= MINNOISECOUNT) { dict.TryGetValue(l, out num1); dict.TryGetValue(curr, out num2); adjmatrix[num1, num2]++; adjmatrix[num2, num1]++; } if (u != null && u != curr && u.Weight >= MINNOISECOUNT) { dict.TryGetValue(u, out num1); dict.TryGetValue(curr, out num2); adjmatrix[num1, num2]++; adjmatrix[num2, num1]++; } } } graph.perimeterarray = adjmatrix; }
private static DirectionGraph CreateSuperGraph(DirectionGraph graph) { Point[] centres = new Point[DIRECTIONNUM]; #region initcentres for (int i = 0; i < DIRECTIONNUM; i++) { centres[i] = new Point(0, 0); } #endregion int[] number = new int[DIRECTIONNUM]; //numbers of buckets int[] nodeweights = new int[DIRECTIONNUM]; DirectionGraph supergraph = new DirectionGraph(); double[,] edgeweights = new double[DIRECTIONNUM, DIRECTIONNUM]; DirectionNode node1, node2; for (int i = 0; i < graph.Nodes.Count; i++) { node1 = graph.Nodes[i]; int dir1 = node1.direction; centres[dir1] += node1.gravitycenter; number[dir1]++; nodeweights[dir1] += node1.Weight; for (int j = i + 1; j < graph.Nodes.Count; j++) { node2 = graph.Nodes[j]; int dir2 = node2.direction; if (dir1 == dir2) continue; edgeweights[dir1, dir2] += graph.perimeterarray[i, j]; edgeweights[dir2, dir1] = edgeweights[dir1, dir2]; } } for (byte i = 0; i < DIRECTIONNUM; i++) { supergraph.add(new DirectionNode(i)); if (number[i] == 0) supergraph.Nodes[i].gravitycenter = new Point(0, 0); else supergraph.Nodes[i].gravitycenter = centres[i] / number[i]; supergraph.Nodes[i].Weight = nodeweights[i]; } for (int i = 0; i < DIRECTIONNUM; i++) { for (int j = 0; j < i; j++) { double dist = Distance(supergraph.Nodes[i].gravitycenter, supergraph.Nodes[j].gravitycenter); edgeweights[i, j] += dist; edgeweights[j, i] += dist; } } supergraph.weightarray = edgeweights; return supergraph; }
private static DirectionGraph CreateGraph(DirectionalImage directions) { DirectionGraph graph = new DirectionGraph(); int width = directions.arr.GetLength(0); int height = directions.arr.GetLength(1); DirectionNode[,] tempnodes = new DirectionNode[width, height]; DirectionNode dirnode; #region First line and first column if (directions.arr[0, 0] != 9) { dirnode = new DirectionNode(); dirnode.direction = directions.arr[0, 0]; dirnode.add(new Point(0, 0)); graph.add(dirnode); tempnodes[0, 0] = dirnode; } for (int i = 1; i < width; i++) { byte curr = directions.arr[i, 0]; if (curr == 9) continue; byte l = directions.arr[i - 1, 0]; if (curr == l) { tempnodes[i, 0] = tempnodes[i - 1, 0]; tempnodes[i - 1, 0].add(new Point(i, 0)); } else { dirnode = new DirectionNode(); dirnode.direction = curr; dirnode.add(new Point(i, 0)); graph.add(dirnode); tempnodes[i, 0] = dirnode; } } int a = 1; for (int j = 1; j < height; j++) { byte curr = directions.arr[0, j]; if (curr == 9) continue; byte u = directions.arr[0, j - 1]; if (curr == u) { tempnodes[0, j] = tempnodes[0, j - 1]; tempnodes[0, j - 1].add(new Point(0, j)); } else { dirnode = new DirectionNode(); dirnode.direction = curr; dirnode.add(new Point(0, j)); graph.add(dirnode); tempnodes[0, j] = dirnode; } } #endregion int b = 0; #region Main for (int j = 1; j < directions.arr.GetLength(1); j++) { for (int i = 1; i < directions.arr.GetLength(0); i++) { byte curr = directions.arr[i, j]; if (curr == 9) continue; byte l = directions.arr[i - 1, j]; byte u = directions.arr[i, j - 1]; if (curr == l && curr == u && tempnodes[i, j - 1] != tempnodes[i - 1, j]) { DirectionNode input, output; if (tempnodes[i - 1, j].Weight > tempnodes[i, j - 1].Weight) { input = tempnodes[i, j - 1]; output = tempnodes[i - 1, j]; } else { output = tempnodes[i, j - 1]; input = tempnodes[i - 1, j]; } foreach (Point point in input.PointList) { tempnodes[point.x, point.y] = output; output.add(point); } tempnodes[i, j] = output; input.PointList.Clear(); output.add(new Point(i, j)); } else if (curr == l) { tempnodes[i, j] = tempnodes[i - 1, j]; tempnodes[i - 1, j].add(new Point(i, j)); } else if (curr == u) { tempnodes[i, j] = tempnodes[i, j - 1]; tempnodes[i, j - 1].add(new Point(i, j)); } else { dirnode = new DirectionNode(); dirnode.direction = curr; dirnode.add(new Point(i, j)); graph.add(dirnode); tempnodes[i, j] = dirnode; } } } #endregion DirectionGraph endgraph = new DirectionGraph(); foreach (DirectionNode node in graph.Nodes) { if (node.Weight >= MINNOISECOUNT) endgraph.add(node); } #region computeweights foreach (DirectionNode node in endgraph.Nodes) { node.ComputeCenter(); } #endregion FindNeighbours(endgraph, tempnodes); //tempnodes - array with references to DirectionNodes return endgraph; }
private static DirectionGraph CreateSuperGraph(DirectionGraph graph) { Point[] centres = new Point[DIRECTIONNUM]; #region initcentres for (int i = 0; i < DIRECTIONNUM; i++) { centres[i] = new Point(0, 0); } #endregion int[] number = new int[DIRECTIONNUM]; //numbers of buckets int[] nodeweights = new int[DIRECTIONNUM]; DirectionGraph supergraph = new DirectionGraph(); double[,] edgeweights = new double[DIRECTIONNUM, DIRECTIONNUM]; DirectionNode node1, node2; for (int i = 0; i < graph.Nodes.Count; i++) { node1 = graph.Nodes[i]; int dir1 = node1.direction; centres[dir1] += node1.gravitycenter; number[dir1]++; nodeweights[dir1] += node1.Weight; for (int j = i + 1; j < graph.Nodes.Count; j++) { node2 = graph.Nodes[j]; int dir2 = node2.direction; if (dir1 == dir2) { continue; } edgeweights[dir1, dir2] += graph.perimeterarray[i, j]; edgeweights[dir2, dir1] = edgeweights[dir1, dir2]; } } for (byte i = 0; i < DIRECTIONNUM; i++) { supergraph.add(new DirectionNode(i)); if (number[i] == 0) { supergraph.Nodes[i].gravitycenter = new Point(0, 0); } else { supergraph.Nodes[i].gravitycenter = centres[i] / number[i]; } supergraph.Nodes[i].Weight = nodeweights[i]; } for (int i = 0; i < DIRECTIONNUM; i++) { for (int j = 0; j < i; j++) { double dist = Distance(supergraph.Nodes[i].gravitycenter, supergraph.Nodes[j].gravitycenter); edgeweights[i, j] += dist; edgeweights[j, i] += dist; } } supergraph.weightarray = edgeweights; return(supergraph); }
private static DirectionGraph CreateGraph(DirectionalImage directions) { DirectionGraph graph = new DirectionGraph(); int width = directions.arr.GetLength(0); int height = directions.arr.GetLength(1); DirectionNode[,] tempnodes = new DirectionNode[width, height]; DirectionNode dirnode; #region First line and first column if (directions.arr[0, 0] != 9) { dirnode = new DirectionNode(); dirnode.direction = directions.arr[0, 0]; dirnode.add(new Point(0, 0)); graph.add(dirnode); tempnodes[0, 0] = dirnode; } for (int i = 1; i < width; i++) { byte curr = directions.arr[i, 0]; if (curr == 9) { continue; } byte l = directions.arr[i - 1, 0]; if (curr == l) { tempnodes[i, 0] = tempnodes[i - 1, 0]; tempnodes[i - 1, 0].add(new Point(i, 0)); } else { dirnode = new DirectionNode(); dirnode.direction = curr; dirnode.add(new Point(i, 0)); graph.add(dirnode); tempnodes[i, 0] = dirnode; } } int a = 1; for (int j = 1; j < height; j++) { byte curr = directions.arr[0, j]; if (curr == 9) { continue; } byte u = directions.arr[0, j - 1]; if (curr == u) { tempnodes[0, j] = tempnodes[0, j - 1]; tempnodes[0, j - 1].add(new Point(0, j)); } else { dirnode = new DirectionNode(); dirnode.direction = curr; dirnode.add(new Point(0, j)); graph.add(dirnode); tempnodes[0, j] = dirnode; } } #endregion int b = 0; #region Main for (int j = 1; j < directions.arr.GetLength(1); j++) { for (int i = 1; i < directions.arr.GetLength(0); i++) { byte curr = directions.arr[i, j]; if (curr == 9) { continue; } byte l = directions.arr[i - 1, j]; byte u = directions.arr[i, j - 1]; if (curr == l && curr == u && tempnodes[i, j - 1] != tempnodes[i - 1, j]) { DirectionNode input, output; if (tempnodes[i - 1, j].Weight > tempnodes[i, j - 1].Weight) { input = tempnodes[i, j - 1]; output = tempnodes[i - 1, j]; } else { output = tempnodes[i, j - 1]; input = tempnodes[i - 1, j]; } foreach (Point point in input.PointList) { tempnodes[point.x, point.y] = output; output.add(point); } tempnodes[i, j] = output; input.PointList.Clear(); output.add(new Point(i, j)); } else if (curr == l) { tempnodes[i, j] = tempnodes[i - 1, j]; tempnodes[i - 1, j].add(new Point(i, j)); } else if (curr == u) { tempnodes[i, j] = tempnodes[i, j - 1]; tempnodes[i, j - 1].add(new Point(i, j)); } else { dirnode = new DirectionNode(); dirnode.direction = curr; dirnode.add(new Point(i, j)); graph.add(dirnode); tempnodes[i, j] = dirnode; } } } #endregion DirectionGraph endgraph = new DirectionGraph(); foreach (DirectionNode node in graph.Nodes) { if (node.Weight >= MINNOISECOUNT) { endgraph.add(node); } } #region computeweights foreach (DirectionNode node in endgraph.Nodes) { node.ComputeCenter(); } #endregion FindNeighbours(endgraph, tempnodes); //tempnodes - array with references to DirectionNodes return(endgraph); }