Search in sources :

Example 16 with Edge

use of chapter4.section3.Edge in project BoofCV by lessthanoptimal.

the class FhEdgeWeights8_PLU8 method process.

@Override
public void process(Planar<GrayU8> input, FastQueue<Edge> edges) {
    edges.reset();
    int w = input.width - 1;
    int h = input.height - 1;
    // First consider the inner pixels
    for (int y = 0; y < h; y++) {
        int indexSrc = input.startIndex + y * input.stride + 1;
        int indexDst = +y * input.width + 1;
        for (int x = 1; x < w; x++, indexSrc++, indexDst++) {
            int weight1 = 0, weight2 = 0, weight3 = 0, weight4 = 0;
            for (int i = 0; i < numBands; i++) {
                GrayU8 band = input.getBand(i);
                // (x,y)
                int color0 = band.data[indexSrc] & 0xFF;
                // (x+1,y)
                int color1 = band.data[indexSrc + 1] & 0xFF;
                // (x,y+1)
                int color2 = band.data[indexSrc + input.stride] & 0xFF;
                int diff1 = color0 - color1;
                int diff2 = color0 - color2;
                weight1 += diff1 * diff1;
                weight2 += diff2 * diff2;
                // (x+1,y+1)
                int color3 = band.data[indexSrc + 1 + input.stride] & 0xFF;
                // (x-1,y+1)
                int color4 = band.data[indexSrc - 1 + input.stride] & 0xFF;
                int diff3 = color0 - color3;
                int diff4 = color0 - color4;
                weight3 += diff3 * diff3;
                weight4 += diff4 * diff4;
            }
            Edge e1 = edges.grow();
            Edge e2 = edges.grow();
            e1.sortValue = (float) Math.sqrt(weight1);
            e1.indexA = indexDst;
            e1.indexB = indexDst + 1;
            e2.sortValue = (float) Math.sqrt(weight2);
            e2.indexA = indexDst;
            e2.indexB = indexDst + input.width;
            Edge e3 = edges.grow();
            Edge e4 = edges.grow();
            e3.sortValue = (float) Math.sqrt(weight3);
            e3.indexA = indexDst;
            e3.indexB = indexDst + 1 + input.width;
            e4.sortValue = (float) Math.sqrt(weight4);
            e4.indexA = indexDst;
            e4.indexB = indexDst - 1 + input.width;
        }
    }
    // Handle border pixels
    for (int y = 0; y < h; y++) {
        checkAround(0, y, input, edges);
        checkAround(w, y, input, edges);
    }
    for (int x = 0; x < w; x++) {
        checkAround(x, h, input, edges);
    }
}
Also used : GrayU8(boofcv.struct.image.GrayU8) Edge(boofcv.alg.segmentation.fh04.SegmentFelzenszwalbHuttenlocher04.Edge)

Example 17 with Edge

use of chapter4.section3.Edge in project BoofCV by lessthanoptimal.

the class FhEdgeWeights8_U8 method process.

@Override
public void process(GrayU8 input, FastQueue<Edge> edges) {
    int w = input.width - 1;
    int h = input.height - 1;
    // First consider the inner pixels
    for (int y = 0; y < h; y++) {
        int indexSrc = input.startIndex + y * input.stride + 1;
        int indexDst = +y * input.width + 1;
        for (int x = 1; x < w; x++, indexSrc++, indexDst++) {
            // (x,y)
            int color0 = input.data[indexSrc] & 0xFF;
            // (x+1,y)
            int color1 = input.data[indexSrc + 1] & 0xFF;
            // (x,y+1)
            int color2 = input.data[indexSrc + input.stride] & 0xFF;
            Edge e1 = edges.grow();
            Edge e2 = edges.grow();
            e1.sortValue = Math.abs(color1 - color0);
            e1.indexA = indexDst;
            e1.indexB = indexDst + 1;
            e2.sortValue = Math.abs(color2 - color0);
            e2.indexA = indexDst;
            e2.indexB = indexDst + input.width;
            // (x+1,y+1)
            int color3 = input.data[indexSrc + 1 + input.stride] & 0xFF;
            // (x-1,y+1)
            int color4 = input.data[indexSrc - 1 + input.stride] & 0xFF;
            Edge e3 = edges.grow();
            Edge e4 = edges.grow();
            e3.sortValue = Math.abs(color3 - color0);
            e3.indexA = indexDst;
            e3.indexB = indexDst + 1 + input.width;
            e4.sortValue = Math.abs(color4 - color0);
            e4.indexA = indexDst;
            e4.indexB = indexDst - 1 + input.width;
        }
    }
    // Handle border pixels
    for (int y = 0; y < h; y++) {
        checkAround(0, y, input, edges);
        checkAround(w, y, input, edges);
    }
    for (int x = 0; x < w; x++) {
        checkAround(x, h, input, edges);
    }
}
Also used : Edge(boofcv.alg.segmentation.fh04.SegmentFelzenszwalbHuttenlocher04.Edge)

