public List<PairIntArray> findEdges() {
        // DFS search for sequential neighbors.
        Stack<PairInt> stack = new Stack<PairInt>();
        int thresh0 = 1;
        for (int i = 0; i < img.getWidth(); i++) {
            for (int j = 0; j < img.getHeight(); j++) {
                //for now, choosing to look only at the blue
                int bPix = img.getValue(i, j);
                if (bPix >= thresh0) {
                    stack.add(new PairInt(i, j));
                }
            }
        }
        numberOfPixelsAboveThreshold = stack.size();
        log.log(Level.FINE, "Number of pixels that exceed threshhold={0}", 
            Long.toString(numberOfPixelsAboveThreshold));
        List<PairIntArray> output = new ArrayList<PairIntArray>();
        int[] uNodeEdgeIdx = new int[img.getWidth() * img.getHeight()];
        Arrays.fill(uNodeEdgeIdx, -1);
        while (!stack.isEmpty()) {
            PairInt uNode = stack.pop();
            int uX = uNode.getX();
            int uY = uNode.getY();
            int uIdx = (uY * img.getWidth()) + uX;
            boolean foundNeighbor = false;
            // for each neighbor v of u
            for (int vX = (uX - 1); vX < (uX + 2); vX++) {
                if (foundNeighbor) {
                    break;
                }
                if (vX < 0 || vX > (img.getWidth() - 1)) {
                    continue;
                }
                for (int vY = (uY - 1); vY < (uY + 2); vY++) {
                    if (vY < 0 || vY > (img.getHeight() - 1)) {
                        continue;
                    }
                    int vIdx = (vY * img.getWidth()) + vX;
                    if (uNodeEdgeIdx[vIdx] != -1 || (uIdx == vIdx)) {
                        continue;
                    }
                    if (img.getValue(vX, vY) < thresh0) {
                        continue;
                    }
                    // if u is not in an edge already, create a new one
                    if (uNodeEdgeIdx[uIdx] == -1) {
                        PairIntArray edge = new PairIntArray();
                        edge.add(uX, uY);
                        uNodeEdgeIdx[uIdx] = output.size();
                        output.add(edge);                        
                    }
                    // keep the curve points ordered
                    // add v to the edge u if u is the last node in it's edge
                    PairIntArray appendToNode = output.get(uNodeEdgeIdx[uIdx]);
                    int aIdx = appendToNode.getN() - 1;
                    if ((appendToNode.getX(aIdx) != uX) || 
                        (appendToNode.getY(aIdx) != uY)) {
                        continue;
                    }
                    appendToNode.add(vX, vY);
                    uNodeEdgeIdx[vIdx] = uNodeEdgeIdx[uIdx];
                    //TODO: do we only want 1 neighbor from the 9 as a continuation?
                    // yes for now, but this requires edges be only 1 pixel wide
                   // inserting back at the top of the stack assures that the 
                   // search continues next from an associated point
                   stack.add(new PairInt(vX, vY));
                   foundNeighbor = true;
                   break;
                }
            }
        }
        log.fine(output.size() + " edges after DFS");
        int nIterMax = 100;
        int n, sz, lastSize;
        // count the number of points in edges
        long sum = countPixelsInEdges(output);
        log.log(Level.FINE, 
            "==> {0} pixels are in edges out of {1} pixels > threshhold", 
            new Object[]{Long.toString(sum), 
                Long.toString(numberOfPixelsAboveThreshold)});
        log.log(Level.FINE, "there are {0} edges", 
            Integer.toString(output.size()));
        output = mergeAdjacentEndPoints(output);
        log.log(Level.FINE, "{0} edges after merge adjacent", 
            Integer.toString(output.size()));
        /*
        //not necessary now that lines from CannyEdgeFilter are 1 pix width.
        MiscellaneousCurveHelper ch = new MiscellaneousCurveHelper();
        n = 0;
        sz = output.size();
        lastSize = Integer.MAX_VALUE;
        while ((sz < lastSize) && (n < nIterMax)) {
            lastSize = sz;
            output = ch.pruneAndIncludeAdjacentCurves(output, img.getWidth());
            sz = output.size();
            log.log(Level.FINE, "{0}) {1} edges after prune overlapping", 
                new Object[]{Integer.toString(n), Integer.toString(sz)});
            n++;
        }
        */
        // This helps to merge edges (that is extracted curves) at adjacent 
        // points that resemble an intersection of the lines, but it's not 
        // necessarily useful if only interested in corners and not inflection
        // points because the curvature is determined correctly 
        // whether the curves are merged or not.
        output = connectClosestPointsIfCanTrim(output);
        log.fine(output.size() + " edges after connect closest");
        output = fillInGaps(output);
        log.log(Level.FINE, "{0} edges after fill in gaps", 
            new Object[]{Integer.toString(output.size())});
        //TODO:  this may need to change
        removeEdgesShorterThan(output, edgeSizeLowerLimit);
        sz = output.size();
        log.log(Level.FINE, "{0} edges after removing those shorter", 
            new Object[]{Integer.toString(sz)});
        long sum2 = countPixelsInEdges(output);
        log.log(Level.FINE, 
            "==> {0}) pixels are in edges out of {1} pixels > threshhold", 
            new Object[]{Long.toString(sum2), 
                Long.toString(numberOfPixelsAboveThreshold)});
        //pruneSpurs(output);
        adjustEdgesTowardsBrightPixels(output);
        return output;
    }
