普通文本  |  92行  |  2.92 KB

# Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import heapq, logging

from PIL import Image
from PIL import ImageChops

from autotest_lib.client.cros.image_comparison import comparison_result
from autotest_lib.client.cros.video import method_logger


"""

*** Consider using PdiffImageComparer instead of this class ***
  * This class uses pixel by pixel comparer while PdiffImageComparer encapsules
  * the perceptualdiff tool available in ChromeOS

"""


class RGBImageComparer(object):
    """
    Compares two RGB images using built-in python image library.

    """


    def __init__(self, rgb_pixel_threshold):
        self.pixel_threshold = rgb_pixel_threshold


    @method_logger.log
    def compare(self, golden_img_path, test_img_path, box=None):
        """
        Compares a test image against a known golden image.

        Both images must be RGB images.

        @param golden_img_path: path, complete path to a golden image.
        @param test_img_path: path, complete path to a test image.
        @param box: int tuple, left, upper, right, lower pixel coordinates
                    defining a box region within which the comparison is made.

        @return: int, number of pixels that are different.

        """
        golden_image = Image.open(golden_img_path)
        test_image = Image.open(test_img_path)

        if golden_image.mode != 'RGB':
            logging.debug('Golden image was not RGB. Converting to RGB.')
            golden_image = golden_image.convert('RGB')

        if test_image.mode != 'RGB':
            logging.debug('Test image was not RGB. Converting to RGB.')
            test_image = test_image.convert('RGB')

        if box is not None:
            golden_image = golden_image.crop(box)
            test_image = test_image.crop(box)

        diff_image = ImageChops.difference(golden_image, test_image)
        maxcolors = diff_image.size[0] * diff_image.size[1]
        colorstuples = diff_image.getcolors(maxcolors)
        max_debug_count = 100

        logging.debug("***ALL Color counts: %d", maxcolors)
        logging.debug(heapq.nlargest(max_debug_count, colorstuples))

        # getcolors returns a list of (count, color) tuples where count is the
        # number of times the corresponding color in the image.

        above_thres_tuples = [t for t in colorstuples
                              if any(pixel > self.pixel_threshold
                                     for pixel in t[1])]

        logging.debug("Color counts above thres.: %d", len(above_thres_tuples))
        logging.debug(heapq.nlargest(max_debug_count, above_thres_tuples))

        diff_pixels = sum(t[0] for t in above_thres_tuples)

        return comparison_result.ComparisonResult(diff_pixels, '')
    
    
    def __enter__(self):
        return self
    
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        pass