diff --git a/libvips/arithmetic/hough_circle.c b/libvips/arithmetic/hough_circle.c index bedd9601..86c76a50 100644 --- a/libvips/arithmetic/hough_circle.c +++ b/libvips/arithmetic/hough_circle.c @@ -2,6 +2,8 @@ * * 7/3/14 * - from hough_line.c + * 2/1/18 + * - 20% speedup */ /* @@ -141,37 +143,24 @@ vips_hough_circle_init_accumulator( VipsHough *hough, VipsImage *accumulator ) return( 0 ); } -static inline void -vips_hough_circle_vote_point( VipsImage *image, int x, int y, void *client ) -{ - guint *q = (guint *) VIPS_IMAGE_ADDR( image, x, y ); - int r = *((int *) client); - - g_assert( image->BandFmt == VIPS_FORMAT_UINT ); - g_assert( x >= 0 ); - g_assert( y >= 0 ); - g_assert( x < image->Xsize ); - g_assert( y < image->Ysize ); - g_assert( r >= 0 ); - g_assert( r < image->Bands ); - - q[r] += 1; -} - /* Vote endpoints, with clip. */ static void vips_hough_circle_vote_endpoints_clip( VipsImage *image, int y, int x1, int x2, int quadrant, void *client ) { + int r = *((int *) client); + guint *line = (guint *) VIPS_IMAGE_ADDR( image, 0, y ) + r; + int b = image->Bands; + if( y >= 0 && y < image->Ysize ) { if( x1 >=0 && x1 < image->Xsize ) - vips_hough_circle_vote_point( image, x1, y, client ); + line[x1 * b] += 1; if( x2 >=0 && x2 < image->Xsize ) - vips_hough_circle_vote_point( image, x2, y, client ); + line[x2 * b] += 1; } } @@ -181,8 +170,12 @@ static void vips_hough_circle_vote_endpoints_noclip( VipsImage *image, int y, int x1, int x2, int quadrant, void *client ) { - vips_hough_circle_vote_point( image, x1, y, client ); - vips_hough_circle_vote_point( image, x2, y, client ); + int r = *((int *) client); + guint *line = (guint *) VIPS_IMAGE_ADDR( image, 0, y ) + r; + int b = image->Bands; + + line[x1 * b] += 1; + line[x2 * b] += 1; } /* Cast votes for all possible circles passing through x, y. @@ -211,7 +204,7 @@ vips_hough_circle_vote( VipsHough *hough, VipsImage *accumulator, int x, int y ) cy - r >= 0 && cy + r < accumulator->Ysize ) draw_scanline = vips_hough_circle_vote_endpoints_noclip; - else + else draw_scanline = vips_hough_circle_vote_endpoints_clip; vips__draw_circle_direct( accumulator,