public List<PairIntArray> findEdges() {
       
        Stack<PairInt> stack = new Stack<PairInt>();
        int thresh0 = 1;
        for (int i = 0; i < img.getWidth(); i++) {
            for (int j = 0; j < img.getHeight(); j++) {
               
                int bPix = img.getValue(i, j);
                if (bPix >= thresh0) {
                    stack.add(new PairInt(i, j));
                }
            }
        }
        numberOfPixelsAboveThreshold = stack.size();
        log.log(Level.FINE, "Number of pixels that exceed threshhold={0}", 
            Long.toString(numberOfPixelsAboveThreshold));
        List<PairIntArray> output = new ArrayList<PairIntArray>();
        int[] uNodeEdgeIdx = new int[img.getWidth() * img.getHeight()];
        Arrays.fill(uNodeEdgeIdx, -1);
        while (!stack.isEmpty()) {
            PairInt uNode = stack.pop();
            int uX = uNode.getX();
            int uY = uNode.getY();
            int uIdx = (uY * img.getWidth()) + uX;
            boolean foundNeighbor = false;
           
            for (int vX = (uX - 1); vX < (uX + 2); vX++) {
                if (foundNeighbor) {
                    break;
                }
                if (vX < 0 || vX > (img.getWidth() - 1)) {
                    continue;
                }
                for (int vY = (uY - 1); vY < (uY + 2); vY++) {
                    if (vY < 0 || vY > (img.getHeight() - 1)) {
                        continue;
                    }
                    int vIdx = (vY * img.getWidth()) + vX;
                    if (uNodeEdgeIdx[vIdx] != -1 || (uIdx == vIdx)) {
                        continue;
                    }
                    if (img.getValue(vX, vY) < thresh0) {
                        continue;
                    }
                   
                    if (uNodeEdgeIdx[uIdx] == -1) {
                        PairIntArray edge = new PairIntArray();
                        edge.add(uX, uY);
                        uNodeEdgeIdx[uIdx] = output.size();
                        output.add(edge);                        
                    }
                   
                   
                    PairIntArray appendToNode = output.get(uNodeEdgeIdx[uIdx]);
                    int aIdx = appendToNode.getN() - 1;
                    if ((appendToNode.getX(aIdx) != uX) || 
                        (appendToNode.getY(aIdx) != uY)) {
                        continue;
                    }
                    appendToNode.add(vX, vY);
                    uNodeEdgeIdx[vIdx] = uNodeEdgeIdx[uIdx];
                   
                   
                  
                  
                   stack.add(new PairInt(vX, vY));
                   foundNeighbor = true;
                   break;
                }
            }
        }
        log.fine(output.size() + " edges after DFS");
        int nIterMax = 100;
        int n, sz, lastSize;
       
        long sum = countPixelsInEdges(output);
        log.log(Level.FINE, 
            "==> {0} pixels are in edges out of {1} pixels > threshhold", 
            new Object[]{Long.toString(sum), 
                Long.toString(numberOfPixelsAboveThreshold)});
        log.log(Level.FINE, "there are {0} edges", 
            Integer.toString(output.size()));
        output = mergeAdjacentEndPoints(output);
        log.log(Level.FINE, "{0} edges after merge adjacent", 
            Integer.toString(output.size()));
       
       
       
       
       
       
        output = connectClosestPointsIfCanTrim(output);
        log.fine(output.size() + " edges after connect closest");
        output = fillInGaps(output);
        log.log(Level.FINE, "{0} edges after fill in gaps", 
            new Object[]{Integer.toString(output.size())});
       
        removeEdgesShorterThan(output, edgeSizeLowerLimit);
        sz = output.size();
        log.log(Level.FINE, "{0} edges after removing those shorter", 
            new Object[]{Integer.toString(sz)});
        long sum2 = countPixelsInEdges(output);
        log.log(Level.FINE, 
            "==> {0}) pixels are in edges out of {1} pixels > threshhold", 
            new Object[]{Long.toString(sum2), 
                Long.toString(numberOfPixelsAboveThreshold)});
       
        adjustEdgesTowardsBrightPixels(output);
        return output;
    }
