Python PIL.ImageStat.Stat() Examples

The following are 20 code examples of PIL.ImageStat.Stat(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module PIL.ImageStat , or try the search function .
Example #1
Source File: img_dynamic_quality.py    From optimize-images with MIT License 13 votes vote down vote up
def compare_images(img1, img2):
    """Calculate the difference between two images of the same size
    by comparing channel values at the pixel level.
    `delete_diff_file`: removes the diff image after ratio found
    `diff_img_file`: filename to store diff image

    Adapted from Nicolas Hahn:
    https://github.com/nicolashahn/diffimg/blob/master/diffimg/__init__.py
    """

    # Don't compare if images are of different modes or different sizes.
    if (img1.mode != img2.mode) \
            or (img1.size != img2.size) \
            or (img1.getbands() != img2.getbands()):
        return None

    # Generate diff image in memory.
    diff_img = ImageChops.difference(img1, img2)
    # Calculate difference as a ratio.
    stat = ImageStat.Stat(diff_img)
    diff_ratio = sum(stat.mean) / (len(stat.mean) * 255)

    return diff_ratio * 100 
Example #2
Source File: test_imagestat.py    From python3_ios with BSD 3-Clause "New" or "Revised" License 7 votes vote down vote up
def test_sanity(self):

        im = hopper()

        st = ImageStat.Stat(im)
        st = ImageStat.Stat(im.histogram())
        st = ImageStat.Stat(im, Image.new("1", im.size, 1))

        # Check these run. Exceptions will cause failures.
        st.extrema
        st.sum
        st.mean
        st.median
        st.rms
        st.sum2
        st.var
        st.stddev

        self.assertRaises(AttributeError, lambda: st.spam)

        self.assertRaises(TypeError, ImageStat.Stat, 1) 
Example #3
Source File: wechit.py    From wechit with MIT License 6 votes vote down vote up
def print_image(im, x_step=12, y_step=24, calc_average=False):
    W,H = im.size
    result = ""
    for i in range(0,H,y_step):
        for j in range(0,W,x_step):
            if calc_average:
                roi = im.crop((j,i,min(W-1,j+x_step),min(H-1,i+y_step)))
                col = ImageStat.Stat(roi).mean
            else:
                col = im.getpixel((min(W-1,j+x_step//2),min(H-1,i+y_step//2)))
            conf = color_mapper(*(col[:3]))
            result += color_text(*conf)
        result += "\n"
    return result

# convert a PIL image to ASCII art given output width in characters 
Example #4
Source File: image_operations.py    From gabenizer with MIT License 6 votes vote down vote up
def create_before_and_after(
        recipient_faces: List[face_detect.Face],
        recipient_image: Image,
        donor_face: face_detect.Face = GABEN_FACE,
        donor_image: Image = GABEN_IMAGE) -> Image:
    logging.info('Locally processing image.')

    after_image = recipient_image

    assert len(recipient_faces) > 0
    for recipient_face in recipient_faces:
        after_image = _paste_donor_on_recipient(recipient_face, after_image, donor_face, donor_image)

    width, height = recipient_image.size
    final = Image.new("RGB", (width * 2, height))
    final.paste(recipient_image, (0, 0))
    final.paste(after_image, (width, 0))

    # if original image was grayscale, convert final
    colors = ImageStat.Stat(recipient_image).var
    if len(colors) == 3 and abs(max(colors) - min(colors)) < COLOR_CUTOFF:
        final = final.convert('L')

    return final 
Example #5
Source File: test_server.py    From python-plexapi with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def _detect_color_image(file, thumb_size=150, MSE_cutoff=22, adjust_color_bias=True):
    # http://stackoverflow.com/questions/20068945/detect-if-image-is-color-grayscale-or-black-and-white-with-python-pil
    pilimg = Image.open(file)
    bands = pilimg.getbands()
    if bands == ("R", "G", "B") or bands == ("R", "G", "B", "A"):
        thumb = pilimg.resize((thumb_size, thumb_size))
        sse, bias = 0, [0, 0, 0]
        if adjust_color_bias:
            bias = ImageStat.Stat(thumb).mean[:3]
            bias = [b - sum(bias) / 3 for b in bias]
        for pixel in thumb.getdata():
            mu = sum(pixel) / 3
            sse += sum(
                (pixel[i] - mu - bias[i]) * (pixel[i] - mu - bias[i]) for i in [0, 1, 2]
            )
        mse = float(sse) / (thumb_size * thumb_size)
        return "grayscale" if mse <= MSE_cutoff else "color"
    elif len(bands) == 1:
        return "blackandwhite" 
Example #6
Source File: auto.py    From thumbor-plugins with MIT License 6 votes vote down vote up
def optimize(self, buffer, input_file, output_file):
        input_image = Image.open(input_file)
        stats = ImageStat.Stat(input_image).extrema
        has_alpha = False
        if len(stats) > 3 and (stats[3][0] < 255):
            has_alpha = True

        if has_alpha == False:
            intermediary = output_file + '-intermediate'
            input_image.save(intermediary, 'JPEG')
            input_file = intermediary

        command = '%s %s %s > /dev/null 2>&1' % (
            self.imgmin_path,
            input_file,
            output_file,
        )
        with open(os.devnull) as null:
            logger.debug("[AUTO IMGMIN] running: " + command)
            subprocess.call(command, shell=True, stdin=null) 
Example #7
Source File: image_util.py    From reddit_crawlers with BSD 2-Clause "Simplified" License 5 votes vote down vote up
def is_color_image(file, thumb_size=50, MSE_cutoff=140, adjust_color_bias=True):
    try:
        pil_img = Image.open(file)
    except:
        print 'Couldn\'t open file %s'%file
        return False

    np_img = np.array(pil_img)
    if len(np_img.shape) > 2 and np_img.shape[2] > 1:
        if np.sum(np_img[:,:,1] - np_img[:,:,2]) == 0:
            print 'Grayscale'
            return False
    else:
        return False

    bands = pil_img.getbands()
    if bands == ('R','G','B') or bands== ('R','G','B','A'):
        thumb = pil_img.resize((thumb_size,thumb_size))
        SSE, bias = 0, [0,0,0]
        if adjust_color_bias:
            bias = ImageStat.Stat(thumb).mean[:3]
            bias = [b - sum(bias)/3 for b in bias ]
        for pixel in thumb.getdata():
            mu = sum(pixel)/3
            SSE += sum((pixel[i] - mu - bias[i])*(pixel[i] - mu - bias[i]) for i in [0,1,2])
        MSE = float(SSE)/(thumb_size*thumb_size)
        if MSE <= MSE_cutoff:
            print "grayscale\t",
            print "( MSE=",MSE,")"
            return False
        else:
            print "Color\t\t\t",
            print "( MSE=",MSE,")"

            return True
    elif len(bands)==1:
        print "Black and white", bands
        return False
    else:
        print "Don't know...", bands
        return False 
Example #8
Source File: __init__.py    From core with Apache License 2.0 5 votes vote down vote up
def image_from_polygon(image, polygon, fill='background', transparency=False):
    """"Mask an image with a polygon.

    Given a PIL.Image ``image`` and a numpy array ``polygon``
    of relative coordinates into the image, fill everything
    outside the polygon hull to a color according to ``fill``:

    - if ``background`` (the default),
      then use the median color of the image;
    - otherwise use the given color, e.g. ``'white'`` or (255,255,255).

    Moreover, if ``transparency`` is true, then add an alpha channel
    from the polygon mask (i.e. everything outside the polygon will
    be transparent, for those consumers that can interpret alpha channels).
    Images which already have an alpha channel will have it shrunk
    from the polygon mask (i.e. everything outside the polygon will
    be transparent, in addition to existing transparent pixels).
    
    Return a new PIL.Image.
    """
    mask = polygon_mask(image, polygon)
    if fill == 'background':
        background = tuple(ImageStat.Stat(image).median)
    else:
        background = fill
    new_image = Image.new(image.mode, image.size, background)
    new_image.paste(image, mask=mask)
    # ensure no information is lost by a adding transparency channel
    # initialized to fully transparent outside the polygon mask
    # (so consumers do not have to rely on background estimation,
    #  which can fail on foreground-dominated segments, or white,
    #  which can be inconsistent on unbinarized images):
    if image.mode in ['RGBA', 'LA']:
        # ensure transparency maximizes (i.e. parent mask AND mask):
        mask = ImageChops.darker(mask, image.getchannel('A')) # min opaque
        new_image.putalpha(mask)
    elif transparency and image.mode in ['RGB', 'L']:
        # introduce transparency:
        new_image.putalpha(mask)
    return new_image 
Example #9
Source File: __init__.py    From core with Apache License 2.0 5 votes vote down vote up
def crop_image(image, box=None):
    """"Crop an image to a rectangle, filling with background.

    Given a PIL.Image ``image`` and a list ``box`` of the bounding
    rectangle relative to the image, crop at the box coordinates,
    filling everything outside ``image`` with the background.
    (This covers the case where ``box`` indexes are negative or
    larger than ``image`` width/height. PIL.Image.crop would fill
    with black.) Since ``image`` is not necessarily binarized yet,
    determine the background from the median color (instead of
    white).

    Return a new PIL.Image.
    """
    if not box:
        box = (0, 0, image.width, image.height)
    elif box[0] < 0 or box[1] < 0 or box[2] > image.width or box[3] > image.height:
        # (It should be invalid in PAGE-XML to extend beyond parents.)
        LOG.warning('crop coordinates (%s) exceed image (%dx%d)',
                    str(box), image.width, image.height)
    LOG.debug('cropping image to %s', str(box))
    xywh = xywh_from_bbox(*box)
    background = tuple(ImageStat.Stat(image).median)
    new_image = Image.new(image.mode, (xywh['w'], xywh['h']),
                          background) # or 'white'
    new_image.paste(image, (-xywh['x'], -xywh['y']))
    return new_image 
Example #10
Source File: warp.py    From open-vot with MIT License 5 votes vote down vote up
def pad_pil(image, npad, padding='avg'):
    if npad == 0:
        return image

    if padding == 'avg':
        avg_chan = ImageStat.Stat(image).mean
        # PIL doesn't support float RGB image
        avg_chan = tuple(int(round(c)) for c in avg_chan)
        image = ImageOps.expand(image, border=npad, fill=avg_chan)
    else:
        image = ImageOps.expand(image, border=npad, fill=padding)

    return image 
Example #11
Source File: warp.py    From open-vot with MIT License 5 votes vote down vote up
def pad(image, npad, padding='avg'):
    if npad == 0:
        return image

    if padding == 'avg':
        avg_chan = ImageStat.Stat(image).mean
        # PIL doesn't support float RGB image
        avg_chan = tuple(int(round(c)) for c in avg_chan)
        image = ImageOps.expand(image, border=npad, fill=avg_chan)
    else:
        image = ImageOps.expand(image, border=npad, fill=padding)

    return image 
Example #12
Source File: diff.py    From diffimg with MIT License 5 votes vote down vote up
def diff(
    im1_file, im2_file, delete_diff_file=False, diff_img_file=None, ignore_alpha=False
):
    """
    Calculate the difference between two images of the same size
    by comparing channel values at the pixel level.

    `delete_diff_file`: removes the diff image after ratio found
    `diff_img_file`: filename to store diff image
    `ignore_alpha`: ignore the alpha channel for ratio calculation, and set the diff
        image's alpha to fully opaque
    """
    if not diff_img_file:
        diff_img_file = DIFF_IMG_FILE

    im1 = Image.open(im1_file)
    im2 = Image.open(im2_file)

    # Ensure we have the same color channels (RGBA vs RGB)
    if im1.mode != im2.mode:
        raise ValueError(
            (
                "Differing color modes:\n  {}: {}\n  {}: {}\n"
                "Ensure image color modes are the same."
            ).format(im1_file, im1.mode, im2_file, im2.mode)
        )

    # Generate diff image in memory.
    diff_img = ImageChops.difference(im1, im2)

    if ignore_alpha:
        diff_img.putalpha(256)

    if not delete_diff_file:
        if "." not in diff_img_file:
            extension = "png"
        else:
            extension = diff_img_file.split(".")[-1]
        if extension in ("jpg", "jpeg"):
            # For some reason, save() thinks "jpg" is invalid
            # This doesn't affect the image's saved filename
            extension = "jpeg"
            diff_img = diff_img.convert("RGB")
        diff_img.save(diff_img_file, extension)

    # Calculate difference as a ratio.
    stat = ImageStat.Stat(diff_img)
    # stat.mean can be [r,g,b] or [r,g,b,a].
    removed_channels = 1 if ignore_alpha and len(stat.mean) == 4 else 0
    num_channels = len(stat.mean) - removed_channels
    sum_channel_values = sum(stat.mean[:num_channels])
    max_all_channels = num_channels * 255
    diff_ratio = sum_channel_values / max_all_channels

    return diff_ratio 
Example #13
Source File: test_imagestat.py    From python3_ios with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_constant(self):

        im = Image.new("L", (128, 128), 128)

        st = ImageStat.Stat(im)

        self.assertEqual(st.extrema[0], (128, 128))
        self.assertEqual(st.sum[0], 128**3)
        self.assertEqual(st.sum2[0], 128**4)
        self.assertEqual(st.mean[0], 128)
        self.assertEqual(st.median[0], 128)
        self.assertEqual(st.rms[0], 128)
        self.assertEqual(st.var[0], 0)
        self.assertEqual(st.stddev[0], 0) 
Example #14
Source File: test_imagestat.py    From python3_ios with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_hopper(self):

        im = hopper()

        st = ImageStat.Stat(im)

        # verify a few values
        self.assertEqual(st.extrema[0], (0, 255))
        self.assertEqual(st.median[0], 72)
        self.assertEqual(st.sum[0], 1470218)
        self.assertEqual(st.sum[1], 1311896)
        self.assertEqual(st.sum[2], 1563008) 
Example #15
Source File: data_loader.py    From Siamese-RPN-pytorch with MIT License 5 votes vote down vote up
def _average(self):
        assert self.ret.__contains__('template_img_path'), 'no template path'
        assert self.ret.__contains__('detection_img_path'),'no detection path'
        template = Image.open(self.ret['template_img_path'])
        detection= Image.open(self.ret['detection_img_path'])
        
        mean_template = tuple(map(round, ImageStat.Stat(template).mean))
        mean_detection= tuple(map(round, ImageStat.Stat(detection).mean))
        self.ret['mean_template'] = mean_template
        self.ret['mean_detection']= mean_detection 
Example #16
Source File: data_loader.py    From Siamese-RPN-pytorch with MIT License 5 votes vote down vote up
def _average(self):
        assert self.ret.__contains__('template_img_path'), 'no template path'
        assert self.ret.__contains__('detection_img_path'),'no detection path'
        template = Image.open(self.ret['template_img_path'])
        detection= Image.open(self.ret['detection_img_path'])
        
        mean_template = tuple(map(round, ImageStat.Stat(template).mean))
        mean_detection= tuple(map(round, ImageStat.Stat(detection).mean))

        self.ret['mean_template'] = (mean_template[0], mean_template[1], mean_template[2])
        self.ret['mean_detection']= (mean_detection[0],mean_detection[1],mean_detection[2]) 
Example #17
Source File: data_loader.py    From Siamese-RPN-pytorch with MIT License 5 votes vote down vote up
def _average(self):
        assert self.ret.__contains__('template_img_path'), 'no template path'
        assert self.ret.__contains__('detection_img_path'),'no detection path'
        template = Image.open(self.ret['template_img_path'])
        detection= Image.open(self.ret['detection_img_path'])
        
        mean_template = tuple(map(round, ImageStat.Stat(template).mean))
        mean_detection= tuple(map(round, ImageStat.Stat(detection).mean))
        self.ret['mean_template'] = mean_template
        self.ret['mean_detection']= mean_detection 
Example #18
Source File: download_cl1024_images.py    From pythonprojects with MIT License 5 votes vote down vote up
def getMean(self):
        if not self.mean:
            self.mean = ImageStat.Stat(self.im.convert('L')).mean[0]

        return self.mean 
Example #19
Source File: imagesmake.py    From pythonprojects with MIT License 5 votes vote down vote up
def getMean(self):
        if not self.mean:
            self.mean = ImageStat.Stat(self.im.convert('L')).mean[0]

        return self.mean 
Example #20
Source File: __init__.py    From core with Apache License 2.0 4 votes vote down vote up
def rotate_image(image, angle, fill='background', transparency=False):
    """"Rotate an image, enlarging and filling with background.

    Given a PIL.Image ``image`` and a rotation angle in degrees
    counter-clockwise ``angle``, rotate the image, increasing its
    size at the margins accordingly, and filling everything outside
    the original image according to ``fill``:

    - if ``background`` (the default),
      then use the median color of the image;
    - otherwise use the given color, e.g. ``'white'`` or (255,255,255).

    Moreover, if ``transparency`` is true, then add an alpha channel
    fully opaque (i.e. everything outside the original image will
    be transparent for those that can interpret alpha channels).
    (This is true for images which already have an alpha channel,
    regardless of the setting used.)

    Return a new PIL.Image.
    """
    LOG.debug('rotating image by %.2f°', angle)
    if transparency and image.mode in ['RGB', 'L']:
        # ensure no information is lost by adding transparency channel
        # initialized to fully opaque (so cropping and rotation will
        # expose areas as transparent):
        image = image.copy()
        image.putalpha(255)
    if fill == 'background':
        background = ImageStat.Stat(image).median
        if image.mode in ['RGBA', 'LA']:
            background[-1] = 0 # fully transparent
        background = tuple(background)
    else:
        background = fill
    new_image = image.rotate(angle,
                             expand=True,
                             #resample=Image.BILINEAR,
                             fillcolor=background)
    if new_image.mode in ['LA']:
        # workaround for #1600 (bug in LA support which
        # causes areas fully transparent before rotation
        # to be filled with black here):
        image = new_image
        new_image = Image.new(image.mode, image.size, background)
        new_image.paste(image, mask=image.getchannel('A'))
    return new_image