Example 18 with Edge

use of chapter4.section3.Edge in project BoofCV by lessthanoptimal.

the class FhEdgeWeights8_U8 method check.

private void check(int x, int y, int color0, int indexA, GrayU8 input, FastQueue<Edge> edges) {
    if (!input.isInBounds(x, y))
        return;
    int indexSrc = input.startIndex + y * input.stride + x;
    int indexB = +y * input.width + x;
    int colorN = input.data[indexSrc] & 0xFF;
    Edge e1 = edges.grow();
    e1.sortValue = (float) Math.abs(color0 - colorN);
    e1.indexA = indexA;
    e1.indexB = indexB;
}
Also used : Edge(boofcv.alg.segmentation.fh04.SegmentFelzenszwalbHuttenlocher04.Edge)

Example 19 with Edge

use of chapter4.section3.Edge in project algorithms-sedgewick-wayne by reneargento.

the class Exercise26_CriticalEdges method findCriticalEdges.

/**
 * An edge e is critical if and only if it is a bridge in the subgraph containing all edges with weights
 * less than or equal to the weight of edge e.
 *
 * Proof:
 * 1st part: If an edge e is critical then it is a bridge in the subgraph containing all edges with weights
 * less than or equal to the weight of edge e.
 * Consider by contradiction that edge e is not a bridge in such subgraph. If it is not a bridge, then there is another
 * edge f that connects the same components as e in the subgraph and it has weight less than or equal to e.
 * In this case, edge e could be replaced by edge f in an MST and the MST weight would not increase.
 * However, since e is critical and cannot be replaced by an edge with weight less than or equal to it,
 * it must be a bridge in the subgraph.
 *
 * 2nd part: If an edge e is a bridge in the subgraph containing all edges with weights less than or equal to its
 * weight then e is critical.
 * Consider by contradiction that e is not critical. If e is not critical, then there must be another edge that
 * could replace it in an MST and would not cause the MST weight to increase.
 * However, if this edge existed, it would be part of the subgraph containing all edges with weights
 * less than or equal to the weight of edge e. It would also connect both components C1 and C2 that are connected
 * by edge e. However, e is a bridge and its removal would split components C1 and C2. So no such edge exists.
 * Therefore, edge e is critical.
 */
