added im_segment()
This commit is contained in:
parent
ce4ed9d2bf
commit
7164a2abec
@ -49,6 +49,7 @@
|
|||||||
and else parts
|
and else parts
|
||||||
- better im_check() functions
|
- better im_check() functions
|
||||||
- added im_flood_other() as start of simple segmentation operator
|
- added im_flood_other() as start of simple segmentation operator
|
||||||
|
- added im_segment()
|
||||||
|
|
||||||
25/3/09 started 7.18.0
|
25/3/09 started 7.18.0
|
||||||
- revised version numbers
|
- revised version numbers
|
||||||
|
@ -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( IMAGE *, int, int, PEL *, Rect * );
|
||||||
int im_flood_blob_copy( IMAGE *in, IMAGE *out, int x, int y, PEL *ink );
|
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( IMAGE *mask, IMAGE *test, int x, int y, int serial );
|
||||||
int im_flood_other_copy( IMAGE *mask, IMAGE *out,
|
int im_flood_other_copy( IMAGE *mask, IMAGE *test, IMAGE *out,
|
||||||
IMAGE *test, int x, int y, int serial );
|
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 im_lineset( IMAGE *in, IMAGE *out, IMAGE *mask, IMAGE *ink,
|
||||||
int n, int *x1v, int *y1v, int *x2v, int *y2v );
|
int n, int *x1v, int *y1v, int *x2v, int *y2v );
|
||||||
|
|
||||||
|
@ -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 ) ||
|
if( im_check_known_coded( "im_flood_other", test ) ||
|
||||||
im_check_uncoded( "im_flood_other", mask ) ||
|
im_check_uncoded( "im_flood_other", mask ) ||
|
||||||
im_check_mono( "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 ) )
|
im_check_same_size( "im_flood_other", test, mask ) )
|
||||||
return( -1 );
|
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?
|
* automatically. Maybe nip could do it if it sees a RW image argument?
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
im_flood_other_copy( IMAGE *mask, IMAGE *out,
|
im_flood_other_copy( IMAGE *mask, IMAGE *test, IMAGE *out,
|
||||||
IMAGE *test, int x, int y, int serial )
|
int x, int y, int serial )
|
||||||
{
|
{
|
||||||
IMAGE *t;
|
IMAGE *t;
|
||||||
|
|
||||||
@ -329,4 +329,46 @@ im_flood_other_copy( IMAGE *mask, IMAGE *out,
|
|||||||
return( 0 );
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -295,6 +295,37 @@ static im_function flood_other_copy_desc = {
|
|||||||
flood_other_copy_args /* Arg list */
|
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:
|
/* To do:
|
||||||
* these all need some kind of pel type
|
* these all need some kind of pel type
|
||||||
*
|
*
|
||||||
@ -313,6 +344,7 @@ static im_function *inplace_list[] = {
|
|||||||
&circle_desc,
|
&circle_desc,
|
||||||
&flood_blob_copy_desc,
|
&flood_blob_copy_desc,
|
||||||
&flood_other_copy_desc,
|
&flood_other_copy_desc,
|
||||||
|
&segment_desc,
|
||||||
&insertplace_desc,
|
&insertplace_desc,
|
||||||
&line_desc,
|
&line_desc,
|
||||||
&lineset_desc
|
&lineset_desc
|
||||||
|
Loading…
Reference in New Issue
Block a user