Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(296)

Side by Side Diff: gm/rebaseline_server/imagediffdb.py

Issue 131453017: Revert of Add the perceptual difference metric to the rebaseline server (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | gm/rebaseline_server/imagediffdb_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 """ 3 """
4 Copyright 2013 Google Inc. 4 Copyright 2013 Google Inc.
5 5
6 Use of this source code is governed by a BSD-style license that can be 6 Use of this source code is governed by a BSD-style license that can be
7 found in the LICENSE file. 7 found in the LICENSE file.
8 8
9 Calulate differences between image pairs, and store them in a database. 9 Calulate differences between image pairs, and store them in a database.
10 """ 10 """
11 11
12 import contextlib 12 import contextlib
13 import csv
14 import logging 13 import logging
15 import os 14 import os
16 import re 15 import re
17 import shutil 16 import shutil
18 import sys
19 import tempfile
20 import urllib 17 import urllib
21 try: 18 try:
22 from PIL import Image, ImageChops 19 from PIL import Image, ImageChops
23 except ImportError: 20 except ImportError:
24 raise ImportError('Requires PIL to be installed; see ' 21 raise ImportError('Requires PIL to be installed; see '
25 + 'http://www.pythonware.com/products/pil/') 22 + 'http://www.pythonware.com/products/pil/')
26 23
27 # Set the PYTHONPATH to include the tools directory.
28 sys.path.append(
29 os.path.join(
30 os.path.dirname(os.path.realpath(__file__)), os.pardir, os.pardir,
31 'tools'))
32 import find_run_binary
33
34 SKPDIFF_BINARY_NAME = 'skpdiff'
35
36 DEFAULT_IMAGE_SUFFIX = '.png' 24 DEFAULT_IMAGE_SUFFIX = '.png'
37 DEFAULT_IMAGES_SUBDIR = 'images' 25 DEFAULT_IMAGES_SUBDIR = 'images'
38 26
39 DISALLOWED_FILEPATH_CHAR_REGEX = re.compile('[^\w\-]') 27 DISALLOWED_FILEPATH_CHAR_REGEX = re.compile('[^\w\-]')
40 28
41 DIFFS_SUBDIR = 'diffs' 29 DIFFS_SUBDIR = 'diffs'
42 WHITEDIFFS_SUBDIR = 'whitediffs' 30 WHITEDIFFS_SUBDIR = 'whitediffs'
43 31
44 VALUES_PER_BAND = 256 32 VALUES_PER_BAND = 256
45 33
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 # Generate the whitediff image (any differing pixels show as white). 92 # Generate the whitediff image (any differing pixels show as white).
105 # This is tricky, because when you convert color images to grayscale or 93 # This is tricky, because when you convert color images to grayscale or
106 # black & white in PIL, it has its own ideas about thresholds. 94 # black & white in PIL, it has its own ideas about thresholds.
107 # We have to force it: if a pixel has any color at all, it's a '1'. 95 # We have to force it: if a pixel has any color at all, it's a '1'.
108 bands = diff_image.split() 96 bands = diff_image.split()
109 graydiff_image = ImageChops.lighter(ImageChops.lighter( 97 graydiff_image = ImageChops.lighter(ImageChops.lighter(
110 bands[0], bands[1]), bands[2]) 98 bands[0], bands[1]), bands[2])
111 whitediff_image = (graydiff_image.point(lambda p: p > 0 and VALUES_PER_BAND) 99 whitediff_image = (graydiff_image.point(lambda p: p > 0 and VALUES_PER_BAND)
112 .convert('1', dither=Image.NONE)) 100 .convert('1', dither=Image.NONE))
113 101
114 # Calculate the perceptual difference percentage.
115 skpdiff_csv_dir = tempfile.mkdtemp()
116 try:
117 skpdiff_csv_output = os.path.join(skpdiff_csv_dir, 'skpdiff-output.csv')
118 skpdiff_binary = find_run_binary.find_path_to_program(SKPDIFF_BINARY_NAME)
119 expected_img = os.path.join(storage_root, expected_images_subdir,
120 str(expected_image_locator) + image_suffix)
121 actual_img = os.path.join(storage_root, actual_images_subdir,
122 str(actual_image_locator) + image_suffix)
123 find_run_binary.run_command(
124 [skpdiff_binary, '-p', expected_img, actual_img,
125 '--csv', skpdiff_csv_output, '-d', 'perceptual'])
126 with contextlib.closing(open(skpdiff_csv_output)) as csv_file:
127 for row in csv.DictReader(csv_file):
128 perceptual_similarity = float(row[' perceptual'].strip())
129 # skpdiff returns the perceptual similarity, convert it to get the
130 # perceptual difference percentage.
131 self._perceptual_difference = 100 - (perceptual_similarity * 100)
132 finally:
133 shutil.rmtree(skpdiff_csv_dir)
134
135 # Final touches on diff_image: use whitediff_image as an alpha mask. 102 # Final touches on diff_image: use whitediff_image as an alpha mask.
136 # Unchanged pixels are transparent; differing pixels are opaque. 103 # Unchanged pixels are transparent; differing pixels are opaque.
137 diff_image.putalpha(whitediff_image) 104 diff_image.putalpha(whitediff_image)
138 105
139 # Store the diff and whitediff images generated above. 106 # Store the diff and whitediff images generated above.
140 diff_image_locator = _get_difference_locator( 107 diff_image_locator = _get_difference_locator(
141 expected_image_locator=expected_image_locator, 108 expected_image_locator=expected_image_locator,
142 actual_image_locator=actual_image_locator) 109 actual_image_locator=actual_image_locator)
143 basename = str(diff_image_locator) + image_suffix 110 basename = str(diff_image_locator) + image_suffix
144 _save_image(diff_image, os.path.join( 111 _save_image(diff_image, os.path.join(
145 storage_root, DIFFS_SUBDIR, basename)) 112 storage_root, DIFFS_SUBDIR, basename))
146 _save_image(whitediff_image, os.path.join( 113 _save_image(whitediff_image, os.path.join(
147 storage_root, WHITEDIFFS_SUBDIR, basename)) 114 storage_root, WHITEDIFFS_SUBDIR, basename))
148 115
149 # Calculate difference metrics. 116 # Calculate difference metrics.
150 (self._width, self._height) = diff_image.size 117 (self._width, self._height) = diff_image.size
151 self._num_pixels_differing = ( 118 self._num_pixels_differing = (
152 whitediff_image.histogram()[VALUES_PER_BAND - 1]) 119 whitediff_image.histogram()[VALUES_PER_BAND - 1])
153 120
154 def get_num_pixels_differing(self): 121 def get_num_pixels_differing(self):
155 """Returns the absolute number of pixels that differ.""" 122 """Returns the absolute number of pixels that differ."""
156 return self._num_pixels_differing 123 return self._num_pixels_differing
157 124
158 def get_percent_pixels_differing(self): 125 def get_percent_pixels_differing(self):
159 """Returns the percentage of pixels that differ, as a float between 126 """Returns the percentage of pixels that differ, as a float between
160 0 and 100 (inclusive).""" 127 0 and 100 (inclusive)."""
161 return ((float(self._num_pixels_differing) * 100) / 128 return ((float(self._num_pixels_differing) * 100) /
162 (self._width * self._height)) 129 (self._width * self._height))
163 130
164 def get_perceptual_difference(self):
165 """Returns the perceptual difference percentage."""
166 return self._perceptual_difference
167
168 def get_weighted_diff_measure(self): 131 def get_weighted_diff_measure(self):
169 """Returns a weighted measure of image diffs, as a float between 0 and 100 132 """Returns a weighted measure of image diffs, as a float between 0 and 100
170 (inclusive).""" 133 (inclusive)."""
171 return self._weighted_diff_measure 134 return self._weighted_diff_measure
172 135
173 def get_max_diff_per_channel(self): 136 def get_max_diff_per_channel(self):
174 """Returns the maximum difference between the expected and actual images 137 """Returns the maximum difference between the expected and actual images
175 for each R/G/B channel, as a list.""" 138 for each R/G/B channel, as a list."""
176 return self._max_diff_per_channel 139 return self._max_diff_per_channel
177 140
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 356
394 Args: 357 Args:
395 expected_image_locator: locator string pointing at expected image 358 expected_image_locator: locator string pointing at expected image
396 actual_image_locator: locator string pointing at actual image 359 actual_image_locator: locator string pointing at actual image
397 360
398 Returns: already-sanitized locator where the diffs between expected and 361 Returns: already-sanitized locator where the diffs between expected and
399 actual images can be found 362 actual images can be found
400 """ 363 """
401 return "%s-vs-%s" % (_sanitize_locator(expected_image_locator), 364 return "%s-vs-%s" % (_sanitize_locator(expected_image_locator),
402 _sanitize_locator(actual_image_locator)) 365 _sanitize_locator(actual_image_locator))
OLDNEW
« no previous file with comments | « no previous file | gm/rebaseline_server/imagediffdb_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698