test for bandrank and bandmean
This commit is contained in:
parent
b402bb173f
commit
7915308155
@ -62,7 +62,7 @@ typedef struct _VipsBandrank {
|
||||
|
||||
/* The input images.
|
||||
*/
|
||||
VipsArea *in;
|
||||
VipsArrayImage *in;
|
||||
int index; /* Pick out this one */
|
||||
} VipsBandrank;
|
||||
|
||||
@ -178,27 +178,34 @@ vips_bandrank_build( VipsObject *object )
|
||||
VipsBandrank *bandrank = (VipsBandrank *) object;
|
||||
|
||||
if( bandrank->in ) {
|
||||
int n;
|
||||
VipsImage **in = vips_array_image_get( bandrank->in, &n );
|
||||
VipsImage **band = (VipsImage **)
|
||||
vips_object_local_array( object, bandrank->in->n );
|
||||
vips_object_local_array( object, n );
|
||||
|
||||
if( bandrank->in->n == 1 )
|
||||
int i;
|
||||
|
||||
for( i = 0; i < n; i++ )
|
||||
if( vips_check_noncomplex( class->nickname, in[i] ) )
|
||||
return( -1 );
|
||||
|
||||
if( n == 1 )
|
||||
return( vips_bandary_copy( bandary ) );
|
||||
|
||||
/* We need to keep one band element for every input image
|
||||
* on the stack.
|
||||
*/
|
||||
if( sizeof( double ) * bandrank->in->n > SORT_BUFFER ) {
|
||||
if( sizeof( double ) * n > SORT_BUFFER ) {
|
||||
vips_error( class->nickname,
|
||||
"%s", _( "too many input images" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( vips__bandalike_vec( class->nickname,
|
||||
bandrank->in->data, band, bandrank->in->n, 0 ) )
|
||||
if( vips__bandalike_vec( class->nickname, in, band, n, 0 ) )
|
||||
return( -1 );
|
||||
|
||||
bandary->in = band;
|
||||
bandary->n = bandrank->in->n;
|
||||
bandary->n = n;
|
||||
bandary->out_bands = band[0]->Bands;
|
||||
|
||||
if( bandrank->index == -1 )
|
||||
@ -281,7 +288,7 @@ vips_bandrankv( VipsImage **in, VipsImage **out, int n, va_list ap )
|
||||
* image in which each band element is selected from the sorted list by the
|
||||
* @index parameter. For example, if @index
|
||||
* is zero, then each output band element will be the minimum of all the
|
||||
* corresponding input band element.
|
||||
* corresponding input band elements.
|
||||
*
|
||||
* By default, @index is -1, meaning pick the median value.
|
||||
*
|
||||
|
@ -44,7 +44,7 @@ class TestConversion(unittest.TestCase):
|
||||
|
||||
# run a function on an image and on a single pixel, the results
|
||||
# should match
|
||||
def run_cmp(self, message, im, x, y, fn):
|
||||
def run_cmp_unary(self, message, im, x, y, fn):
|
||||
a = im.getpoint(x, y)
|
||||
v1 = fn(a)
|
||||
im2 = fn(im)
|
||||
@ -53,7 +53,7 @@ class TestConversion(unittest.TestCase):
|
||||
|
||||
# run a function on a pair of images and on a pair of pixels, the results
|
||||
# should match
|
||||
def run_cmp2(self, message, left, right, x, y, fn):
|
||||
def run_cmp_binary(self, message, left, right, x, y, fn):
|
||||
a = left.getpoint(x, y)
|
||||
b = right.getpoint(x, y)
|
||||
v1 = fn(a, b)
|
||||
@ -63,20 +63,25 @@ class TestConversion(unittest.TestCase):
|
||||
|
||||
# run a function on a pair of images
|
||||
# 50,50 and 10,10 should have different values on the test image
|
||||
def run_test2(self, message, left, right, fn):
|
||||
self.run_cmp2(message, left, right, 50, 50, fn)
|
||||
self.run_cmp2(message, left, right, 10, 10, fn)
|
||||
def run_testbinary(self, message, left, right, fn):
|
||||
self.run_cmp_binary(message, left, right, 50, 50, fn)
|
||||
self.run_cmp_binary(message, left, right, 10, 10, fn)
|
||||
|
||||
# run a function on an image,
|
||||
# 50,50 and 10,10 should have different values on the test image
|
||||
def run_testunary(self, message, im, fn):
|
||||
self.run_cmp(message, im, 50, 50, fn)
|
||||
self.run_cmp(message, im, 10, 10, fn)
|
||||
self.run_cmp_unary(message, im, 50, 50, fn)
|
||||
self.run_cmp_unary(message, im, 10, 10, fn)
|
||||
|
||||
def run_unary(self, images, fn, fmt = all_formats):
|
||||
[self.run_testunary(fn.func_name + ' image', x.cast(y), fn)
|
||||
[self.run_testunary(fn.func_name + (' %s' % y), x.cast(y), fn)
|
||||
for x in images for y in fmt]
|
||||
|
||||
def run_binary(self, images, fn, fmt = all_formats):
|
||||
[self.run_testbinary(fn.func_name + (' %s %s' % (y, z)),
|
||||
x.cast(y), x.cast(z), fn)
|
||||
for x in images for y in fmt for z in fmt]
|
||||
|
||||
def setUp(self):
|
||||
im = Vips.Image.mask_ideal(100, 100, 0.5, reject = True, optical = True)
|
||||
self.colour = im * [1, 2, 3] + [2, 3, 4]
|
||||
@ -111,13 +116,36 @@ class TestConversion(unittest.TestCase):
|
||||
self.run_unary([self.colour], band_eor, fmt = int_formats)
|
||||
|
||||
def test_bandjoin(self):
|
||||
im2 = Vips.Image.bandjoin([self.colour, self.mono])
|
||||
def bandjoin(x, y):
|
||||
if isinstance(x, Vips.Image) and isinstance(y, Vips.Image):
|
||||
return x.bandjoin2(y)
|
||||
else:
|
||||
return x + y
|
||||
|
||||
self.assertEqual(im2.bands, self.colour.bands + self.mono.bands)
|
||||
v = im2.getpoint(10, 10)
|
||||
self.assertAlmostEqualObjects(v, [2, 3, 4, 3])
|
||||
v = im2.getpoint(50, 50)
|
||||
self.assertAlmostEqualObjects(v, [3, 5, 7, 5])
|
||||
self.run_binary(self.all_images, bandjoin)
|
||||
|
||||
def test_bandmean(self):
|
||||
def bandmean(x):
|
||||
if isinstance(x, Vips.Image):
|
||||
return x.bandmean()
|
||||
else:
|
||||
return [sum(x) / len(x)]
|
||||
|
||||
self.run_unary([self.colour], bandmean, fmt = noncomplex_formats)
|
||||
|
||||
def test_bandrank(self):
|
||||
def median(x, y):
|
||||
joined = zip(x, y)
|
||||
map(lambda x: list(x).sort(), joined)
|
||||
return map(lambda x: x[len(x) / 2], joined)
|
||||
|
||||
def bandrank(x, y):
|
||||
if isinstance(x, Vips.Image) and isinstance(y, Vips.Image):
|
||||
return Vips.Image.bandrank([x, y])
|
||||
else:
|
||||
return median(x, y)
|
||||
|
||||
self.run_binary(self.all_images, bandrank, fmt = noncomplex_formats)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
Reference in New Issue
Block a user