ENH: Autocontrast method enhancement - adding the option to specify mask for contrast computation

This commit is contained in:
navneeth 2020-08-06 09:00:13 +09:00
parent 0ccb28088f
commit 8fad541531
2 changed files with 39 additions and 4 deletions

View File

@ -1,5 +1,5 @@
import pytest import pytest
from PIL import Image, ImageOps, features from PIL import Image, ImageOps, ImageDraw, features
from .helper import ( from .helper import (
assert_image_equal, assert_image_equal,
@ -24,7 +24,9 @@ def test_sanity():
ImageOps.autocontrast(hopper("RGB")) ImageOps.autocontrast(hopper("RGB"))
ImageOps.autocontrast(hopper("L"), cutoff=10) ImageOps.autocontrast(hopper("L"), cutoff=10)
ImageOps.autocontrast(hopper("L"), cutoff=(2, 10))
ImageOps.autocontrast(hopper("L"), ignore=[0, 255]) ImageOps.autocontrast(hopper("L"), ignore=[0, 255])
ImageOps.autocontrast(hopper("L"), mask=hopper("L"))
ImageOps.colorize(hopper("L"), (0, 0, 0), (255, 255, 255)) ImageOps.colorize(hopper("L"), (0, 0, 0), (255, 255, 255))
ImageOps.colorize(hopper("L"), "black", "white") ImageOps.colorize(hopper("L"), "black", "white")
@ -311,3 +313,30 @@ def test_autocontrast_cutoff():
assert autocontrast(10) == autocontrast((10, 10)) assert autocontrast(10) == autocontrast((10, 10))
assert autocontrast(10) != autocontrast((1, 10)) assert autocontrast(10) != autocontrast((1, 10))
def test_autocontrast_mask():
# Test the mask argument of autocontrast
with Image.open("Tests/images/bw_gradient.png") as img:
rect_mask = Image.new("L", img.size, 0)
draw = ImageDraw.Draw(rect_mask)
x0, y0 = img.size[0]//4, img.size[1]//4
x1, y1 = 3*img.size[0]//4, 3*img.size[1]//4
draw.rectangle((x0, y0, x1, y1), fill=255)
assert ImageOps.autocontrast(img, mask=rect_mask) != ImageOps.autocontrast(img)
# Test the autocontrast with a rectangular mask
with Image.open("Tests/images/iptc.jpg") as img:
rect_mask = Image.new("L", img.size, 0)
draw = ImageDraw.Draw(rect_mask)
x0, y0 = img.size[0]//2, img.size[1]//2
x1, y1 = img.size[0]-40, img.size[1]
draw.rectangle((x0, y0, x1, y1), fill=255)
result = ImageOps.autocontrast(img, mask=rect_mask)
result_nomask = ImageOps.autocontrast(img)
assert result_nomask != result

View File

@ -61,10 +61,10 @@ def _lut(image, lut):
# actions # actions
def autocontrast(image, cutoff=0, ignore=None): def autocontrast(image, cutoff=0, ignore=None, mask=None):
""" """
Maximize (normalize) image contrast. This function calculates a Maximize (normalize) image contrast. This function calculates a
histogram of the input image, removes **cutoff** percent of the histogram of the input image (or mask region), removes **cutoff** percent of the
lightest and darkest pixels from the histogram, and remaps the image lightest and darkest pixels from the histogram, and remaps the image
so that the darkest pixel becomes black (0), and the lightest so that the darkest pixel becomes black (0), and the lightest
becomes white (255). becomes white (255).
@ -74,8 +74,14 @@ def autocontrast(image, cutoff=0, ignore=None):
high ends. Either a tuple of (low, high), or a single high ends. Either a tuple of (low, high), or a single
number for both. number for both.
:param ignore: The background pixel value (use None for no background). :param ignore: The background pixel value (use None for no background).
:param mask: histogram used in contrast operation is computed using pixels
within the mask. If no mask is given the entire image is used
for histogram computation.
:return: An image. :return: An image.
""" """
if mask:
histogram = image.histogram(mask)
else:
histogram = image.histogram() histogram = image.histogram()
lut = [] lut = []
for layer in range(0, len(histogram), 256): for layer in range(0, len(histogram), 256):