public list<pairintarray> findedges() { stack<pairint> stack = new stack<pairint>(); int thresh0 = 1; for (int i = 0; i < img.getwidth(); i++) { for (int j = 0; j < img.getheight(); j++) { int bpix = img.getvalue(i, j); if (bpix >= thresh0) { stack.add(new pairint(i, j)); } } } numberofpixelsabovethreshold = stack.size(); log.log(level.fine, "number of pixels that exceed threshhold={0}", long.tostring(numberofpixelsabovethreshold)); list<pairintarray> output = new arraylist<pairintarray>(); int[] unodeedgeidx = new int[img.getwidth() * img.getheight()]; arrays.fill(unodeedgeidx, -1); while (!stack.isempty()) { pairint unode = stack.pop(); int ux = unode.getx(); int uy = unode.gety(); int uidx = (uy * img.getwidth()) + ux; boolean foundneighbor = false; for (int vx = (ux - 1); vx < (ux + 2); vx++) { if (foundneighbor) { break; } if (vx < 0 || vx > (img.getwidth() - 1)) { continue; } for (int vy = (uy - 1); vy < (uy + 2); vy++) { if (vy < 0 || vy > (img.getheight() - 1)) { continue; } int vidx = (vy * img.getwidth()) + vx; if (unodeedgeidx[vidx] != -1 || (uidx == vidx)) { continue; } if (img.getvalue(vx, vy) < thresh0) { continue; } if (unodeedgeidx[uidx] == -1) { pairintarray edge = new pairintarray(); edge.add(ux, uy); unodeedgeidx[uidx] = output.size(); output.add(edge); } pairintarray appendtonode = output.get(unodeedgeidx[uidx]); int aidx = appendtonode.getn() - 1; if ((appendtonode.getx(aidx) != ux) || (appendtonode.gety(aidx) != uy)) { continue; } appendtonode.add(vx, vy); unodeedgeidx[vidx] = unodeedgeidx[uidx]; stack.add(new pairint(vx, vy)); foundneighbor = true; break; } } } log.fine(output.size() + " edges after dfs"); int nitermax = 100; int n, sz, lastsize; long sum = countpixelsinedges(output); log.log(level.fine, "==> {0} pixels are in edges out of {1} pixels > threshhold", new object[]{long.tostring(sum), long.tostring(numberofpixelsabovethreshold)}); log.log(level.fine, "there are {0} edges", integer.tostring(output.size())); output = mergeadjacentendpoints(output); log.log(level.fine, "{0} edges after merge adjacent", integer.tostring(output.size())); output = connectclosestpointsifcantrim(output); log.fine(output.size() + " edges after connect closest"); output = fillingaps(output); log.log(level.fine, "{0} edges after fill in gaps", new object[]{integer.tostring(output.size())}); removeedgesshorterthan(output, edgesizelowerlimit); sz = output.size(); log.log(level.fine, "{0} edges after removing those shorter", new object[]{integer.tostring(sz)}); long sum2 = countpixelsinedges(output); log.log(level.fine, "==> {0}) pixels are in edges out of {1} pixels > threshhold", new object[]{long.tostring(sum2), long.tostring(numberofpixelsabovethreshold)}); adjustedgestowardsbrightpixels(output); return output; }