| LEFT | RIGHT |
|---|---|
| 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 } | 123 } |
| 124 | 124 |
| 125 | 125 |
| 126 // simple convolution based edge detection. | 126 // simple convolution based edge detection with a 3-by-3 size kernel. |
|
vangelis
2009/07/01 18:35:31
It would be helpful to expand a bit on the comment
| |
| 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. | |
| 127 void DetectEdge(RGBAImage* diffImg, int* edgeImg, unsigned int w, | 130 void DetectEdge(RGBAImage* diffImg, int* edgeImg, unsigned int w, |
| 128 unsigned int h, float edgeDetectDegree) { | 131 unsigned int h, int edgeNeighborNum) { |
|
vangelis
2009/07/01 18:35:31
move second line back by 1 space to align under th
| |
| 129 // define the kernel for convolution. | 132 // define the kernel for convolution. |
| 130 int kernelLength = 3; | 133 » int kernelLength = 3; |
| 131 int kernel[9] = {-1, -1, -1, -1, 8, -1, -1, -1, -1}; | 134 » int kernel[9] = {-1, -1, -1, -1, 8, -1, -1, -1, -1}; |
| 132 unsigned int x = 0, y = 0; | 135 » unsigned int x = 0, y = 0; |
| 133 int cx = 0, cy = 0; | 136 » int cx = 0, cy = 0; |
| 134 for (y = 0; y < h; y++) { | 137 |
| 135 for (x = 0; x < w; x++) { | 138 // threshold based on edgeNeighborNum |
|
vangelis
2009/07/01 18:35:31
best to use the same number of spaces for indentin
| |
| 136 int index = y * w + x; | 139 // edgeNeighborNum is the max number of neighbors |
| 137 edgeImg[index] = 0; | 140 // a pixel could have to be considered as |
| 138 for (cx = -1; cx <=1; cx++) { | 141 // edges. |
| 139 for (cy = -1; cy <= 1; cy++) { | 142 int threshold = (8 - edgeNeighborNum) * 255; |
| 140 int nx = x + cx; | 143 |
| 141 int ny = y + cy; | 144 » // shrink the image by 1 pixel to avoid checking boundaries. |
| 142 if (nx < 0) nx = -nx; | 145 » for (y = 1; y < h - 1; y++) { |
|
vangelis
2009/07/01 18:35:31
I mentioned this in the last review as well but I
| |
| 143 if (ny < 0) ny = -ny; | 146 » » for (x = 1; x < w - 1; x++) { |
| 144 if (nx >= w) nx = 2 * w - nx - 1; | 147 » » » int index = y * w + x; |
| 145 if (ny >= h) ny= 2 * h - ny - 1; | 148 » » » edgeImg[index] = 0; |
| 146 edgeImg[index] += diffImg->Get_Red(ny * w + nx) * | 149 » » for (cx = -1; cx <=1; cx++) { |
| 147 kernel[(cy + 1) * kernelLength + cx + 1]; | 150 » » » for (cy = -1; cy <= 1; cy++) { |
|
vangelis
2009/07/01 18:35:31
indent the line in to make it clear that it's cont
| |
| 148 } | 151 » » » » int nx = x + cx; |
| 149 } | 152 » » » » int ny = y + cy; |
| 150 // make it binary based on edgeDetectDegree. | 153 » » » » edgeImg[index] += |
| 151 // if edgeDetectDegree is 1, threshold is 0 | 154 » » » » diffImg->Get_Red(ny * w + nx) * |
| 152 // all edges would be ignored. | 155 » » » » kernel[(cy + 1) * kernelLength + cx + 1]; |
|
vangelis
2009/07/01 18:35:31
That's not quite true, right? If threshold is 0 z
| |
| 153 // if edgeDetectDegree is a small value near 0 | 156 » » » } |
| 154 // threshold is near 8X255, only scattered | 157 » » } |
| 155 // points would be ignored. | 158 |
| 156 int threshold = static_cast<int>((1.0f - edgeDetectDegree) * | 159 » » if (edgeImg[index] >= threshold) |
|
vangelis
2009/07/01 18:35:31
the threshold calculation should move outside the
| |
| 157 (8 * 255)); | 160 » » » edgeImg[index] = 255; |
| 158 if (edgeImg[index] > threshold) | 161 » » else |
| 159 edgeImg[index] = 255; | 162 » » » edgeImg[index] = 0; |
|
vangelis
2009/07/01 18:35:31
Use 4 space indent to stay consistent.
| |
| 160 else | 163 » » } |
| 161 edgeImg[index] = 0; | 164 » } |
| 162 } | |
| 163 } | |
| 164 } | 165 } |
| 165 | 166 |
| 166 bool Yee_Compare(CompareArgs &args) | 167 bool Yee_Compare(CompareArgs &args) |
| 167 { | 168 { |
| 168 if ((args.ImgA->Get_Width() != args.ImgB->Get_Width()) || | 169 if ((args.ImgA->Get_Width() != args.ImgB->Get_Width()) || |
| 169 (args.ImgA->Get_Height() != args.ImgB->Get_Height())) { | 170 (args.ImgA->Get_Height() != args.ImgB->Get_Height())) { |
| 170 args.ErrorStr = "Image dimensions do not match\n"; | 171 args.ErrorStr = "Image dimensions do not match\n"; |
| 171 return false; | 172 return false; |
| 172 } | 173 } |
| 173 | 174 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 324 if (bZ) delete[] bZ; | 325 if (bZ) delete[] bZ; |
| 325 if (aLum) delete[] aLum; | 326 if (aLum) delete[] aLum; |
| 326 if (bLum) delete[] bLum; | 327 if (bLum) delete[] bLum; |
| 327 if (la) delete la; | 328 if (la) delete la; |
| 328 if (lb) delete lb; | 329 if (lb) delete lb; |
| 329 if (aA) delete aA; | 330 if (aA) delete aA; |
| 330 if (bA) delete bA; | 331 if (bA) delete bA; |
| 331 if (aB) delete aB; | 332 if (aB) delete aB; |
| 332 if (bB) delete bB; | 333 if (bB) delete bB; |
| 333 | 334 |
| 334 » if (args.EdgeDetectDegree > 0.0f) | 335 » if (args.IgnoreEdge) |
| 335 { | 336 { |
| 336 int* edgeImg = new int[w * h]; | 337 » » int* edgeImg = new int[w * h]; |
|
vangelis
2009/07/01 18:35:31
code block needs to be indented
| |
| 337 | 338 |
| 338 // run convolution based edge detection algorithm. | 339 » » // run convolution based edge detection algorithm. |
| 339 DetectEdge(args.ImgDiff, edgeImg, w, h, args.EdgeDetectDegree); | 340 » » DetectEdge(args.ImgDiff, edgeImg, w, h, args.EdgeNeighborNum); |
| 340 | 341 |
| 341 // delete edge pixels from the result image. | 342 » » // delete edge pixels from the result image. |
| 342 for (y = 0; y < h; y++) { | 343 » » for (y = 1; y < h - 1; y++) { |
| 343 for (x = 0; x < w; x++) { | 344 » » » for (x = 1; x < w - 1; x++) { |
| 344 unsigned int index = y * w + x; | 345 » » » » unsigned int index = y * w + x; |
| 345 if (args.ImgDiff->Get_Red(index) == 255 && | 346 » » » » if (args.ImgDiff->Get_Red(index) == 255 && |
| 346 edgeImg[index] == 255) | 347 » » » » » edgeImg[index] == 255) { |
| 347 { | 348 » » » » » args.ImgDiff->Set(0, 0, 0, 255, index); |
| 348 args.ImgDiff->Set(0, 0, 0, 255, index); | 349 » » » » » pixels_failed--; |
| 349 pixels_failed--; | 350 » » » » } |
| 350 } | 351 » » » } |
| 351 } | 352 » » } |
| 352 } | |
| 353 | 353 |
| 354 delete[] edgeImg; | 354 delete[] edgeImg; |
| 355 } | 355 } |
| 356 | 356 |
| 357 char different[100]; | 357 char different[100]; |
| 358 sprintf(different, "%d pixels are different\n", pixels_failed); | 358 sprintf(different, "%d pixels are different\n", pixels_failed); |
| 359 | 359 |
| 360 // Always output image difference if requested. | 360 // Always output image difference if requested. |
| 361 if (args.ImgDiff) | 361 » if (args.ImgDiff) |
|
vangelis
2009/07/01 18:35:31
watch indentation
| |
| 362 { | 362 » { |
|
vangelis
2009/07/09 02:43:29
seems to be some extra whitespace after the { . Pl
| |
| 363 if (args.ImgDiff->Get_Name().size() > 0) { | 363 » » if (args.ImgDiff->Get_Name().size() > 0) { |
| 364 if (args.ImgDiff->WriteToFile(args.ImgDiff->Get_Name().c_str())) { | 364 » » » if (args.ImgDiff->WriteToFile( |
| 365 args.ErrorStr += "Wrote difference image to "; | 365 args.ImgDiff->Get_Name().c_str())) { |
| 366 args.ErrorStr+= args.ImgDiff->Get_Name(); | 366 » » » » args.ErrorStr += "Wrote difference image to "; |
| 367 args.ErrorStr += "\n"; | 367 » » » » args.ErrorStr+= args.ImgDiff->Get_Name(); |
| 368 } else { | 368 » » » » args.ErrorStr += "\n"; |
| 369 args.ErrorStr += "Could not write difference image to "; | 369 » » » } else { |
| 370 args.ErrorStr+= args.ImgDiff->Get_Name(); | 370 » » » » args.ErrorStr += |
| 371 args.ErrorStr += "\n"; | 371 "Could not write difference image to "; |
| 372 } | 372 » » » » args.ErrorStr+= args.ImgDiff->Get_Name(); |
| 373 } | 373 » » » » args.ErrorStr += "\n"; |
| 374 } | 374 » » » } |
| 375 » » } | |
| 376 » } | |
| 375 if (pixels_failed < args.ThresholdPixels) { | 377 if (pixels_failed < args.ThresholdPixels) { |
| 376 args.ErrorStr = "Images are perceptually indistinguishable\n"; | 378 args.ErrorStr = "Images are perceptually indistinguishable\n"; |
| 377 args.ErrorStr += different; | 379 args.ErrorStr += different; |
| 378 return true; | 380 return true; |
| 379 } | 381 } |
| 380 | 382 |
| 381 args.ErrorStr = "Images are visibly different\n"; | 383 args.ErrorStr = "Images are visibly different\n"; |
| 382 args.ErrorStr += different; | 384 args.ErrorStr += different; |
| 383 | 385 |
| 384 return false; | 386 return false; |
| 385 } | 387 } |
| LEFT | RIGHT |