Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 82ecfcf

Browse files
committed
testing/compare: Fix image comparison RMS calculation.
The previous implementation did not compute the RMS error. It computed the RMS in the difference of the number of colour components of each value. While this computes 0 for equal images, it is incorrect in general. In particular, it does not detect differences in images with the same pixels in different places. It also cannot distinguish small changes in the colour of a pixel from large ones.
1 parent 2f139f2 commit 82ecfcf

1 file changed

Lines changed: 13 additions & 28 deletions

File tree

lib/matplotlib/testing/compare.py

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -251,37 +251,21 @@ def crop_to_same(actual_path, actual_image, expected_path, expected_image):
251251
return actual_image, expected_image
252252

253253
def calculate_rms(expectedImage, actualImage):
254-
# compare the resulting image histogram functions
255-
expected_version = version.LooseVersion("1.6")
256-
found_version = version.LooseVersion(np.__version__)
254+
# calculate the per-pixel errors, then compute the root mean square error
255+
num_values = reduce(operator.mul, expectedImage.shape)
256+
absDiffImage = abs(expectedImage - actualImage)
257257

258258
# On Numpy 1.6, we can use bincount with minlength, which is much faster than
259259
# using histogram
260+
expected_version = version.LooseVersion("1.6")
261+
found_version = version.LooseVersion(np.__version__)
260262
if found_version >= expected_version:
261-
rms = 0
262-
263-
for i in xrange(0, 3):
264-
h1p = expectedImage[:,:,i]
265-
h2p = actualImage[:,:,i]
266-
267-
h1h = np.bincount(h1p.ravel(), minlength=256)
268-
h2h = np.bincount(h2p.ravel(), minlength=256)
269-
270-
rms += np.sum(np.power((h1h-h2h), 2))
263+
histogram = np.bincount(absDiffImage.ravel(), minlength=256)
271264
else:
272-
rms = 0
273-
bins = np.arange(257)
274-
275-
for i in xrange(0, 3):
276-
h1p = expectedImage[:,:,i]
277-
h2p = actualImage[:,:,i]
278-
279-
h1h = np.histogram(h1p, bins=bins)[0]
280-
h2h = np.histogram(h2p, bins=bins)[0]
265+
histogram = np.histogram(absDiffImage, bins=np.arange(257))[0]
281266

282-
rms += np.sum(np.power((h1h-h2h), 2))
283-
284-
rms = np.sqrt(rms / (256 * 3))
267+
sumOfSquares = sum(count*(i**2) for i, count in enumerate(histogram))
268+
rms = np.sqrt(float(sumOfSquares) / num_values)
285269

286270
return rms
287271

@@ -321,9 +305,10 @@ def compare_images( expected, actual, tol, in_decorator=False ):
321305

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

324-
# compare the resulting image histogram functions
325-
expected_version = version.LooseVersion("1.6")
326-
found_version = version.LooseVersion(np.__version__)
308+
# convert to signed integers, so that the images can be subtracted without
309+
# overflow
310+
expectedImage = expectedImage.astype(np.int32)
311+
actualImage = actualImage.astype(np.int32)
327312

328313
rms = calculate_rms(expectedImage, actualImage)
329314

0 commit comments

Comments
 (0)