mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 09:57:43 +03:00 
			
		
		
		
	ENH: Autocontrast method enhancement - adding the option to specify mask for contrast computation
This commit is contained in:
		
							parent
							
								
									0ccb28088f
								
							
						
					
					
						commit
						8fad541531
					
				| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
import pytest
 | 
			
		||||
from PIL import Image, ImageOps, features
 | 
			
		||||
from PIL import Image, ImageOps, ImageDraw, features
 | 
			
		||||
 | 
			
		||||
from .helper import (
 | 
			
		||||
    assert_image_equal,
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +24,9 @@ def test_sanity():
 | 
			
		|||
    ImageOps.autocontrast(hopper("RGB"))
 | 
			
		||||
 | 
			
		||||
    ImageOps.autocontrast(hopper("L"), cutoff=10)
 | 
			
		||||
    ImageOps.autocontrast(hopper("L"), cutoff=(2, 10))
 | 
			
		||||
    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"), "black", "white")
 | 
			
		||||
| 
						 | 
				
			
			@ -311,3 +313,30 @@ def test_autocontrast_cutoff():
 | 
			
		|||
 | 
			
		||||
        assert autocontrast(10) == autocontrast((10, 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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,10 +61,10 @@ def _lut(image, lut):
 | 
			
		|||
# 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
 | 
			
		||||
    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
 | 
			
		||||
    so that the darkest pixel becomes black (0), and the lightest
 | 
			
		||||
    becomes white (255).
 | 
			
		||||
| 
						 | 
				
			
			@ -74,9 +74,15 @@ def autocontrast(image, cutoff=0, ignore=None):
 | 
			
		|||
                   high ends. Either a tuple of (low, high), or a single
 | 
			
		||||
                   number for both.
 | 
			
		||||
    :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.
 | 
			
		||||
    """
 | 
			
		||||
    histogram = image.histogram()
 | 
			
		||||
    if mask:
 | 
			
		||||
        histogram = image.histogram(mask)
 | 
			
		||||
    else:
 | 
			
		||||
        histogram = image.histogram()
 | 
			
		||||
    lut = []
 | 
			
		||||
    for layer in range(0, len(histogram), 256):
 | 
			
		||||
        h = histogram[layer : layer + 256]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user