From c80fe312e47d395e6d98d96ed3602c58b562b675 Mon Sep 17 00:00:00 2001 From: homm Date: Mon, 20 Oct 2014 10:48:16 +0400 Subject: [PATCH] Add extended box blur. --- PIL/ImageOps.py | 16 ++++++++++++++++ Tests/test_box_blur.py | 31 ++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/PIL/ImageOps.py b/PIL/ImageOps.py index 2f4cbe564..4fe7bf222 100644 --- a/PIL/ImageOps.py +++ b/PIL/ImageOps.py @@ -20,6 +20,7 @@ from PIL import Image from PIL._util import isStringType import operator +import math from functools import reduce @@ -458,3 +459,18 @@ def box_blur(image, radius): image.load() return image._new(image.im.box_blur(radius)) + + +def extended_box_blur(image, radius, n=3): + sigma2 = float(radius) * radius / n + # http://www.mia.uni-saarland.de/Publications/gwosdek-ssvm11.pdf + # [7] Box length. + L = math.sqrt(12.0 * sigma2 + 1.0) + # [11] Integer part of box radius. + l = math.floor((L - 1.0) / 2.0) + # [14], [Fig. 2] Fractional part of box radius. + a = (2 * l + 1) * (l * (l + 1) - 3 * sigma2) + a /= 6 * (sigma2 - (l + 1) * (l + 1)) + + image.load() + return image._new(image.im.box_blur(l + a, n)) diff --git a/Tests/test_box_blur.py b/Tests/test_box_blur.py index f5b97ac7d..c3f46bfc2 100644 --- a/Tests/test_box_blur.py +++ b/Tests/test_box_blur.py @@ -13,14 +13,43 @@ sample.putdata(sum([ ], [])) +class ImageMock(object): + def __init__(self): + self.im = self + + def load(self): + pass + + def _new(self, im): + return im + + def box_blur(self, radius, n): + return radius, n + + class TestBoxBlurApi(PillowTestCase): - def test_imageops(self): + def test_imageops_box_blur(self): i = ImageOps.box_blur(sample, 1) self.assertEqual(i.mode, sample.mode) self.assertEqual(i.size, sample.size) self.assertIsInstance(i, Image.Image) + def test_imageops_extended_box_blur(self): + i = ImageOps.extended_box_blur(sample, 1) + self.assertEqual(i.mode, sample.mode) + self.assertEqual(i.size, sample.size) + self.assertIsInstance(i, Image.Image) + + def test_extended_box_blur_radius(self): + mock = ImageMock() + self.assertEqual((0.25, 3), ImageOps.extended_box_blur(mock, 1)) + self.assertEqual((0.25, 3), ImageOps.extended_box_blur(mock, 1, 3)) + self.assertAlmostEqual(ImageOps.extended_box_blur(mock, .5, 3)[0], + 0.0455, delta=0.0001) + self.assertAlmostEqual(ImageOps.extended_box_blur(mock, 35, 3)[0], + 34.49, delta=0.01) + class TestBoxBlur(PillowTestCase):