Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix image comparison #1291

Merged
merged 20 commits into from
Feb 28, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3dcc2cb
Added new test suite, test_compare_images.
mgiuca-google Aug 28, 2012
2f139f2
Remove the alpha channel from the expected and actual images.
mgiuca-google Aug 28, 2012
82ecfcf
testing/compare: Fix image comparison RMS calculation.
mgiuca-google Aug 28, 2012
125d235
Do not divide RMS by 10000 when testing against tolerance.
mgiuca-google Aug 28, 2012
a344de6
Update the documentation to the 'tol' parameter.
mgiuca-google Sep 20, 2012
7a9a71b
compare: Use np.prod instead of Python reduce.
mgiuca-google Sep 24, 2012
4e12012
compare: Use int16 instead of int32 arrays.
mgiuca-google Sep 24, 2012
62a548d
compare: Simplify and speed up sum of squares algorithm.
pelson Sep 24, 2012
6edf6bc
test_compare_images: Added two new test cases, testing a whole-image …
mgiuca-google Sep 24, 2012
9701a43
compare: Use PEP-8 variable names.
mgiuca-google Sep 24, 2012
c855310
test_compare_images: Import nose.tools at the top, instead of in a fu…
mgiuca-google Jan 16, 2013
23b03aa
testing/compare: Remove "retry ignoring pixels with differences of on…
mgiuca-google Jan 16, 2013
80f89a1
test_compare_images: Fix errors on Python 2.6 because assert_is_none …
mgiuca-google Jan 16, 2013
91c969a
test_compare_images: Replace cosine_peak-nn test images with new base…
mgiuca-google Jan 18, 2013
64ae6c8
compare: PEP-8 formatting.
mgiuca-google Jan 18, 2013
8d44f75
tests: Removed existing custom tolerance values, since they are irrel…
mgiuca-google Jan 18, 2013
38b6157
Change spelling of 'colour' to 'color'.
mgiuca-google Jan 20, 2013
9d3e774
test_axes: Remove more arbitrary large tolerances.
mgiuca-google Jan 24, 2013
afc50bf
Update all of the images to use antialiased text
mdboom Jan 25, 2013
9410fcf
Reduce the tolerance for test_mathtext from 50 down to 32.
mgiuca-google Jan 24, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions lib/matplotlib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,7 @@ def tk_window_focus():
'matplotlib.tests.test_collections',
'matplotlib.tests.test_colorbar',
'matplotlib.tests.test_colors',
'matplotlib.tests.test_compare_images',
'matplotlib.tests.test_contour',
'matplotlib.tests.test_dates',
'matplotlib.tests.test_delaunay',
Expand Down
68 changes: 20 additions & 48 deletions lib/matplotlib/testing/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from distutils import version
import hashlib
import math
import operator
import os
import numpy as np
import shutil
Expand Down Expand Up @@ -251,37 +250,21 @@ def crop_to_same(actual_path, actual_image, expected_path, expected_image):
return actual_image, expected_image

def calculate_rms(expectedImage, actualImage):
# compare the resulting image histogram functions
expected_version = version.LooseVersion("1.6")
found_version = version.LooseVersion(np.__version__)
# calculate the per-pixel errors, then compute the root mean square error
num_values = np.prod(expectedImage.shape)
abs_diff_image = abs(expectedImage - actualImage)

# On Numpy 1.6, we can use bincount with minlength, which is much faster than
# using histogram
expected_version = version.LooseVersion("1.6")
found_version = version.LooseVersion(np.__version__)
if found_version >= expected_version:
rms = 0

for i in xrange(0, 3):
h1p = expectedImage[:,:,i]
h2p = actualImage[:,:,i]

h1h = np.bincount(h1p.ravel(), minlength=256)
h2h = np.bincount(h2p.ravel(), minlength=256)

rms += np.sum(np.power((h1h-h2h), 2))
histogram = np.bincount(abs_diff_image.ravel(), minlength=256)
else:
rms = 0
bins = np.arange(257)

for i in xrange(0, 3):
h1p = expectedImage[:,:,i]
h2p = actualImage[:,:,i]
histogram = np.histogram(abs_diff_image, bins=np.arange(257))[0]

h1h = np.histogram(h1p, bins=bins)[0]
h2h = np.histogram(h2p, bins=bins)[0]

rms += np.sum(np.power((h1h-h2h), 2))

rms = np.sqrt(rms / (256 * 3))
sum_of_squares = np.sum(histogram * np.arange(len(histogram))**2)
rms = np.sqrt(float(sum_of_squares) / num_values)

