added im_segment()

This commit is contained in:
John Cupitt 2009-09-29 13:45:58 +00:00
parent ce4ed9d2bf
commit 7164a2abec
4 changed files with 81 additions and 5 deletions

View File

@ -49,6 +49,7 @@
and else parts
- better im_check() functions
- added im_flood_other() as start of simple segmentation operator
- added im_segment()
25/3/09 started 7.18.0
- revised version numbers

View File

@ -620,8 +620,9 @@ int im_flood( IMAGE *, int, int, PEL *, Rect * );
int im_flood_blob( IMAGE *, int, int, PEL *, Rect * );
int im_flood_blob_copy( IMAGE *in, IMAGE *out, int x, int y, PEL *ink );
int im_flood_other( IMAGE *mask, IMAGE *test, int x, int y, int serial );
int im_flood_other_copy( IMAGE *mask, IMAGE *out,
IMAGE *test, int x, int y, int serial );
int im_flood_other_copy( IMAGE *mask, IMAGE *test, IMAGE *out,
int x, int y, int serial );
int im_segment( IMAGE *test, IMAGE *mask, int *segments );
int im_lineset( IMAGE *in, IMAGE *out, IMAGE *mask, IMAGE *ink,
int n, int *x1v, int *y1v, int *x2v, int *y2v );

View File

@ -275,7 +275,7 @@ im_flood_other( IMAGE *mask, IMAGE *test, int x, int y, int serial )
if( im_check_known_coded( "im_flood_other", test ) ||
im_check_uncoded( "im_flood_other", mask ) ||
im_check_mono( "im_flood_other", mask ) ||
im_check_int( "im_flood_other", mask ) ||
im_check_format( "im_flood_other", mask, IM_BANDFMT_INT ) ||
im_check_same_size( "im_flood_other", test, mask ) )
return( -1 );
@ -315,8 +315,8 @@ im_flood_other( IMAGE *mask, IMAGE *test, int x, int y, int serial )
* automatically. Maybe nip could do it if it sees a RW image argument?
*/
int
im_flood_other_copy( IMAGE *mask, IMAGE *out,
IMAGE *test, int x, int y, int serial )
im_flood_other_copy( IMAGE *mask, IMAGE *test, IMAGE *out,
int x, int y, int serial )
{
IMAGE *t;
@ -329,4 +329,46 @@ im_flood_other_copy( IMAGE *mask, IMAGE *out,
return( 0 );
}
/* Now: segment with im_flood_other().
*/
int
im_segment( IMAGE *test, IMAGE *mask, int *segments )
{
IMAGE *t[2];
int serial;
int x, y;
/* Create the mask image.
*/
if( im_open_local_array( mask, t, 2, "im_segment", "p" ) ||
im_black( t[0], test->Xsize, test->Ysize, 1 ) ||
im_clip2fmt( t[0], t[1], IM_BANDFMT_INT ) )
return( 0 );
/* Search the mask image, flooding as we find zero pixels.
*/
if( im_incheck( t[1] ) )
return( -1 );
serial = 0;
for( y = 0; y < test->Ysize; y++ )
for( x = 0; x < test->Xsize; x++ ) {
int *m = (int *) t[1]->data + x + y * test->Ysize;
if( !*m ) {
if( im_flood_other( t[1], test, x, y, serial ) )
return( -1 );
serial += 1;
}
}
/* Copy result to mask.
*/
if( im_copy( t[1], mask ) )
return( -1 );
if( segments )
*segments = serial;
return( 0 );
}

View File

@ -295,6 +295,37 @@ static im_function flood_other_copy_desc = {
flood_other_copy_args /* Arg list */
};
/* Args for im_segment().
*/
static im_arg_desc segment_args[] = {
IM_INPUT_IMAGE( "test" ),
IM_OUTPUT_IMAGE( "mask" ),
IM_OUTPUT_INT( "segments" )
};
/* Call im_segment() via arg vector.
*/
static int
segment_vec( im_object *argv )
{
IMAGE *test = argv[1];
IMAGE *mask = argv[0];
int *serial = (int *) argv[5];
return( im_segment( test, mask, serial ) );
}
/* Description of im_segment().
*/
static im_function segment_desc = {
"im_segment", /* Name */
"number continuous regions in an image",
0, /* Flags */
segment_vec, /* Dispatch function */
IM_NUMBER( segment_args ),/* Size of arg list */
segment_args /* Arg list */
};
/* To do:
* these all need some kind of pel type
*
@ -313,6 +344,7 @@ static im_function *inplace_list[] = {
&circle_desc,
&flood_blob_copy_desc,
&flood_other_copy_desc,
&segment_desc,
&insertplace_desc,
&line_desc,
&lineset_desc