00001 /*!@file VFAT/segmentImageMC2.H Basic image segmenter blob finder using color */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // 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: T. Nathan Mundhenk <mundhenk@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/VFAT/segmentImageMC2.H $ 00035 // $Id: segmentImageMC2.H 9898 2008-07-09 05:17:17Z mundhenk $ 00036 // 00037 00038 // ############################################################ 00039 // ############################################################ 00040 // ##### --- VFAT --- 00041 // ##### Vision Feature Analysis Tool: 00042 // ##### T. Nathan Mundhenk nathan@mundhenk.com 00043 // ##### Laurent Itti itti@pollux.usc.edu 00044 // ##### 00045 // ############################################################ 00046 // ############################################################ 00047 00048 #ifndef SEGMENTIMAGEMC2_H_DEFINED 00049 #define SEGMENTIMAGEMC2_H_DEFINED 00050 00051 #include "Image/All.H" 00052 #include "Image/Pixels.H" 00053 #include <time.h> 00054 #include <sys/time.h> 00055 00056 //******************************************* 00057 /* ABOUT THE USE OF TEMPLATES HERE 00058 00059 the INT value is an integer number and should be an unsigned 00060 number (but isn't required to be). However, for images larger 00061 than 256x256 after decimation 00062 e.g. that contain more than 2^16 pixels, you should use a long instead 00063 this is because the number of blobs may be as large as the number 00064 of pixels. 00065 00066 the FLOAT is for a floating point. A double may be used to obtain more 00067 accurate values at run time. This is at your discression 00068 00069 */ 00070 00071 //! Define the template declaration for this class 00072 #define SI_TEMPLATE_CLASS <class FLOAT, class INT, unsigned int SI_channels> 00073 //! further define templates for this class 00074 #define SI_TEMPLATE FLOAT,INT,SI_channels 00075 //! This is a class to track hyper spectal blobs 00076 /*! This class is most likely called by segmentImageTrackMC and will 00077 segment images by linking pixels and the corresponding image 00078 regions by linked stripes. It will also segregate each blob and 00079 track it seperately. 00080 */ 00081 template SI_TEMPLATE_CLASS class segmentImageMC2 00082 { 00083 public: 00084 //! create an object. Set true for RGB false for HSV 00085 /*! skews here are used to skew the curve towards one end of the threshold 00086 that is, you pick the ideal color value as val, the you pick the 00087 cut off threshold as thresh. You can then bias towads one end or the 00088 other by setting skew to +/- value, that value bing added to the 00089 upper or lower bound for the cut off depending on whether it is 00090 +/- that is, if its a neg. value then the lower bound is 00091 extended 00092 */ 00093 segmentImageMC2(); 00094 ~segmentImageMC2(); 00095 00096 //! set the Value (brightness) value you are looking for with thresh error 00097 /*! This method will set the threshold to be val +/- thresh. Thus, 00098 consider val to be the mean color you wish to track with a standard 00099 deviation like boundary as thresh. To set the high and low values 00100 directly use SIsetValThresh as an alternative. 00101 */ 00102 void SIsetVal(const typename std::vector<FLOAT> &val, 00103 const typename std::vector<FLOAT> &thresh); 00104 //! set the Value (brightness) value you are looking for with thresh error 00105 /*! Set threshold values directly as a boundary between high and low. 00106 If you wish to work more on mean values use SIsetVal instead. 00107 */ 00108 void SIsetValThresh(const typename std::vector<FLOAT> &high, 00109 const typename std::vector<FLOAT> &low); 00110 //! set the region of the image to inspect 00111 void SIsetFrame(int *x, int *y); 00112 //! Call during run if color is totally reset 00113 void SIresetCandidates(const bool whichWay); 00114 //! set up averaging for color averaging adaptation 00115 void SIsetAvg(const INT doAvg); 00116 //! reset averaging for color averaging adaptation 00117 void SIresetAvg(); 00118 //! segment image based upon parameters input (depricated) 00119 void SIsegment(Image<PixRGB<byte> > *image, 00120 typename std::vector<Image<FLOAT> > *featureMap, 00121 const bool lowPass = false); 00122 //! segment image based upon parameters input 00123 void SIsegment(typename std::vector<Image<FLOAT> > *featureMap, 00124 const bool lowPass = false); 00125 //! toggle band pass filter on candidate pixels on/off 00126 void SItoggleCandidateBandPass(const bool toggle); 00127 //! Turn on or off single removal: defaults to ON 00128 void SItoggleRemoveSingles(const bool toggle); 00129 //! override and set the kill value for removing singles 00130 void SIsetKillValue(const unsigned int kv); 00131 //! merge all blobs into one big blob, useful if you erase blobs 00132 /*! else just use returnCandidates */ 00133 Image<INT> SIcreateMother(const Image<INT> &img) const; 00134 //! return an image with labeled blobs. Use getBlobMap to map blobs 00135 Image<int> SIreturnBlobs() const; 00136 //! return a bool map off all candidate pixels 00137 Image<bool> SIreturnCandidates() const; 00138 //! return a normalized displayable map off all candidate pixels 00139 Image<FLOAT> SIreturnNormalizedCandidates() const; 00140 //! return the image that is being worked on, to check if its ok 00141 Image<PixRGB<FLOAT> > SIreturnWorkImage() const; 00142 //! return the total number of blobs 00143 INT SInumberBlobs() const; 00144 //! return a map of blobs that gives the numeric ID of a blob from the image 00145 std::vector<INT> SIgetBlobMap() const; 00146 //! calculate basic mass/center blob properties 00147 void SIcalcMassCenter(); 00148 //! get blob center in X 00149 FLOAT SIgetCenterX(const INT blob) const; 00150 //! get blob center in X 00151 FLOAT SIgetCenterY(const INT blob) const; 00152 //! get blob mass 00153 INT SIgetMass(const INT blob) const; 00154 //! get X min for a blob 00155 int SIgetXmin(const INT blob) const; 00156 //! get X max for a blob 00157 int SIgetXmax(const INT blob) const; 00158 //! get Y min for a blob 00159 int SIgetYmin(const INT blob) const; 00160 //! get Y max for a blob 00161 int SIgetYmax(const INT blob) const; 00162 //! get the working image size in X 00163 int SIgetImageSizeX() const; 00164 //! get the working image size in Y 00165 int SIgetImageSizeY() const; 00166 //! get HSV mean values and standard deviations for a blob 00167 void SIgetValue(INT *blob, typename std::vector<FLOAT> *mean, 00168 typename std::vector<FLOAT> *std, INT *in); 00169 //! do HVS color value means for x last iterations 00170 void SIgetValueMean(INT *blobListSize, 00171 std::vector<INT> *blobList, 00172 typename std::vector<FLOAT> *mean, 00173 typename std::vector<FLOAT> *std, 00174 FLOAT *mass); 00175 private: 00176 //! find any candidate pixel based upon pixel thresholding RGB 00177 void SIfindCandidates(); 00178 //! find any candidate pixel based upon pixel thresholding RGB 00179 void SIfindCandidatesNoBandPass(); 00180 //! remove single pixels without neighbors 00181 void SIremoveSingles(); 00182 //! remove single pixels without neighbors, iterator version with weird mem 00183 void SIremoveSinglesItr(); 00184 //! scan candidate image and link continious pixels with a unique ID tag 00185 void SIdiscreteLinking(); 00186 //! variant on discrete linking works orthogonally with iterators 00187 void SIdiscreteLinkingOrtho(); 00188 //! backward link pixels, find master, relabel masters 00189 void SIbackwardLink(const INT slave, const INT master); 00190 //! basic link pixels 00191 void SIbasicLink(const INT node); 00192 //! combine slaves together into single blobs 00193 void SIcombine(); 00194 //! get information on blobs for debugging 00195 void SIgetBlobs(); 00196 //! Call to segmentation which calls most of these methods 00197 void SIdoSegment(); 00198 Image<PixRGB<byte> > *SI_workImage; 00199 Image<bool> SI_candidatePixels; 00200 Image<bool> SI_preCandidatePixels; 00201 Image<int> SI_blobID; 00202 // color properties for averageing 00203 typename std::vector<std::vector<FLOAT> > SI_avg; 00204 typename std::vector<std::vector<FLOAT> > SI_std; 00205 typename std::vector<Image<FLOAT> > *SI_featureMaps; 00206 typename std::vector<Image<FLOAT> > SI_infeatureMaps; 00207 typename std::vector<FLOAT> SI_tempAvg; 00208 typename std::vector<FLOAT> SI_tempStd; 00209 //! values for lower threshold values 00210 typename std::vector<FLOAT> SI_lowThresh; 00211 //! values for upper threshold values 00212 typename std::vector<FLOAT> SI_highThresh; 00213 //! list of blob properties 00214 typename std::vector<FLOAT> SI_centerX; 00215 typename std::vector<FLOAT> SI_centerY; 00216 typename std::vector<INT> SI_N; 00217 typename std::vector<INT> SI_Xsum; 00218 typename std::vector<INT> SI_Ysum; 00219 typename std::vector<INT> SI_mass; 00220 typename std::vector<INT> SI_reOrderVec; 00221 typename std::vector<INT> SI_reverseOrderVec; 00222 // list of a pixels master 00223 typename std::vector<int> SI_masterVec; 00224 std::vector<short> SI_xmin; 00225 std::vector<short> SI_xmax; 00226 std::vector<short> SI_ymin; 00227 std::vector<short> SI_ymax; 00228 std::vector<bool> SI_reset; 00229 INT SI_num; // number of blob segments 00230 INT SI_masters; // number of masters; 00231 INT SI_mastersCount; 00232 INT SI_totalBlobs; 00233 INT SI_count; 00234 INT SI_iter; 00235 INT SI_maxIDVal; 00236 int SI_doType; 00237 //! the typical kill value for removing single pixels 00238 unsigned int SI_killVal; 00239 //! frame size that will be inspected 00240 unsigned short SI_frameX1,SI_frameY1,SI_frameX2,SI_frameY2; 00241 //! bools to determine if all values have been set to run image 00242 bool SI_set1,SI_set2,SI_set3,SI_set4; 00243 //! set to false to not use band pass filter on candidates 00244 bool SI_useCandidateBandPass; 00245 //! Should singles be removed? Default: yes 00246 bool SI_removeSingles; 00247 }; 00248 00249 // ###################################################################### 00250 /* So things look consistent in everyone's emacs... */ 00251 /* Local Variables: */ 00252 /* indent-tabs-mode: nil */ 00253 /* End: */ 00254 00255 #endif