From 59b36f8351c0fdfa2f340b6ab49b9d143e853233 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 1 Apr 2014 18:54:00 +0100 Subject: [PATCH] fix hough_circle params --- libvips/arithmetic/hough.c | 18 +---------- libvips/arithmetic/hough.h | 6 ---- libvips/arithmetic/hough_circle.c | 51 +++++++++++++++++-------------- libvips/arithmetic/hough_line.c | 47 ++++++++++++++++++++++------ 4 files changed, 67 insertions(+), 55 deletions(-) diff --git a/libvips/arithmetic/hough.c b/libvips/arithmetic/hough.c index 83e470d6..5b71280c 100644 --- a/libvips/arithmetic/hough.c +++ b/libvips/arithmetic/hough.c @@ -56,7 +56,7 @@ vips_hough_new_accumulator( VipsHough *hough ) accumulator = vips_image_new_buffer(); vips_image_pipelinev( accumulator, - VIPS_DEMAND_STYLE_ANY, statistic->in, NULL ); + VIPS_DEMAND_STYLE_ANY, statistic->ready, NULL ); if( class->init_accumulator( hough, accumulator ) || vips_image_write_prepare( accumulator ) ) { @@ -187,25 +187,9 @@ vips_hough_class_init( VipsHoughClass *class ) VIPS_ARGUMENT_REQUIRED_OUTPUT, G_STRUCT_OFFSET( VipsHough, out ) ); - VIPS_ARG_INT( class, "width", 110, - _( "Width" ), - _( "horizontal size of parameter space" ), - VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsHough, width ), - 1, 100000, 256 ); - - VIPS_ARG_INT( class, "height", 111, - _( "Height" ), - _( "Vertical size of parameter space" ), - VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsHough, height ), - 1, 100000, 256 ); - } static void vips_hough_init( VipsHough *hough ) { - hough->width = 256; - hough->height = 256; } diff --git a/libvips/arithmetic/hough.h b/libvips/arithmetic/hough.h index 095ffe87..2691fb7f 100644 --- a/libvips/arithmetic/hough.h +++ b/libvips/arithmetic/hough.h @@ -64,12 +64,6 @@ typedef void (*VipsHoughVote)( VipsHough *hough, struct _VipsHough { VipsStatistic parent_instance; - /* Size of parameter space. All have at least two dimensions, some - * subclasses add a third. - */ - int width; - int height; - /* Sum the thread accumulators to here. */ VipsImage *out; diff --git a/libvips/arithmetic/hough_circle.c b/libvips/arithmetic/hough_circle.c index a7ebb409..cb59b07e 100644 --- a/libvips/arithmetic/hough_circle.c +++ b/libvips/arithmetic/hough_circle.c @@ -47,8 +47,12 @@ typedef struct _VipsHoughCircle { VipsHough parent_instance; + int scale; int min_radius; int max_radius; + + int width; + int height; int bands; } VipsHoughCircle; @@ -61,18 +65,20 @@ static int vips_hough_circle_build( VipsObject *object ) { VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); + VipsStatistic *statistic = (VipsStatistic *) object; VipsHoughCircle *hough_circle = (VipsHoughCircle *) object; + int range = hough_circle->max_radius - hough_circle->min_radius; - if( !vips_object_argument_isset( object, "bands" ) ) - hough_circle->bands = 1 + hough_circle->max_radius - - hough_circle->min_radius; - - if( hough_circle->min_radius > hough_circle->max_radius ) { + if( range <= 0 ) { vips_error( class->nickname, "%s", _( "parameters out of range" ) ); return( -1 ); } + hough_circle->width = statistic->in->Xsize / hough_circle->scale; + hough_circle->height = statistic->in->Ysize / hough_circle->scale; + hough_circle->bands = 1 + range / hough_circle->scale; + if( VIPS_OBJECT_CLASS( vips_hough_circle_parent_class )-> build( object ) ) return( -1 ); @@ -86,7 +92,7 @@ vips_hough_circle_init_accumulator( VipsHough *hough, VipsImage *accumulator ) VipsHoughCircle *hough_circle = (VipsHoughCircle *) hough; vips_image_init_fields( accumulator, - hough->width, hough->height, hough_circle->bands, + hough_circle->width, hough_circle->height, hough_circle->bands, VIPS_FORMAT_UINT, VIPS_CODING_NONE, VIPS_INTERPRETATION_MATRIX, 1.0, 1.0 ); @@ -104,7 +110,7 @@ vips_hough_circle_vote_point( VipsImage *image, int x, int y, void *client ) g_assert( x >= 0 ); g_assert( y >= 0 ); g_assert( x < image->Xsize ); - g_assert( y < image->Xsize ); + g_assert( y < image->Ysize ); g_assert( r >= 0 ); g_assert( r < image->Bands ); @@ -144,19 +150,20 @@ static void vips_hough_circle_vote( VipsHough *hough, VipsImage *accumulator, int x, int y ) { VipsHoughCircle *hough_circle = (VipsHoughCircle *) hough; - VipsStatistic *statistic = (VipsStatistic *) hough; int min_radius = hough_circle->min_radius; int max_radius = hough_circle->max_radius; int range = max_radius - min_radius; - int cx = x * accumulator->Xsize / statistic->ready->Xsize; - int cy = y * accumulator->Ysize / statistic->ready->Ysize; + int cx = x / hough_circle->scale; + int cy = y / hough_circle->scale; - int r; + int rb; g_assert( range >= 0 ); - for( r = min_radius; r <= max_radius; r++ ) { - int rb = (r - min_radius) * hough_circle->bands / (range + 1); + for( rb = 0; rb < hough_circle->bands; rb++ ) { + /* r needs to be in scaled down image space. + */ + int r = rb + min_radius / hough_circle->scale; VipsDrawScanline draw_scanline; @@ -190,12 +197,12 @@ vips_hough_circle_class_init( VipsHoughClass *class ) hclass->init_accumulator = vips_hough_circle_init_accumulator; hclass->vote = vips_hough_circle_vote; - VIPS_ARG_INT( class, "bands", 119, - _( "Bands" ), - _( "Number of bands in parameter space" ), + VIPS_ARG_INT( class, "scale", 119, + _( "Scale" ), + _( "Scale down dimensions by this factor" ), VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsHoughCircle, bands ), - 1, 100000, 10 ); + G_STRUCT_OFFSET( VipsHoughCircle, scale ), + 1, 100000, 3 ); VIPS_ARG_INT( class, "min_radius", 120, _( "Min radius" ), @@ -204,7 +211,7 @@ vips_hough_circle_class_init( VipsHoughClass *class ) G_STRUCT_OFFSET( VipsHoughCircle, min_radius ), 1, 100000, 10 ); - VIPS_ARG_INT( class, "max_radius", 121, + VIPS_ARG_INT( class, "max_radius", 120, _( "Max radius" ), _( "Largest radius to search for" ), VIPS_ARGUMENT_OPTIONAL_INPUT, @@ -216,9 +223,9 @@ vips_hough_circle_class_init( VipsHoughClass *class ) static void vips_hough_circle_init( VipsHoughCircle *hough_circle ) { + hough_circle->scale = 3; hough_circle->min_radius = 10; hough_circle->max_radius = 20; - hough_circle->bands = 10; } /** @@ -229,11 +236,9 @@ vips_hough_circle_init( VipsHoughCircle *hough_circle ) * * Optional arguments: * - * @width: horizontal size of parameter space - * @height: vertical size of parameter space + * @scale: scale down dimensions by this much * @min_radius: smallest radius to search for * @max_radius: largest radius to search for - * @bands: number of bands (radii) in accumulator image * * See also: * diff --git a/libvips/arithmetic/hough_line.c b/libvips/arithmetic/hough_line.c index 57ab3710..dcb862e5 100644 --- a/libvips/arithmetic/hough_line.c +++ b/libvips/arithmetic/hough_line.c @@ -46,6 +46,11 @@ typedef struct _VipsHoughLine { VipsHough parent_instance; + /* Size of parameter space. + */ + int width; + int height; + /* LUT for this transform. */ double *sin; @@ -59,16 +64,16 @@ G_DEFINE_TYPE( VipsHoughLine, vips_hough_line, VIPS_TYPE_HOUGH ); static int vips_hough_line_build( VipsObject *object ) { - VipsHough *hough = (VipsHough *) object; VipsHoughLine *hough_line = (VipsHoughLine *) object; + int width = hough_line->width; int i; - if( !(hough_line->sin = VIPS_ARRAY( object, hough->width, double )) ) + if( !(hough_line->sin = VIPS_ARRAY( object, width, double )) ) return( -1 ); - for( i = 0; i < hough->width; i++ ) - hough_line->sin[i] = sin( 2 * VIPS_PI * i / hough->width ); + for( i = 0; i < width; i++ ) + hough_line->sin[i] = sin( 2 * VIPS_PI * i / width ); if( VIPS_OBJECT_CLASS( vips_hough_line_parent_class )->build( object ) ) return( -1 ); @@ -79,8 +84,10 @@ vips_hough_line_build( VipsObject *object ) static int vips_hough_line_init_accumulator( VipsHough *hough, VipsImage *accumulator ) { + VipsHoughLine *hough_line = (VipsHoughLine *) hough; + vips_image_init_fields( accumulator, - hough->width, hough->height, 1, + hough_line->width, hough_line->height, 1, VIPS_FORMAT_UINT, VIPS_CODING_NONE, VIPS_INTERPRETATION_MATRIX, 1.0, 1.0 ); @@ -97,16 +104,18 @@ vips_hough_line_vote( VipsHough *hough, VipsImage *accumulator, int x, int y ) VipsStatistic *statistic = (VipsStatistic *) hough; double xd = (double) x / statistic->ready->Xsize; double yd = (double) y / statistic->ready->Ysize; + int width = hough_line->width; + int height = hough_line->height; int i; - for( i = 0; i < hough->width; i++ ) { - int i90 = (i + hough->width / 4) % hough->width; + for( i = 0; i < width; i++ ) { + int i90 = (i + width / 4) % width; double r = xd * hough_line->sin[i90] + yd * hough_line->sin[i]; - int ri = hough->height * r; + int ri = height * r; if( ri >= 0 && - ri < hough->height ) + ri < height ) *VIPS_IMAGE_ADDR( accumulator, i, ri ) += 1; } } @@ -114,9 +123,13 @@ vips_hough_line_vote( VipsHough *hough, VipsImage *accumulator, int x, int y ) static void vips_hough_line_class_init( VipsHoughClass *class ) { + GObjectClass *gobject_class = (GObjectClass *) class; VipsObjectClass *object_class = (VipsObjectClass *) class; VipsHoughClass *hclass = (VipsHoughClass *) class; + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; + object_class->nickname = "hough_line"; object_class->description = _( "find hough line transform" ); object_class->build = vips_hough_line_build; @@ -124,11 +137,27 @@ vips_hough_line_class_init( VipsHoughClass *class ) hclass->init_accumulator = vips_hough_line_init_accumulator; hclass->vote = vips_hough_line_vote; + VIPS_ARG_INT( class, "width", 110, + _( "Width" ), + _( "horizontal size of parameter space" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsHoughLine, width ), + 1, 100000, 256 ); + + VIPS_ARG_INT( class, "height", 111, + _( "Height" ), + _( "Vertical size of parameter space" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsHoughLine, height ), + 1, 100000, 256 ); + } static void vips_hough_line_init( VipsHoughLine *hough_line ) { + hough_line->width = 256; + hough_line->height = 256; } /**