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

Side by Side Diff: cc/test/pixel_comparator.cc

Issue 12558003: cc: Made image comparison for pixel tests error tolerant. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase to tip of tree. Added discard_alpha flag. Created 7 years, 8 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
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/test/pixel_comparator.h"
6
7 #include <algorithm>
8
9 #include "base/logging.h"
10
11 namespace cc {
12
13 ExactPixelComparator::ExactPixelComparator(const bool discard_alpha)
14 : discard_alpha_(discard_alpha) {
15 }
16
17 bool ExactPixelComparator::Compare(const SkBitmap& actual_bmp,
18 const SkBitmap& expected_bmp) const {
19 // Number of pixels with an error
20 int error_pixels_count = 0;
21
22 // Check that bitmaps have identical dimensions.
23 DCHECK(actual_bmp.width() == expected_bmp.width() &&
24 actual_bmp.height() == expected_bmp.height());
25
26 SkAutoLockPixels lock_actual_bmp(actual_bmp);
27 SkAutoLockPixels lock_expected_bmp(expected_bmp);
28
29 for (int x = 0; x < actual_bmp.width(); ++x) {
30 for (int y = 0; y < actual_bmp.height(); ++y) {
31 SkColor actual_color = actual_bmp.getColor(x, y);
32 SkColor expected_color = expected_bmp.getColor(x, y);
33 if (discard_alpha_) {
34 SkColorSetA(actual_color, 0);
35 SkColorSetA(expected_color, 0);
36 }
37
38 if (actual_color != expected_color) {
39 ++error_pixels_count;
danakj 2013/03/28 22:17:25 How about logging the pixel differences here as we
danakj 2013/03/28 22:18:57 Or, I guess we don't on TOT. We would when https:/
ernstm 2013/03/28 23:10:26 Done.
40 }
41 }
42 }
43
44 if (error_pixels_count != 0) {
45 LOG(ERROR) << "Number of pixel with an error: " << error_pixels_count;
46 return false;
47 }
48
49 return true;
50 }
51
52 FuzzyPixelComparator::FuzzyPixelComparator(
53 const bool discard_alpha,
54 const float error_pixels_percentage_limit,
55 const float small_error_pixels_percentage_limit,
56 const float avg_abs_error_limit,
57 const int max_abs_error_limit,
58 const int small_error_threshold)
59 : discard_alpha_(discard_alpha),
60 error_pixels_percentage_limit_(error_pixels_percentage_limit),
61 small_error_pixels_percentage_limit_(small_error_pixels_percentage_limit),
62 avg_abs_error_limit_(avg_abs_error_limit),
63 max_abs_error_limit_(max_abs_error_limit),
64 small_error_threshold_(small_error_threshold) {
65 }
66
67 bool FuzzyPixelComparator::Compare(const SkBitmap& actual_bmp,
68 const SkBitmap& expected_bmp) const {
69 // Number of pixels with an error
70 int error_pixels_count = 0;
71 // Number of pixels with a small error
72 int small_error_pixels_count = 0;
73 // The per channel sums of absolute errors over all pixels.
74 int64 sum_abs_error_r = 0;
75 int64 sum_abs_error_g = 0;
76 int64 sum_abs_error_b = 0;
77 int64 sum_abs_error_a = 0;
78 // The per channel maximum absolute errors over all pixels.
79 int max_abs_error_r = 0;
80 int max_abs_error_g = 0;
81 int max_abs_error_b = 0;
82 int max_abs_error_a = 0;
83
84 // Check that bitmaps have identical dimensions.
85 DCHECK(actual_bmp.width() == expected_bmp.width() &&
86 actual_bmp.height() == expected_bmp.height());
87
88 // Check that bitmaps are not empty.
89 DCHECK(actual_bmp.width() > 0 && actual_bmp.height() > 0);
90
91 SkAutoLockPixels lock_actual_bmp(actual_bmp);
92 SkAutoLockPixels lock_expected_bmp(expected_bmp);
93
94 for (int x = 0; x < actual_bmp.width(); ++x) {
95 for (int y = 0; y < actual_bmp.height(); ++y) {
96 SkColor actual_color = actual_bmp.getColor(x, y);
97 SkColor expected_color = expected_bmp.getColor(x, y);
98 if (discard_alpha_) {
99 SkColorSetA(actual_color, 0);
100 SkColorSetA(expected_color, 0);
101 }
102
103 if (actual_color != expected_color) {
104 ++error_pixels_count;
105
106 // Compute per channel errors
107 int error_r = SkColorGetR(actual_color) - SkColorGetR(expected_color);
108 int error_g = SkColorGetG(actual_color) - SkColorGetG(expected_color);
109 int error_b = SkColorGetB(actual_color) - SkColorGetB(expected_color);
110 int error_a = SkColorGetA(actual_color) - SkColorGetA(expected_color);
111 int abs_error_r = std::abs(error_r);
112 int abs_error_g = std::abs(error_g);
113 int abs_error_b = std::abs(error_b);
114 int abs_error_a = std::abs(error_a);
115
116 // Increment small error counter if error is below threshold
117 if (abs_error_r <= small_error_threshold_ &&
118 abs_error_g <= small_error_threshold_ &&
119 abs_error_b <= small_error_threshold_ &&
120 abs_error_a <= small_error_threshold_)
121 ++small_error_pixels_count;
122
123 // Update per channel maximum absolute errors
124 max_abs_error_r = std::max(max_abs_error_r, abs_error_r);
125 max_abs_error_g = std::max(max_abs_error_g, abs_error_g);
126 max_abs_error_b = std::max(max_abs_error_b, abs_error_b);
127 max_abs_error_a = std::max(max_abs_error_a, abs_error_a);
128
129 // Update per channel absolute error sums
130 sum_abs_error_r += abs_error_r;
131 sum_abs_error_g += abs_error_g;
132 sum_abs_error_b += abs_error_b;
133 sum_abs_error_a += abs_error_a;
134 }
135 }
136 }
137
138 // Compute error metrics from collected data
139 int pixels_count = actual_bmp.width() * actual_bmp.height();
140 float error_pixels_percentage = 0.0f;
141 float small_error_pixels_percentage = 0.0f;
142 if (pixels_count > 0) {
143 error_pixels_percentage = static_cast<float>(error_pixels_count) /
144 pixels_count * 100.0f;
145 small_error_pixels_percentage =
146 static_cast<float>(small_error_pixels_count) / pixels_count * 100.0f;
147 }
148 float avg_abs_error_r = 0.0f;
149 float avg_abs_error_g = 0.0f;
150 float avg_abs_error_b = 0.0f;
151 float avg_abs_error_a = 0.0f;
152 if (error_pixels_count > 0) {
153 avg_abs_error_r = static_cast<float>(sum_abs_error_r) / error_pixels_count;
154 avg_abs_error_g = static_cast<float>(sum_abs_error_g) / error_pixels_count;
155 avg_abs_error_b = static_cast<float>(sum_abs_error_b) / error_pixels_count;
156 avg_abs_error_a = static_cast<float>(sum_abs_error_a) / error_pixels_count;
157 }
158
159 if (error_pixels_percentage > error_pixels_percentage_limit_ ||
160 small_error_pixels_percentage > small_error_pixels_percentage_limit_ ||
161 avg_abs_error_r > avg_abs_error_limit_ ||
162 avg_abs_error_g > avg_abs_error_limit_ ||
163 avg_abs_error_b > avg_abs_error_limit_ ||
164 avg_abs_error_a > avg_abs_error_limit_ ||
165 max_abs_error_r > max_abs_error_limit_ ||
166 max_abs_error_g > max_abs_error_limit_ ||
167 max_abs_error_b > max_abs_error_limit_ ||
168 max_abs_error_a > max_abs_error_limit_) {
169 LOG(ERROR) << "Percentage of pixels with an error: "
170 << error_pixels_percentage << "; "
171 << "Percentage of pixels with errors not greater than "
172 << small_error_threshold_ << ": "
173 << small_error_pixels_percentage << "; "
174 << "Average absolute error (excluding identical pixels): "
175 << "R=" << avg_abs_error_r << " "
176 << "G=" << avg_abs_error_g << " "
177 << "B=" << avg_abs_error_b << " "
178 << "A=" << avg_abs_error_a << "; "
179 << "Largest absolute error: "
180 << "R=" << max_abs_error_r << " "
181 << "G=" << max_abs_error_g << " "
182 << "B=" << max_abs_error_b << " "
183 << "A=" << max_abs_error_a;
184 return false;
185 } else {
186 return true;
187 }
188 }
189
190 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698