00001 /*!@file TestSuite/app-imageCompare.C Helper program for the test suite to compare two or more images */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/TestSuite/app-imageCompare.C $ 00035 // $Id: app-imageCompare.C 14290 2010-12-01 21:44:03Z itti $ 00036 // 00037 00038 #if defined INVT_HAVE_QT3 || defined INVT_HAVE_QT4 00039 # define IMAGECOMPARE_USE_QT 1 00040 #endif 00041 00042 #include "Component/ModelManager.H" 00043 #include "Component/ModelOptionDef.H" 00044 #include "Component/ModelParam.H" 00045 #ifdef IMAGECOMPARE_USE_QT 00046 # ifdef INVT_HAVE_QT4 00047 # include "GUI/QtDisplayStream4.H" // use Qt4 if available 00048 # else 00049 # include "GUI/QtDisplayStream.H" 00050 # endif 00051 #else 00052 # include "GUI/ImageDisplayStream.H" 00053 #endif 00054 #include "Image/ColorOps.H" 00055 #include "Image/MathOps.H" 00056 #include "Image/Image.H" 00057 #include "Image/Pixels.H" 00058 #include "Raster/GenericFrame.H" 00059 #include "Raster/Raster.H" 00060 #include "Transport/FrameInfo.H" 00061 00062 #include <cstdio> 00063 #include <cstdlib> 00064 #include <unistd.h> 00065 #include <vector> 00066 00067 static Image<float> rectify(const Image<float>& x) 00068 { 00069 Image<float> y(x); 00070 inplaceRectify(y); 00071 return y; 00072 } 00073 00074 static Image<PixRGB<float> > rectifyRgb(const Image<PixRGB<float> >& x) 00075 { 00076 Image<float> r, g, b; 00077 getComponents(x, r, g, b); 00078 return makeRGB(rectify(r), rectify(g), rectify(b)); 00079 } 00080 00081 template <class T> 00082 static Image<byte> findNonZero(const Image<T>& x) 00083 { 00084 Image<byte> result(x.getDims(), NO_INIT); 00085 00086 typename Image<T>::const_iterator sptr = x.begin(); 00087 Image<byte>::iterator dptr = result.beginw(); 00088 Image<byte>::iterator stop = result.endw(); 00089 00090 const T zero = T(); 00091 00092 while (dptr != stop) { *dptr++ = (*sptr++ == zero) ? 0 : 255; } 00093 00094 return result; 00095 } 00096 00097 static const ModelOptionDef OPT_Compare = 00098 { MODOPT_FLAG, "Compare", &MOC_GENERAL, OPTEXP_CORE, 00099 "Whether to show comparisons between images (otherwise, just the images themselves will be shown)", 00100 "compare", '\0', "", "true" }; 00101 00102 int main(int argc, char** argv) 00103 { 00104 MYLOGVERB = LOG_CRIT; 00105 00106 ModelManager mgr("imageCompare"); 00107 OModelParam<bool> docompare(&OPT_Compare, &mgr); 00108 00109 #ifdef IMAGECOMPARE_USE_QT 00110 nub::ref<FrameOstream> ofs(new QtDisplayStream(mgr)); 00111 #else 00112 nub::ref<FrameOstream> ofs(new ImageDisplayStream(mgr)); 00113 #endif 00114 mgr.addSubComponent(ofs); 00115 00116 if (mgr.parseCommandLine(argc, argv, "image1 [image2 [image3 ...]]", 1, -1) == false) 00117 return(1); 00118 00119 mgr.start(); 00120 00121 std::vector<GenericFrame> im; 00122 std::vector<std::string> imname; 00123 00124 for (uint i = 0; i < mgr.numExtraArgs(); ++i) 00125 { 00126 imname.push_back(mgr.getExtraArg(i)); 00127 00128 im.push_back(Raster::ReadFrame(imname.back())); 00129 00130 im.back().setFloatFlags(FLOAT_NORM_0_255); 00131 00132 ofs->writeFrame(im.back(), sformat("image%u",i+1), FrameInfo(imname.back(), SRC_POS)); 00133 } 00134 00135 if (docompare.getVal()) 00136 for (size_t i = 0; i < im.size(); ++i) 00137 { 00138 const GenericFrame im1 = im[i]; 00139 00140 for (size_t j = i+1; j < im.size(); ++j) 00141 { 00142 const GenericFrame im2 = im[j]; 00143 00144 if (im1.getDims() != im2.getDims()) 00145 continue; 00146 00147 GenericFrame im1_greater_than_im2, im2_greater_than_im1, im1_neq_im2; 00148 00149 switch (im1.nativeType()) 00150 { 00151 case GenericFrame::NONE: 00152 case GenericFrame::RGB_U8: 00153 case GenericFrame::RGBD: 00154 case GenericFrame::RGB_F32: 00155 case GenericFrame::VIDEO: 00156 im1_greater_than_im2 = GenericFrame(rectifyRgb(im1.asRgbF32() - im2.asRgbF32()), FLOAT_NORM_0_255); 00157 im2_greater_than_im1 = GenericFrame(rectifyRgb(im2.asRgbF32() - im1.asRgbF32()), FLOAT_NORM_0_255); 00158 im1_neq_im2 = GenericFrame(findNonZero(im1.asRgbF32() - im2.asRgbF32())); 00159 break; 00160 00161 case GenericFrame::GRAY_U8: 00162 case GenericFrame::GRAY_F32: 00163 im1_greater_than_im2 = GenericFrame(rectify(im1.asGrayF32() - im2.asGrayF32()), FLOAT_NORM_0_255); 00164 im2_greater_than_im1 = GenericFrame(rectify(im2.asGrayF32() - im1.asGrayF32()), FLOAT_NORM_0_255); 00165 im1_neq_im2 = GenericFrame(findNonZero(im1.asGrayF32() - im2.asGrayF32())); 00166 break; 00167 00168 case GenericFrame::RGB_U16: break; 00169 case GenericFrame::GRAY_U16: break; 00170 } 00171 00172 ofs->writeFrame(im1_greater_than_im2, sformat("image%"ZU">image%"ZU"", i+1, j+1), 00173 FrameInfo(imname[i] + " > " + imname[j], SRC_POS)); 00174 ofs->writeFrame(im2_greater_than_im1, sformat("image%"ZU">image%"ZU"", j+1, i+1), 00175 FrameInfo(imname[j] + " > " + imname[i], SRC_POS)); 00176 ofs->writeFrame(im1_neq_im2, sformat("image%"ZU"!=image%"ZU"", i+1, j+1), 00177 FrameInfo(imname[i] + " != " + imname[j], SRC_POS)); 00178 } 00179 } 00180 00181 while (!ofs->isVoid()) sleep(1); 00182 00183 mgr.stop(); 00184 } 00185 00186 // ###################################################################### 00187 /* So things look consistent in everyone's emacs... */ 00188 /* Local Variables: */ 00189 /* mode: c++ */ 00190 /* indent-tabs-mode: nil */ 00191 /* End: */