add [] overload to python
index and slice image bands
This commit is contained in:
parent
a49e6772fd
commit
5d912fdbbb
@ -10,6 +10,7 @@
|
||||
- added test_foreign.py, plus more test images
|
||||
- rewritten tiff writer is about 3 - 4x faster at making pyramids
|
||||
- jpg, magick, png, tiff readers now use only 1 fd per input image
|
||||
- python: use [] to index and slice image bands
|
||||
|
||||
6/2/15 started 7.42.3
|
||||
- bump version for back-compat ABI change
|
||||
|
8
TODO
8
TODO
@ -3,6 +3,14 @@
|
||||
|
||||
python people are not going to want to use the glib arg parser, for example
|
||||
|
||||
- need to add [] overload to Ruby bindings
|
||||
|
||||
- overload (x, y) to be getpoint()?
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- support orientation tag in tiff images
|
||||
|
@ -1263,6 +1263,12 @@ public:
|
||||
return( a * -1 );
|
||||
}
|
||||
|
||||
friend VImage operator[]( VImage a, int index )
|
||||
throw( VError )
|
||||
{
|
||||
return( a.extract_band( index ) );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
VIPS_NAMESPACE_END
|
||||
|
@ -347,6 +347,26 @@ help(image.add)
|
||||
result_image = ((image * [1, 2, 3]).abs() < 128) | 4
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The wrapper overloads <code>[]</code> to be band indexing. You can write:
|
||||
|
||||
<programlisting language="Python">
|
||||
result_image = image[2]
|
||||
</programlisting>
|
||||
|
||||
to extract the third band of the image. It implements the usual
|
||||
slicing and negative indexes, so you can write:
|
||||
|
||||
<programlisting language="Python">
|
||||
result_image = image[1:]
|
||||
result_image = image[:3]
|
||||
result_image = image[-2:]
|
||||
result_image = [x.avg() for x in image]
|
||||
</programlisting>
|
||||
|
||||
and so on.
|
||||
</para>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="python-expansions">
|
||||
|
@ -757,6 +757,32 @@ class Image(Vips.Image):
|
||||
else:
|
||||
return self.relational_const(other, Vips.OperationRelational.NOTEQ)
|
||||
|
||||
def __getitem__(self, arg):
|
||||
if isinstance(arg, slice):
|
||||
i = 0
|
||||
if arg.start != None:
|
||||
i = arg.start
|
||||
|
||||
n = self.bands - i
|
||||
if arg.stop != None:
|
||||
if arg.stop < 0:
|
||||
n = self.bands + arg.stop - i
|
||||
else:
|
||||
n = arg.stop - i
|
||||
elif isinstance(arg, int):
|
||||
i = arg
|
||||
n = 1
|
||||
else:
|
||||
raise TypeError
|
||||
|
||||
if i < 0:
|
||||
i = self.bands + i
|
||||
|
||||
if i < 0 or i >= self.bands:
|
||||
raise IndexError
|
||||
|
||||
return self.extract_band(i, n = n)
|
||||
|
||||
# the cast operators int(), long() and float() must return numeric types,
|
||||
# so we can't define them for images
|
||||
|
||||
@ -813,7 +839,7 @@ class Image(Vips.Image):
|
||||
|
||||
def bandsplit(self):
|
||||
"""Split an n-band image into n separate images."""
|
||||
return [self.extract_band(i) for i in range(0, self.bands)]
|
||||
return [x for x in self]
|
||||
|
||||
def bandjoin(self, other):
|
||||
"""Join a set of images bandwise."""
|
||||
|
18
python/example/try17.py
Executable file
18
python/example/try17.py
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
|
||||
import logging
|
||||
#logging.basicConfig(level = logging.DEBUG)
|
||||
|
||||
from gi.repository import Vips
|
||||
|
||||
#Vips.cache_set_trace(True)
|
||||
|
||||
a = Vips.Image.new_from_file(sys.argv[1])
|
||||
|
||||
a = a[1:]
|
||||
|
||||
a.write_to_file(sys.argv[2])
|
||||
|
||||
|
@ -80,6 +80,8 @@ rot_angle_bonds = [Vips.Angle.D0,
|
||||
# the other
|
||||
def zip_expand(x, y):
|
||||
if isinstance(x, list) and isinstance(y, list):
|
||||
if len(x) != len(y):
|
||||
raise Vips.Error("zip_expand list args not equal length")
|
||||
return list(zip(x, y))
|
||||
elif isinstance(x, list):
|
||||
return [[i, y] for i in x]
|
||||
@ -138,7 +140,7 @@ class TestConversion(unittest.TestCase):
|
||||
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]
|
||||
self.mono = self.colour.extract_band(1)
|
||||
self.mono = self.colour[1]
|
||||
self.all_images = [self.mono, self.colour]
|
||||
|
||||
def test_band_and(self):
|
||||
@ -295,6 +297,31 @@ class TestConversion(unittest.TestCase):
|
||||
pixel = sub.getpoint(30, 30)
|
||||
self.assertAlmostEqualObjects(pixel, [3, 4])
|
||||
|
||||
def test_slice(self):
|
||||
test = self.colour
|
||||
bands = [x.avg() for x in test]
|
||||
|
||||
x = test[0].avg()
|
||||
self.assertEqual(x, bands[0])
|
||||
|
||||
x = test[-1].avg()
|
||||
self.assertAlmostEqualObjects(x, bands[2])
|
||||
|
||||
x = [i.avg() for i in test[1:3]]
|
||||
self.assertAlmostEqualObjects(x, bands[1:3])
|
||||
|
||||
x = [i.avg() for i in test[1:-1]]
|
||||
self.assertAlmostEqualObjects(x, bands[1:-1])
|
||||
|
||||
x = [i.avg() for i in test[:2]]
|
||||
self.assertAlmostEqualObjects(x, bands[:2])
|
||||
|
||||
x = [i.avg() for i in test[1:]]
|
||||
self.assertAlmostEqualObjects(x, bands[1:])
|
||||
|
||||
x = [i.avg() for i in test[-1]]
|
||||
self.assertAlmostEqualObjects(x, bands[-1])
|
||||
|
||||
def test_crop(self):
|
||||
for fmt in all_formats:
|
||||
test = self.colour.cast(fmt)
|
||||
|
Loading…
Reference in New Issue
Block a user