// O(E lg E)
public Queue<Edge> findCriticalEdges(EdgeWeightedGraph edgeWeightedGraph) {
    Queue<Edge> criticalEdges = new Queue<>();
    // Modified Kruskal's algorithm
    Queue<Edge> minimumSpanningTree = new Queue<>();
    PriorityQueueResize<Edge> priorityQueue = new PriorityQueueResize<>(PriorityQueueResize.Orientation.MIN);
    for (Edge edge : edgeWeightedGraph.edges()) {
        priorityQueue.insert(edge);
    }
    UnionFind unionFind = new UnionFind(edgeWeightedGraph.vertices());
    // Subgraph with components
    EdgeWeightedGraphWithDelete componentsSubGraph = new EdgeWeightedGraphWithDelete(unionFind.count());
    while (!priorityQueue.isEmpty() && minimumSpanningTree.size() < edgeWeightedGraph.vertices() - 1) {
        Edge edge = priorityQueue.deleteTop();
        int vertex1 = edge.either();
        int vertex2 = edge.other(vertex1);
        // Ineligible edges are never critical edges
        if (unionFind.connected(vertex1, vertex2)) {
            continue;
        }
        // Get next equal-weight edge block
        double currentWeight = edge.weight();
        HashSet<Edge> equalWeightEdges = new HashSet<>();
        equalWeightEdges.add(edge);
        while (!priorityQueue.isEmpty() && priorityQueue.peek().weight() == currentWeight) {
            equalWeightEdges.add(priorityQueue.deleteTop());
        }
        if (equalWeightEdges.size() == 1) {
            // There is no cycle, so this is a critical edge
            criticalEdges.enqueue(edge);
            unionFind.union(vertex1, vertex2);
            minimumSpanningTree.enqueue(edge);
            continue;
        }
        List<Edge> edgesToAddToComponentsSubGraph = new ArrayList<>();
        // Map to make the mapping between edges in the components subgraph and the original graph
        int averageMapListSize = Math.max(2, equalWeightEdges.size() / 20);
        SeparateChainingHashTable<Edge, Edge> subGraphToGraphEdgeMap = new SeparateChainingHashTable<>(equalWeightEdges.size(), averageMapListSize);
        HashSet<Integer> verticesInSubGraph = new HashSet<>();
        // Generate subgraph with the current components
        for (Edge edgeInCurrentBlock : equalWeightEdges.keys()) {
            vertex1 = edgeInCurrentBlock.either();
            vertex2 = edgeInCurrentBlock.other(vertex1);
            int component1 = unionFind.find(vertex1);
            int component2 = unionFind.find(vertex2);
            Edge subGraphEdge = new Edge(component1, component2, currentWeight);
            edgesToAddToComponentsSubGraph.add(subGraphEdge);
            subGraphToGraphEdgeMap.put(subGraphEdge, edgeInCurrentBlock);
            verticesInSubGraph.add(component1);
            verticesInSubGraph.add(component2);
        }
        for (Edge edgeToAddToComponentSubGraph : edgesToAddToComponentsSubGraph) {
            componentsSubGraph.addEdge(edgeToAddToComponentSubGraph);
        }
        // Run DFS to check if there is a cycle. Any edges in the cycle are non-critical.
        // Every edge in the original graph will be visited by a DFS at most once.
        HashSet<Edge> nonCriticalEdges = new HashSet<>();
        // Use a different constructor for EdgeWeightedCycle to avoid O(E * V) runtime
        EdgeWeightedCycle edgeWeightedCycle = new EdgeWeightedCycle(componentsSubGraph, verticesInSubGraph);
        if (edgeWeightedCycle.hasCycle()) {
            for (Edge edgeInCycle : edgeWeightedCycle.cycle()) {
                Edge edgeInGraph = subGraphToGraphEdgeMap.get(edgeInCycle);
                nonCriticalEdges.add(edgeInGraph);
            }
        }
        // Clear components subgraph edges
        for (Edge edgeToAddToComponentSubGraph : edgesToAddToComponentsSubGraph) {
            componentsSubGraph.deleteEdge(edgeToAddToComponentSubGraph);
        }
        // Add all edges that belong to an MST to the MST
        for (Edge edgeInCurrentBlock : equalWeightEdges.keys()) {
            if (!nonCriticalEdges.contains(edgeInCurrentBlock)) {
                criticalEdges.enqueue(edgeInCurrentBlock);
            }
            vertex1 = edgeInCurrentBlock.either();
            vertex2 = edgeInCurrentBlock.other(vertex1);
            if (!unionFind.connected(vertex1, vertex2)) {
                unionFind.union(vertex1, vertex2);
                // Add edge to the minimum spanning tree
                minimumSpanningTree.enqueue(edge);
            }
        }
    }
    return criticalEdges;
}
Also used : PriorityQueueResize(chapter2.section4.PriorityQueueResize) ArrayList(java.util.ArrayList) UnionFind(chapter1.section5.UnionFind) SeparateChainingHashTable(chapter3.section4.SeparateChainingHashTable) Queue(chapter1.section3.Queue) HashSet(chapter3.section5.HashSet)

