00001 /* 00002 File: ImageComp.cc 00003 00004 Function: Compare two image files 00005 00006 Author: Andrew Willmott 00007 00008 Notes: 00009 */ 00010 00011 #include "cl/ArgParse.h" 00012 #include <stdlib.h> 00013 #include <unistd.h> 00014 00015 #include "gcl/Image.h" 00016 #include "gcl/XGraphicsSystem.h" 00017 #include "cl/Action.h" 00018 00019 Void ApplyToImageDiff(Action<ClrReal> &action, Image &image1, Image &image2, 00020 ImgChannel chn = chMono) 00021 { 00022 Int i, j; 00023 ClrReal temp; 00024 00025 action.Start(); 00026 00027 for (i = 0; i < image1.Height(); i++) 00028 for (j = 0; j < image1.Width(); j++) 00029 { 00030 temp = image1.GetRealPixel(j, i, chn) - image2.GetRealPixel(j, i, chn); 00031 action.Process(temp); 00032 } 00033 00034 action.Stop(); 00035 } 00036 00037 ClrReal AbsImageDiff(Image &image1, Image &image2, Image &destImage) 00038 { 00039 Int i, j; 00040 Colour c; 00041 ClrReal maxCmpt = 0.0; 00042 00043 for (i = 0; i < image1.Height(); i++) 00044 for (j = 0; j < image1.Width(); j++) 00045 { 00046 Colour a = image1.GetPixel(j, i); 00047 Colour b = image2.GetPixel(j, i); 00048 00049 c = a - b; 00050 c[0] = abs(c[0]); 00051 c[1] = abs(c[1]); 00052 c[2] = abs(c[2]); 00053 00054 maxCmpt = Max(maxCmpt, Max(c[0], Max(c[1], c[2]))); 00055 destImage.SetPixel(j, i, c); 00056 } 00057 00058 return(maxCmpt); 00059 } 00060 00061 00062 // --- Main Program ----------------------------------------------------------- 00063 00064 00065 Int main(Int argc, Char **argv) 00066 { 00067 XGraphicsSystem *gs; 00068 StatsFinder<ClrReal> rstats, bstats, gstats; 00069 RGBAImage img1, img2, imgDiff; 00070 XOffscreenPane *offImg; 00071 XBackedPane *window; 00072 FileName fpath; 00073 Char *file1, *file2; 00074 Int useWin, noFork; 00075 ClrReal maxCmpt; 00076 00077 // command-line options 00078 00079 if (arg_parse(argc, argv, 00080 "", "usage: prog [options]", 00081 00082 "%S", &file1, "image file 1", 00083 "%S", &file2, "image file 2", 00084 00085 // Output options 00086 00087 "-window", ARG_FLAG(&useWin), "display image differences in window", 00088 "-noFork", ARG_FLAG(&noFork), "Don't fork into background", 00089 0) < 0) 00090 exit(1); 00091 00092 // Read two images 00093 00094 fpath.SetPath(file1); 00095 if (img1.Load(fpath) != 0) 00096 exit(1); 00097 00098 if (useWin) 00099 { 00100 #ifndef DEBUG 00101 if (!noFork && fork()) 00102 return(0); 00103 #endif 00104 gs = new XGraphicsSystem; 00105 offImg = new XOffscreenPane; 00106 gs->CreateOffscreen(offImg, img1.Width(), img1.Height()); 00107 window = new XBackedPane; 00108 gs->CreateWindow(window, "difference", img1.Width(), img1.Height()); 00109 offImg->PutImage(img1); 00110 window->Attach(offImg); 00111 window->HandleExpose(); 00112 gs->Spin(); 00113 } 00114 00115 fpath.SetPath(file2); 00116 if (img2.Load(fpath) != 0) 00117 exit(1); 00118 00119 if (img2.Width() != img1.Width() || img2.Height() != img1.Height()) 00120 { 00121 cerr << "Error: picture dimensions don't match." << endl; 00122 exit(1); 00123 } 00124 00125 if (useWin) 00126 { 00127 offImg->PutImage(img2); 00128 window->HandleExpose(); 00129 gs->Spin(); 00130 } 00131 00132 // Compare... 00133 00134 ApplyToImageDiff(rstats, img1, img2, chRed); 00135 ApplyToImageDiff(gstats, img1, img2, chGreen); 00136 ApplyToImageDiff(bstats, img1, img2, chBlue); 00137 00138 cout << "mean_R " << rstats.mean << endl; 00139 cout << "var_R " << rstats.variance << endl; 00140 cout << "dev_R " << sqrt(rstats.variance) << endl; 00141 cout << endl; 00142 cout << "mean_G " << gstats.mean << endl; 00143 cout << "var_G " << gstats.variance << endl; 00144 cout << "dev_G " << sqrt(gstats.variance) << endl; 00145 cout << endl; 00146 cout << "mean_B " << bstats.mean << endl; 00147 cout << "var_B " << bstats.variance << endl; 00148 cout << "dev_B " << sqrt(bstats.variance) << endl; 00149 cout << endl; 00150 cout << "mean_L " << dot(cRGBToLum, Colour(rstats.mean, gstats.mean, bstats.mean)) << endl; 00151 cout << "var_L " << dot(cRGBToLum, Colour(rstats.variance, gstats.variance, bstats.variance)) << endl; 00152 cout << "dev_L " << sqrt(dot(cRGBToLum, Colour(rstats.variance, gstats.variance, bstats.variance))) << endl; 00153 00154 if (useWin) 00155 { 00156 imgDiff.SetSize(img1.Width(), img1.Height()); 00157 maxCmpt = AbsImageDiff(img1, img2, imgDiff); 00158 imgDiff.Scale(1.0 / maxCmpt); 00159 00160 offImg->PutImage(imgDiff); 00161 window->HandleExpose(); 00162 gs->Run(); 00163 } 00164 00165 return(0); 00166 }