From 16c4eeabadd9178c5fa9bab529b47f40c0dbce6e Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 20 Nov 2015 16:29:43 +0000 Subject: [PATCH] python does auto complx/uncomplx this is a bit ugly :-( --- TODO | 22 +--------------------- python/Vips.py | 38 ++++++++++++++++++++++++++++++++++++-- python/example/cod.py | 41 ++++++----------------------------------- 3 files changed, 43 insertions(+), 58 deletions(-) diff --git a/TODO b/TODO index ff804400..b521c35d 100644 --- a/TODO +++ b/TODO @@ -1,29 +1,9 @@ -- we need to be able to run .polar() on xyz images ... argh - - - could special-case vips_complex() to work for multi-band int images as - well as complex - - would need to output as multi-band float - - what about other cases though? cast real to complex? - - - could add new ops for polar/rect of real images with two bands - - - could add a thing to Vips.py to do this - - - could add full support for complex arithmetic ... linear would need an - extra arg for complex constants - - - could abandon complex images and just use 2*bands instead, have complex - as a flag you set? or just rely on FOURIER - - paste fixed up run_cmplx() into Vips.py - easy to get a segv with Nicolas's interpolators, argh just with float images? - try to_polar, set LBB, zoom in and scroll around a bit + try to_polar workspace, set LBB, zoom in and scroll around a bit diff --git a/python/Vips.py b/python/Vips.py index babda542..e4f59513 100644 --- a/python/Vips.py +++ b/python/Vips.py @@ -134,6 +134,40 @@ def arrayize(gtype, value): return value +def run_cmplx(fn, image): + """Run a complex function on a non-complex image. + + The image needs to be complex, or have an even number of bands. The input + can be int, the output is always float or double. + """ + original_format = image.format + + if not Vips.band_format_iscomplex(image.format): + if image.bands % 2 != 0: + raise "not an even number of bands" + + if not Vips.band_format_isfloat(image.format): + image = image.cast(Vips.BandFormat.FLOAT) + + if image.format == Vips.BandFormat.DOUBLE: + new_format = Vips.BandFormat.DPCOMPLEX + else: + new_format = Vips.BandFormat.COMPLEX + + image = image.copy(format = new_format, bands = image.bands / 2) + + image = fn(image) + + if not Vips.band_format_iscomplex(original_format): + if image.format == Vips.BandFormat.DPCOMPLEX: + new_format = Vips.BandFormat.DOUBLE + else: + new_format = Vips.BandFormat.FLOAT + + image = image.copy(format = new_format, bands = image.bands * 2) + + return image + class Error(Exception): """An error from vips. @@ -911,11 +945,11 @@ class Image(Vips.Image): def polar(self): """Return an image converted to polar coordinates.""" - return self.complex(Vips.OperationComplex.POLAR) + return run_cmplx(lambda x: x.complex(Vips.OperationComplex.POLAR), self) def rect(self): """Return an image converted to rectangular coordinates.""" - return self.complex(Vips.OperationComplex.RECT) + return run_cmplx(lambda x: x.complex(Vips.OperationComplex.RECT), self) def conj(self): """Return the complex conjugate of an image.""" diff --git a/python/example/cod.py b/python/example/cod.py index 449f6ffb..bbe8771f 100755 --- a/python/example/cod.py +++ b/python/example/cod.py @@ -11,37 +11,6 @@ from gi.repository import Vips #Vips.cache_set_trace(True) -# Run a function expecting a complex image on an image with an even number of -# bands -def run_cmplx(fn, image): - original_format = image.format - - if not Vips.band_format_iscomplex(image.format): - if image.bands % 2 != 0: - raise "not an even number of bands" - - if not Vips.band_format_isfloat(image.format): - image = image.cast(Vips.BandFormat.FLOAT) - - if image.format == Vips.BandFormat.DOUBLE: - new_format = Vips.BandFormat.DPCOMPLEX - else: - new_format = Vips.BandFormat.COMPLEX - - image = image.copy(format = new_format, bands = image.bands / 2) - - image = fn(image) - - if not Vips.band_format_iscomplex(original_format): - if image.format == Vips.BandFormat.DPCOMPLEX: - new_format = Vips.BandFormat.DOUBLE - else: - new_format = Vips.BandFormat.FLOAT - - image = image.copy(format = new_format, bands = image.bands * 2) - - return image - def to_polar(image): """Transform image coordinates to polar. @@ -55,8 +24,9 @@ def to_polar(image): scale = min(image.width, image.height) / float(image.width) xy *= 2.0 / scale - # to polar, scale vertical axis to 360 degrees - index = run_cmplx(lambda x: x.polar(), xy) + index = xy.polar() + + # scale vertical axis to 360 degrees index *= [1, image.height / 360.0] return image.mapim(index) @@ -72,8 +42,9 @@ def to_rectangular(image): xy = Vips.Image.xyz(image.width, image.height) xy *= [1, 360.0 / image.height] - # to rect, scale to image rect - index = run_cmplx(lambda x: x.rect(), xy) + index = xy.rect() + + # scale to image rect scale = min(image.width, image.height) / float(image.width) index *= scale / 2.0 index += [image.width / 2.0, image.height / 2.0]