diff --git a/TODO b/TODO index 17ca6f0f..e7afd2d8 100644 --- a/TODO +++ b/TODO @@ -5,6 +5,8 @@ http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CIE2000.html + requesting Ronnier's paper on his CMC colourspece, try that + - could import like this: from gi.repository import Vips diff --git a/python/test_arithmetic.py b/python/test_arithmetic.py index 08c8e1f9..3ba8a66f 100755 --- a/python/test_arithmetic.py +++ b/python/test_arithmetic.py @@ -107,7 +107,7 @@ class TestArithmetic(unittest.TestCase): for x in self.all_images for y in fmt for z in fmt] def setUp(self): - im = Vips.Image.mask_ideal(100, 100, 0.5, 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.mono = self.colour.extract_band(1) self.all_images = [self.mono, self.colour] diff --git a/python/test_colour.py b/python/test_colour.py index 3ab59687..71f81498 100755 --- a/python/test_colour.py +++ b/python/test_colour.py @@ -102,18 +102,11 @@ class TestColour(unittest.TestCase): lambda x, y: run_fn2(fn, x, y)) def setUp(self): - im = Vips.Image.mask_ideal(100, 100, 0.5, 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.mono = self.colour.extract_band(1) self.all_images = [self.mono, self.colour] - def test_bug(self): - test = Vips.Image.black(100, 100) + [50, 0, 0, 42] - test = test.copy(interpretation = Vips.Interpretation.LAB) - im = test.colourspace(Vips.Interpretation.XYZ) - after = im.getpoint(10, 10) - self.assertAlmostEqualObjects(after, [17.5064, 18.4187, 20.0547, 42]) - def test_colourspace(self): # mid-grey in Lab ... put 42 in the extra band, it should be copied # unmodified @@ -155,8 +148,8 @@ class TestColour(unittest.TestCase): # but 8-bit we should hit exactly self.assertLess(abs(after - before), 1) - # checked against Bruce Lindbloom's calculator: - # http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CIE2000.html + # test results from Bruce Lindbloom's calculator: + # http://www.brucelindbloom.com def test_dE00(self): reference = Vips.Image.black(100, 100) + [50, 10, 20] @@ -178,6 +171,8 @@ class TestColour(unittest.TestCase): result = difference.getpoint(10, 10) self.assertAlmostEqualObjects(result, [33.166], places = 3) + # this fails ... redo the CMC space from Ronnier Luo's paper + # though it'll probably still fail def test_dECMC(self): reference = Vips.Image.black(100, 100) + [50, 10, 20] reference = reference.copy(interpretation = Vips.Interpretation.LAB) @@ -188,8 +183,8 @@ class TestColour(unittest.TestCase): result = difference.getpoint(10, 10) self.assertAlmostEqualObjects(result, [44.1147], places = 3) - - + # hard to test ICC stuff without including test images + # rely on the nip2 test suite for this if __name__ == '__main__': unittest.main() diff --git a/python/test_conversion.py b/python/test_conversion.py new file mode 100755 index 00000000..6091224a --- /dev/null +++ b/python/test_conversion.py @@ -0,0 +1,114 @@ +#!/usr/bin/python + +import unittest +import math + +#import logging +#logging.basicConfig(level = logging.DEBUG) + +from gi.repository import Vips +from vips8 import vips + +unsigned_formats = [Vips.BandFormat.UCHAR, + Vips.BandFormat.USHORT, + Vips.BandFormat.UINT] +signed_formats = [Vips.BandFormat.CHAR, + Vips.BandFormat.SHORT, + Vips.BandFormat.INT] +float_formats = [Vips.BandFormat.FLOAT, + Vips.BandFormat.DOUBLE] +complex_formats = [Vips.BandFormat.COMPLEX, + Vips.BandFormat.DPCOMPLEX] +int_formats = unsigned_formats + signed_formats +noncomplex_formats = int_formats + float_formats +all_formats = int_formats + float_formats + complex_formats + +# an expanding zip ... if either of the args is not a list, duplicate it down +# the other +def zip_expand(x, y): + if isinstance(x, list) and isinstance(y, list): + return zip(x, y) + elif isinstance(x, list): + return [[i, y] for i in x] + elif isinstance(y, list): + return [[x, j] for j in y] + else: + return [[x, y]] + +class TestConversion(unittest.TestCase): + # test a pair of things which can be lists for approx. equality + def assertAlmostEqualObjects(self, a, b, places = 4, msg = ''): + #print 'assertAlmostEqualObjects %s = %s' % (a, b) + for x, y in zip_expand(a, b): + self.assertAlmostEqual(x, y, places = places, msg = msg) + + # run a function on an image and on a single pixel, the results + # should match + def run_cmp(self, message, im, x, y, fn): + a = im.getpoint(x, y) + v1 = fn(a) + im2 = fn(im) + v2 = im2.getpoint(x, y) + self.assertAlmostEqualObjects(v1, v2, msg = message) + + # 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): + a = left.getpoint(x, y) + b = right.getpoint(x, y) + v1 = fn(a, b) + after = fn(left, right) + v2 = after.getpoint(x, y) + self.assertAlmostEqualObjects(v1, v2, msg = message) + + # 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) + + # 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) + + def run_unary(self, images, fn, fmt = all_formats): + [self.run_testunary(fn.func_name + ' image', x.cast(y), fn) + for x in images for y 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] + self.mono = self.colour.extract_band(1) + self.all_images = [self.mono, self.colour] + + def test_band_and(self): + def band_and(x): + if isinstance(x, Vips.Image): + return x.bandbool(Vips.OperationBoolean.AND) + else: + return [reduce(lambda a, b: int(a) & int(b), x)] + + self.run_unary([self.colour], band_and, fmt = int_formats) + + def test_band_or(self): + def band_or(x): + if isinstance(x, Vips.Image): + return x.bandbool(Vips.OperationBoolean.OR) + else: + return [reduce(lambda a, b: int(a) | int(b), x)] + + self.run_unary([self.colour], band_or, fmt = int_formats) + + def test_band_eor(self): + def band_eor(x): + if isinstance(x, Vips.Image): + return x.bandbool(Vips.OperationBoolean.EOR) + else: + return [reduce(lambda a, b: int(a) ^ int(b), x)] + + self.run_unary([self.colour], band_eor, fmt = int_formats) + +if __name__ == '__main__': + unittest.main()