fix hough_circle params

This commit is contained in:
John Cupitt 2014-04-01 18:54:00 +01:00
parent 9d3311468c
commit 59b36f8351
4 changed files with 67 additions and 55 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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:
*

View File

@ -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;
}
/**