public void setConnectRule( ConnectRule rule ) { if( rule != tracer.getConnectRule() ) tracer = new ContourTracer(rule); }
private boolean searchOne4() { if( checkOne(indexBinary + offsetsBinary[dir])) return true; dir = (dir+1)%4; if( checkOne(indexBinary + offsetsBinary[dir])) return true; dir = (dir+1)%4; if( checkOne(indexBinary + offsetsBinary[dir])) return true; dir = (dir+1)%4; if( checkOne(indexBinary + offsetsBinary[dir])) return true; dir = (dir+1)%4; return false; }
/** * Searches in a circle around the current point in a clock-wise direction for the first black pixel. */ private boolean searchOne() { // for( int i = 0; i < ruleN; i++ ) { // if( checkBlack(indexBinary + offsetsBinary[dir])) // return true; // dir = (dir+1)%ruleN; // } // return false; // Unrolling here results in about a 10% speed up if( ruleN == 4 ) return searchOne4(); else return searchOne8(); }
add(x,y); if( !searchOne() ) { return; } else { initialDir = dir; moveToNext(); dir = nextDirection[dir]; searchOne(); if( x == initialX && y == initialY && dir == initialDir ) { add(x, y); moveToNext(); dir = nextDirection[dir];
/** * Step 2: If the pixel below is unmarked and white then it must be an internal contour * Same behavior it the pixel in question has been labeled or not already */ private void handleStep2(GrayS32 labeled, int label) { // if the blob is not labeled and in this state it cannot be against the left side of the image if( label == 0 ) label = labeled.data[indexOut-1]; ContourPacked c = contours.get(label-1); c.internalIndexes.add( packedPoints.size() ); packedPoints.grow(); tracer.setMaxContourSize(saveInternalContours?maxContourSize:0); tracer.trace(label,x,y,false); // See if the inner contour exceeded the maximum or minimum size. If so free its points if( packedPoints.sizeOfTail() >= maxContourSize || packedPoints.sizeOfTail() < minContourSize ) { packedPoints.removeTail(); packedPoints.grow(); } }
/** * Configures the algorithm. * * @param rule Connectivity rule. 4 or 8 */ public LinearContourLabelChang2004( ConnectRule rule ) { tracer = new ContourTracer(rule); }
public ConnectRule getConnectRule() { return tracer.getConnectRule(); } }
packedPoints.reset(); contours.reset(); tracer.setInputs(binary,labeled, packedPoints);
/** * Step 1: If the pixel is unlabeled and the pixel above is not one, then it * must be an external contour of a newly encountered blob. */ private void handleStep1() { ContourPacked c = contours.grow(); c.reset(); c.id = contours.size(); tracer.setMaxContourSize(maxContourSize); // save the set index for this contour and declare memory for it c.externalIndex = packedPoints.size(); packedPoints.grow(); c.internalIndexes.reset(); tracer.trace(contours.size(),x,y,true); // Keep track that this was a contour, but free up all the points used in defining it if( packedPoints.sizeOfTail() >= maxContourSize || packedPoints.sizeOfTail() < minContourSize ) { packedPoints.removeTail(); packedPoints.grow(); } }
private boolean searchOne8() { if( checkOne(indexBinary + offsetsBinary[dir])) return true; dir = (dir+1)%8; if( checkOne(indexBinary + offsetsBinary[dir])) return true; dir = (dir+1)%8; if( checkOne(indexBinary + offsetsBinary[dir])) return true; dir = (dir+1)%8; if( checkOne(indexBinary + offsetsBinary[dir])) return true; dir = (dir+1)%8; if( checkOne(indexBinary + offsetsBinary[dir])) return true; dir = (dir+1)%8; if( checkOne(indexBinary + offsetsBinary[dir])) return true; dir = (dir+1)%8; if( checkOne(indexBinary + offsetsBinary[dir])) return true; dir = (dir+1)%8; if( checkOne(indexBinary + offsetsBinary[dir])) return true; dir = (dir+1)%8; return false; }