diff --git a/TODO b/TODO index bea70776..cf3e4800 100644 --- a/TODO +++ b/TODO @@ -6,20 +6,6 @@ -- vips_hough_circle() params need fixing - - we need to give a "scale" param which sets width/height of acc as a - factor of original - - min_radius / max_radius set range of circles to search for - - number of bands in acc image is range / scale - - width/height need to move out of hough.c into hough_line.c: they only make - sense for that param space - - - - ink to vec etc must have a way to give a complex constant eg. drawink needs a --ink_imag option with the imaginary components of the diff --git a/libvips/arithmetic/hough_circle.c b/libvips/arithmetic/hough_circle.c index cb59b07e..7d0fc0ab 100644 --- a/libvips/arithmetic/hough_circle.c +++ b/libvips/arithmetic/hough_circle.c @@ -61,6 +61,42 @@ typedef VipsHoughClass VipsHoughCircleClass; G_DEFINE_TYPE( VipsHoughCircle, vips_hough_circle, VIPS_TYPE_HOUGH ); +/* Smaller circles have fewer pixels and therefore fewer votes. Scale bands by + * the ratio of circumference, so all radii get equal weight. + */ +static void +vips_hough_circle_normalise( VipsHoughCircle *hough_circle ) +{ + VipsHough *hough = (VipsHough *) hough_circle; + + int max_radius = hough_circle->max_radius; + int min_radius = hough_circle->min_radius; + int scale = hough_circle->scale; + int bands = hough_circle->bands; + int width = hough_circle->width; + int height = hough_circle->height; + + double max_circumference = 2 * VIPS_PI * max_radius; + + int b; + + for( b = 0; b < bands; b++ ) { + int radius = b * scale + min_radius; + double circumference = 2 * VIPS_PI * radius; + double ratio = max_circumference / circumference; + + int x, y; + guint *q; + + q = b + (guint *) VIPS_IMAGE_ADDR( hough->out, 0, 0 ); + for( y = 0; y < height; y++ ) { + for( x = 0; x < width; x++ ) + *q *= ratio; + q += bands; + } + } +} + static int vips_hough_circle_build( VipsObject *object ) { @@ -83,6 +119,8 @@ vips_hough_circle_build( VipsObject *object ) build( object ) ) return( -1 ); + vips_hough_circle_normalise( hough_circle ); + return( 0 ); } @@ -240,7 +278,14 @@ vips_hough_circle_init( VipsHoughCircle *hough_circle ) * @min_radius: smallest radius to search for * @max_radius: largest radius to search for * - * See also: + * Find the circular Hough transform of an image. @in must be one band, with + * non-zero pixels for image edges. @out is three-band, with the third channel + * representing the detected circle radius. + * + * + * + * + * See also: vips_hough_line(). * * Returns: 0 on success, -1 on error */