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
|
- added test_foreign.py, plus more test images
|
||||||
- rewritten tiff writer is about 3 - 4x faster at making pyramids
|
- rewritten tiff writer is about 3 - 4x faster at making pyramids
|
||||||
- jpg, magick, png, tiff readers now use only 1 fd per input image
|
- 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
|
6/2/15 started 7.42.3
|
||||||
- bump version for back-compat ABI change
|
- 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
|
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
|
- support orientation tag in tiff images
|
||||||
|
@ -1263,6 +1263,12 @@ public:
|
|||||||
return( a * -1 );
|
return( a * -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend VImage operator[]( VImage a, int index )
|
||||||
|
throw( VError )
|
||||||
|
{
|
||||||
|
return( a.extract_band( index ) );
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VIPS_NAMESPACE_END
|
VIPS_NAMESPACE_END
|
||||||
|
@ -347,6 +347,26 @@ help(image.add)
|
|||||||
result_image = ((image * [1, 2, 3]).abs() < 128) | 4
|
result_image = ((image * [1, 2, 3]).abs() < 128) | 4
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</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>
|
||||||
|
|
||||||
<refsect3 id="python-expansions">
|
<refsect3 id="python-expansions">
|
||||||
|
@ -757,6 +757,32 @@ class Image(Vips.Image):
|
|||||||
else:
|
else:
|
||||||
return self.relational_const(other, Vips.OperationRelational.NOTEQ)
|
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,
|
# the cast operators int(), long() and float() must return numeric types,
|
||||||
# so we can't define them for images
|
# so we can't define them for images
|
||||||
|
|
||||||
@ -813,7 +839,7 @@ class Image(Vips.Image):
|
|||||||
|
|
||||||
def bandsplit(self):
|
def bandsplit(self):
|
||||||
"""Split an n-band image into n separate images."""
|
"""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):
|
def bandjoin(self, other):
|
||||||
"""Join a set of images bandwise."""
|
"""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
|
# the other
|
||||||
def zip_expand(x, y):
|
def zip_expand(x, y):
|
||||||
if isinstance(x, list) and isinstance(y, list):
|
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))
|
return list(zip(x, y))
|
||||||
elif isinstance(x, list):
|
elif isinstance(x, list):
|
||||||
return [[i, y] for i in x]
|
return [[i, y] for i in x]
|
||||||
@ -138,7 +140,7 @@ class TestConversion(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
im = Vips.Image.mask_ideal(100, 100, 0.5, reject = True, optical = True)
|
im = Vips.Image.mask_ideal(100, 100, 0.5, reject = True, optical = True)
|
||||||
self.colour = im * [1, 2, 3] + [2, 3, 4]
|
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]
|
self.all_images = [self.mono, self.colour]
|
||||||
|
|
||||||
def test_band_and(self):
|
def test_band_and(self):
|
||||||
@ -295,6 +297,31 @@ class TestConversion(unittest.TestCase):
|
|||||||
pixel = sub.getpoint(30, 30)
|
pixel = sub.getpoint(30, 30)
|
||||||
self.assertAlmostEqualObjects(pixel, [3, 4])
|
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):
|
def test_crop(self):
|
||||||
for fmt in all_formats:
|
for fmt in all_formats:
|
||||||
test = self.colour.cast(fmt)
|
test = self.colour.cast(fmt)
|
||||||
|
Loading…
Reference in New Issue
Block a user