return rms

Expand All @@ -299,8 +282,9 @@ def compare_images( expected, actual, tol, in_decorator=False ):
= INPUT VARIABLES
- expected The filename of the expected image.
- actual The filename of the actual image.
- tol The tolerance (a unitless float). This is used to
determine the 'fuzziness' to use when comparing images.
- tol The tolerance (a color value difference, where 255 is the
maximal difference). The test fails if the average pixel
difference is greater than this value.
- in_decorator If called from image_comparison decorator, this should be
True. (default=False)
'''
Expand All @@ -316,37 +300,25 @@ def compare_images( expected, actual, tol, in_decorator=False ):
# open the image files and remove the alpha channel (if it exists)
expectedImage = _png.read_png_int( expected )
actualImage = _png.read_png_int( actual )
expectedImage = expectedImage[:, :, :3]
actualImage = actualImage[:, :, :3]

actualImage, expectedImage = crop_to_same(actual, actualImage, expected, expectedImage)

# compare the resulting image histogram functions
expected_version = version.LooseVersion("1.6")
found_version = version.LooseVersion(np.__version__)
# convert to signed integers, so that the images can be subtracted without
# overflow
expectedImage = expectedImage.astype(np.int16)
actualImage = actualImage.astype(np.int16)

rms = calculate_rms(expectedImage, actualImage)

diff_image = make_test_filename(actual, 'failed-diff')

if ( (rms / 10000.0) <= tol ):
if rms <= tol:
if os.path.exists(diff_image):
os.unlink(diff_image)
return None

# For Agg-rendered images, we can retry by ignoring pixels with
# differences of only 1
if extension == 'png':
# Remove differences of only 1
diffImage = np.abs(np.asarray(actualImage, dtype=np.int) -
np.asarray(expectedImage, dtype=np.int))
actualImage = np.where(diffImage <= 1, expectedImage, actualImage)

rms = calculate_rms(expectedImage, actualImage)

if ( (rms / 10000.0) <= tol ):
if os.path.exists(diff_image):
os.unlink(diff_image)
return None

save_diff_image( expected, actual, diff_image )

if in_decorator:
Expand All @@ -360,7 +332,7 @@ def compare_images( expected, actual, tol, in_decorator=False ):
else:
# old-style call from mplTest directory
msg = " Error: Image files did not match.\n" \
" RMS Value: " + str( rms / 10000.0 ) + "\n" \
" RMS Value: " + str( rms ) + "\n" \
" Expected:\n " + str( expected ) + "\n" \
" Actual:\n " + str( actual ) + "\n" \
" Difference:\n " + str( diff_image ) + "\n" \
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/testing/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def do_test():

yield (do_test,)

def image_comparison(baseline_images=None, extensions=None, tol=1e-3,
def image_comparison(baseline_images=None, extensions=None, tol=10,
freetype_version=None, remove_text=False,
savefig_kwarg=None):
"""
Expand Down
1 change: 0 additions & 1 deletion lib/matplotlib/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,3 @@ def setup():
rcParams['font.family'] = 'Bitstream Vera Sans'
rcParams['text.hinting'] = False
rcParams['text.hinting_factor'] = 8
rcParams['text.antialiased'] = False
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/axhspan_epoch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/axvspan_epoch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/boxplot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/canonical.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/const_xy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/fill_units.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/hist2d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/hist_stacked.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/imshow_clip.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/log_scales.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/markevery.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/offset_points.png
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/polar_axes.png
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/polar_coords.png
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/polar_rmin.png
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/polar_units.png
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/polar_units_2.png
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/scatter.png
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/shaped_data.png
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/single_date.png
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/single_point.png
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/symlog.png
Binary file modified lib/matplotlib/tests/baseline_images/test_dates/date_axhline.png
Binary file modified lib/matplotlib/tests/baseline_images/test_dates/date_axhspan.png
Binary file modified lib/matplotlib/tests/baseline_images/test_dates/date_axvline.png
Binary file modified lib/matplotlib/tests/baseline_images/test_dates/date_axvspan.png
Binary file modified lib/matplotlib/tests/baseline_images/test_dates/date_empty.png
Binary file modified lib/matplotlib/tests/baseline_images/test_image/image_clip.png
Binary file modified lib/matplotlib/tests/baseline_images/test_legend/framealpha.png
Binary file modified lib/matplotlib/tests/baseline_images/test_legend/scatter_rc1.png
Binary file modified lib/matplotlib/tests/baseline_images/test_legend/scatter_rc3.png
Loading