Example 20 with Edge

use of chapter4.section3.Edge in project algorithms-sedgewick-wayne by reneargento.

the class Exercise41_OddLengthDirectedCycle method hasOddLengthDirectedCycle.

// A digraph G has an odd-length directed cycle if and only if one (or more) of its strong components
// (when treated as an undirected graph) is nonbipartite
// Proof
// If the digraph G has an odd-length directed cycle, then this cycle will be entirely contained in one of the
// strong components. When the strong component is treated as an undirected graph, the odd-length directed cycle
// becomes an odd-length cycle.
// An undirected graph is bipartite if and only if it has no odd-length cycle.
// Suppose a strong component of G is nonbipartite (when treated as an undirected graph). This means that there is
// an odd-length cycle C in the strong component, ignoring direction.
// If C is a directed cycle, then we are done.
// Otherwise, if and edge v->w is pointing in the "wrong" direction, we can replace it with an odd-length path that
// is pointing in the opposite direction (which preserves the parity of the number of edges in the cycle).
// To see how, note that there exists a directed path P from w to v because v and w are in the same strong component.
// If P has odd length, then we replace edge v->w by P; if P has even length, then this path P combined with
// v->w is an odd-length cycle.
// O(V + E)
public boolean hasOddLengthDirectedCycle(Digraph digraph) {
    KosarajuSharirSCC kosarajuSharirSCC = new KosarajuSharirSCC(digraph);
    Set<Integer>[] strongComponents = (Set<Integer>[]) new HashSet[kosarajuSharirSCC.count()];
    for (int scc = 0; scc < strongComponents.length; scc++) {
        strongComponents[scc] = new HashSet<>();
    }
    for (int vertex = 0; vertex < digraph.vertices(); vertex++) {
        int strongComponentId = kosarajuSharirSCC.id(vertex);
        strongComponents[strongComponentId].add(vertex);
    }
    for (int scc = 0; scc < strongComponents.length; scc++) {
        // Uses optimized graph to make the algorithm O(V + E) instead of O(V^2)
        // (No need to initialize all adjacency lists for the subGraphs)
        OptimizedGraph subGraph = new OptimizedGraph(digraph.vertices());
        for (int vertex : strongComponents[scc]) {
            for (int neighbor : digraph.adjacent(vertex)) {
                if (strongComponents[scc].contains(neighbor)) {
                    subGraph.addEdge(vertex, neighbor);
                }
            }
        }
        TwoColor twoColor = new TwoColor(subGraph);
        if (!twoColor.isBipartite()) {
            return true;
        }
    }
    return false;
}
Also used : TwoColor(chapter4.section1.TwoColor) HashSet(java.util.HashSet) Set(java.util.Set) OptimizedGraph(chapter4.section1.OptimizedGraph)

Aggregations

Edge (boofcv.alg.segmentation.fh04.SegmentFelzenszwalbHuttenlocher04.Edge)18 GrayF32 (boofcv.struct.image.GrayF32)4 GrayU8 (boofcv.struct.image.GrayU8)4 FastQueue (org.ddogleg.struct.FastQueue)2 Test (org.junit.Test)2 Queue (chapter1.section3.Queue)1 UnionFind (chapter1.section5.UnionFind)1 PriorityQueueResize (chapter2.section4.PriorityQueueResize)1 SeparateChainingHashTable (chapter3.section4.SeparateChainingHashTable)1 HashSet (chapter3.section5.HashSet)1 OptimizedGraph (chapter4.section1.OptimizedGraph)1 TwoColor (chapter4.section1.TwoColor)1 Edge (chapter4.section3.Edge)1 EdgeWeightedGraph (chapter4.section3.EdgeWeightedGraph)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1