| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 Metric | 2 Metric |
| 3 Copyright (C) 2006 Yangli Hector Yee | 3 Copyright (C) 2006 Yangli Hector Yee |
| 4 | 4 |
| 5 This program is free software; you can redistribute it and/or modify it under th e terms of the | 5 This program is free software; you can redistribute it and/or modify it under th e terms of the |
| 6 GNU General Public License as published by the Free Software Foundation; either version 2 of the License, | 6 GNU General Public License as published by the Free Software Foundation; either version 2 of the License, |
| 7 or (at your option) any later version. | 7 or (at your option) any later version. |
| 8 | 8 |
| 9 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; | 9 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
| 10 without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 10 without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 for (int i = 0; i < 3; i++) { | 113 for (int i = 0; i < 3; i++) { |
| 114 if (r[i] > epsilon) { | 114 if (r[i] > epsilon) { |
| 115 f[i] = powf(r[i], 1.0f / 3.0f); | 115 f[i] = powf(r[i], 1.0f / 3.0f); |
| 116 } else { | 116 } else { |
| 117 f[i] = (kappa * r[i] + 16.0f) / 116.0f; | 117 f[i] = (kappa * r[i] + 16.0f) / 116.0f; |
| 118 } | 118 } |
| 119 } | 119 } |
| 120 L = 116.0f * f[1] - 16.0f; | 120 L = 116.0f * f[1] - 16.0f; |
| 121 A = 500.0f * (f[0] - f[1]); | 121 A = 500.0f * (f[0] - f[1]); |
| 122 B = 200.0f * (f[1] - f[2]); | 122 B = 200.0f * (f[1] - f[2]); |
| 123 } | |
| 124 | |
| 125 | |
| 126 // simple convolution based edge detection with a 3-by-3 size kernel. | |
| 127 // edgeImg is the result, pixel is either 255 which means an edge point | |
| 128 // or 0 means it is not edge, based on whether the result | |
| 129 // of convolution is larger than pre-defiend threshold or not. | |
| 130 void DetectEdge(RGBAImage* diffImg, int* edgeImg, unsigned int w, | |
| 131 unsigned int h, int edgeNeighborNum) { | |
| 132 // define the kernel for convolution. | |
| 133 int kernelLength = 3; | |
| 134 int kernel[9] = {-1, -1, -1, -1, 8, -1, -1, -1, -1}; | |
| 135 unsigned int x = 0, y = 0; | |
| 136 int cx = 0, cy = 0; | |
| 137 | |
| 138 // threshold based on edgeNeighborNum | |
| 139 // edgeNeighborNum is the max number of neighbors | |
| 140 // a pixel could have to be considered as | |
| 141 // edges. | |
| 142 int threshold = (8 - edgeNeighborNum) * 255; | |
| 143 | |
| 144 // shrink the image by 1 pixel to avoid checking boundaries. | |
| 145 for (y = 1; y < h - 1; y++) { | |
| 146 for (x = 1; x < w - 1; x++) { | |
| 147 int index = y * w + x; | |
| 148 edgeImg[index] = 0; | |
| 149 for (cx = -1; cx <=1; cx++) { | |
| 150 for (cy = -1; cy <= 1; cy++) { | |
| 151 int nx = x + cx; | |
| 152 int ny = y + cy; | |
| 153 edgeImg[index] += | |
| 154 diffImg->Get_Red(ny * w + nx) * | |
| 155 kernel[(cy + 1) * kernelLength + cx + 1]; | |
| 156 } | |
| 157 } | |
| 158 | |
| 159 if (edgeImg[index] >= threshold) | |
| 160 edgeImg[index] = 255; | |
| 161 else | |
| 162 edgeImg[index] = 0; | |
| 163 } | |
| 164 } | |
| 123 } | 165 } |
| 124 | 166 |
| 125 bool Yee_Compare(CompareArgs &args) | 167 bool Yee_Compare(CompareArgs &args) |
| 126 { | 168 { |
| 127 if ((args.ImgA->Get_Width() != args.ImgB->Get_Width()) || | 169 if ((args.ImgA->Get_Width() != args.ImgB->Get_Width()) || |
| 128 (args.ImgA->Get_Height() != args.ImgB->Get_Height())) { | 170 (args.ImgA->Get_Height() != args.ImgB->Get_Height())) { |
| 129 args.ErrorStr = "Image dimensions do not match\n"; | 171 args.ErrorStr = "Image dimensions do not match\n"; |
| 130 return false; | 172 return false; |
| 131 } | 173 } |
| 132 | 174 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 283 if (bZ) delete[] bZ; | 325 if (bZ) delete[] bZ; |
| 284 if (aLum) delete[] aLum; | 326 if (aLum) delete[] aLum; |
| 285 if (bLum) delete[] bLum; | 327 if (bLum) delete[] bLum; |
| 286 if (la) delete la; | 328 if (la) delete la; |
| 287 if (lb) delete lb; | 329 if (lb) delete lb; |
| 288 if (aA) delete aA; | 330 if (aA) delete aA; |
| 289 if (bA) delete bA; | 331 if (bA) delete bA; |
| 290 if (aB) delete aB; | 332 if (aB) delete aB; |
| 291 if (bB) delete bB; | 333 if (bB) delete bB; |
| 292 | 334 |
| 335 if (args.IgnoreEdge) | |
| 336 { | |
| 337 int* edgeImg = new int[w * h]; | |
| 338 | |
| 339 // run convolution based edge detection algorithm. | |
| 340 DetectEdge(args.ImgDiff, edgeImg, w, h, args.EdgeNeighborNum); | |
| 341 | |
| 342 // delete edge pixels from the result image. | |
| 343 for (y = 1; y < h - 1; y++) { | |
| 344 for (x = 1; x < w - 1; x++) { | |
| 345 unsigned int index = y * w + x; | |
| 346 if (args.ImgDiff->Get_Red(index) == 255 && | |
| 347 edgeImg[index] == 255) { | |
| 348 args.ImgDiff->Set(0, 0, 0, 255, index); | |
| 349 pixels_failed--; | |
| 350 } | |
| 351 } | |
| 352 } | |
| 353 | |
| 354 delete[] edgeImg; | |
| 355 } | |
| 356 | |
| 293 char different[100]; | 357 char different[100]; |
| 294 sprintf(different, "%d pixels are different\n", pixels_failed); | 358 sprintf(different, "%d pixels are different\n", pixels_failed); |
| 295 | 359 |
| 296 // Always output image difference if requested. | 360 // Always output image difference if requested. |
| 297 » if (args.ImgDiff) { | 361 » if (args.ImgDiff) |
| 298 » » if (args.ImgDiff->WriteToFile(args.ImgDiff->Get_Name().c_str())) { | 362 » { |
|
vangelis
2009/07/09 02:43:29
seems to be some extra whitespace after the { . Pl
| |
| 299 » » » args.ErrorStr += "Wrote difference image to "; | 363 » » if (args.ImgDiff->Get_Name().size() > 0) { |
| 300 » » » args.ErrorStr+= args.ImgDiff->Get_Name(); | 364 » » » if (args.ImgDiff->WriteToFile( |
| 301 » » » args.ErrorStr += "\n"; | 365 args.ImgDiff->Get_Name().c_str())) { |
| 302 » » } else { | 366 » » » » args.ErrorStr += "Wrote difference image to "; |
| 303 » » » args.ErrorStr += "Could not write difference image to "; | 367 » » » » args.ErrorStr+= args.ImgDiff->Get_Name(); |
| 304 » » » args.ErrorStr+= args.ImgDiff->Get_Name(); | 368 » » » » args.ErrorStr += "\n"; |
| 305 » » » args.ErrorStr += "\n"; | 369 » » » } else { |
| 370 » » » » args.ErrorStr += | |
| 371 "Could not write difference image to "; | |
| 372 » » » » args.ErrorStr+= args.ImgDiff->Get_Name(); | |
| 373 » » » » args.ErrorStr += "\n"; | |
| 374 » » » } | |
| 306 } | 375 } |
| 307 } | 376 } |
| 308 | |
| 309 if (pixels_failed < args.ThresholdPixels) { | 377 if (pixels_failed < args.ThresholdPixels) { |
| 310 args.ErrorStr = "Images are perceptually indistinguishable\n"; | 378 args.ErrorStr = "Images are perceptually indistinguishable\n"; |
| 311 args.ErrorStr += different; | 379 args.ErrorStr += different; |
| 312 return true; | 380 return true; |
| 313 } | 381 } |
| 314 | 382 |
| 315 args.ErrorStr = "Images are visibly different\n"; | 383 args.ErrorStr = "Images are visibly different\n"; |
| 316 args.ErrorStr += different; | 384 args.ErrorStr += different; |
| 317 | 385 |
| 318 return false; | 386 return false; |
| 319 } | 387 } |
| OLD | NEW |