imagej-ops
imagej-ops copied to clipboard
Hough circle transforms.
Package for Hough circle transform in ops, based on Bresenham circle iteration.
To be merged after discussion with the work of @gselzer on https://github.com/imagej/imagej-ops/blob/54ba352f1f28ccf912806d8781529c1fb15f03a0/src/main/java/net/imagej/ops/segment/hough/CircleTransform.java
Example (requires imglib2-ij and imagej-ops...)
ImageJ.main( args );
final Context context = new Context();
final OpService ops = context.getService( OpService.class );
/*
* Create two simple circle.
*/
final int w = 256;
final Img< BitType > img = ops.create().img( FinalDimensions.wrap( new long[] { w, w } ), new BitType() );
final int r1 = 50;
final Point c1 = new Point( w / 2 - r1, w / 2 );
MidPointAlgorithm.set( img, c1, r1, new BitType( true ) );
final int r2 = 75;
final Point c2 = new Point( w / 2 + r2 / 2, w / 2 );
MidPointAlgorithm.set( img, c2, r2, new BitType( true ) );
/*
* Hough transform.
*/
final long minCircleRadius = 30;
final long maxCircleRadius = 100;
final long stepRadius = 3;
@SuppressWarnings( { "unchecked", "rawtypes" } )
final HoughTransformOpNoWeights< BitType > hough = ( HoughTransformOpNoWeights ) Hybrids.unaryCF( ops,
HoughTransformOpNoWeights.class,
Img.class, img,
minCircleRadius, maxCircleRadius, stepRadius );
final Img< DoubleType > voteImg = hough.calculate( img );
final ImagePlus imp = ImageJFunctions.show( img, "Two circles" );
ImageJFunctions.show( voteImg, "Vote" );
/*
* Hough detection.
*/
final double sensitivity = 5.;
@SuppressWarnings( { "rawtypes", "unchecked" } )
final HoughCircleDetectorLocalExtremaOp< DoubleType > houghDetector = ( HoughCircleDetectorLocalExtremaOp ) Functions.unary( ops,
HoughCircleDetectorLocalExtremaOp.class,
List.class, voteImg,
minCircleRadius, stepRadius, sensitivity );
final List< HoughCircle > circles = houghDetector.calculate( voteImg );
System.out.println( "Found " + circles.size() + " circles:" );
imp.setOverlay( new Overlay() );
for ( final HoughCircle circle : circles )
{
final OvalRoi roi = new OvalRoi(
circle.getDoublePosition( 0 ) - circle.getRadius(),
circle.getDoublePosition( 1 ) - circle.getRadius(),
2. * circle.getRadius(),
2. * circle.getRadius() );
imp.getOverlay().add( roi );
System.out.println( circle );
}
imp.updateAndDraw();
Output:
Found 2 circles:
(165.0,128.0) R=75.0 Sensitivity=1.1
(77.3,127.3) R=51.1 Sensitivity=3.4