00001 /*!@file Gist/*/ 00002 // //////////////////////////////////////////////////////////////////// // 00003 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00004 // University of Southern California (USC) and the iLab at USC. // 00005 // See http://iLab.usc.edu for information about this project. // 00006 // //////////////////////////////////////////////////////////////////// // 00007 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00008 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00009 // in Visual Environments, and Applications'' by Christof Koch and // 00010 // Laurent Itti, California Institute of Technology, 2001 (patent // 00011 // pending; application number 09/912,225 filed July 23, 2001; see // 00012 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00013 // //////////////////////////////////////////////////////////////////// // 00014 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00015 // // 00016 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00017 // redistribute it and/or modify it under the terms of the GNU General // 00018 // Public License as published by the Free Software Foundation; either // 00019 // version 2 of the License, or (at your option) any later version. // 00020 // // 00021 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00022 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00023 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00024 // PURPOSE. See the GNU General Public License for more details. // 00025 // // 00026 // You should have received a copy of the GNU General Public License // 00027 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00028 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00029 // Boston, MA 02111-1307 USA. // 00030 // //////////////////////////////////////////////////////////////////// // 00031 // 00032 // Primary maintainer for this file: Christian Siagian <siagian@usc.edu> 00033 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Gist/SuperPixel_filter.H $ 00034 // $Id: SuperPixel_filter.H 12962 2010-03-06 02:13:53Z irock $ 00035 // 00036 ////////////////////////////////////////////////////////////////////////// 00037 // 00038 // Implementation of the segmentation algorithm described in: 00039 // 00040 // Efficient Graph-Based Image Segmentation 00041 // Pedro F. Felzenszwalb and Daniel P. Huttenlocher 00042 // International Journal of Computer Vision, 59(2) September 2004. 00043 // Copyright (C) 2006 Pedro Felzenszwalb 00044 00045 /* simple filters */ 00046 00047 #ifndef SUPERPIXEL_FILTER_H 00048 #define SUPERPIXEL_FILTER_H 00049 00050 #include <vector> 00051 #include <cmath> 00052 00053 00054 00055 #define WIDTH 4.0 00056 00057 /* convolve src with mask. dst is flipped! */ 00058 void convolve_even(Image<float> src, Image<float> &dst, 00059 std::vector<float> &mask) 00060 { 00061 int width = src.getWidth(); 00062 int height = src.getHeight(); 00063 int len = mask.size(); 00064 00065 for (int y = 0; y < height; y++) { 00066 for (int x = 0; x < width; x++) { 00067 float sum = mask[0] * src.getVal(x, y); 00068 for (int i = 1; i < len; i++) { 00069 sum += mask[i] * 00070 (src.getVal(std::max(x-i,0), y) + 00071 src.getVal(std::min(x+i, width-1), y)); 00072 } 00073 dst.setVal(y, x, sum); 00074 } 00075 } 00076 } 00077 00078 // /* convolve src with mask. dst is flipped! */ 00079 // static void convolve_odd(image<float> *src, image<float> *dst, 00080 // std::vector<float> &mask) { 00081 // int width = src->width(); 00082 // int height = src->height(); 00083 // int len = mask.size(); 00084 00085 // for (int y = 0; y < height; y++) { 00086 // for (int x = 0; x < width; x++) { 00087 // float sum = mask[0] * imRef(src, x, y); 00088 // for (int i = 1; i < len; i++) { 00089 // sum += mask[i] * 00090 // (imRef(src, std::max(x-i,0), y) - 00091 // imRef(src, std::min(x+i, width-1), y)); 00092 // } 00093 // imRef(dst, y, x) = sum; 00094 // } 00095 // } 00096 // } 00097 00098 00099 00100 /* normalize mask so it integrates to one */ 00101 static void normalize(std::vector<float> &mask) { 00102 int len = mask.size(); 00103 float sum = 0; 00104 for (int i = 1; i < len; i++) { 00105 sum += fabs(mask[i]); 00106 } 00107 sum = 2*sum + fabs(mask[0]); 00108 for (int i = 0; i < len; i++) { 00109 mask[i] /= sum; 00110 } 00111 } 00112 00113 /* make filters */ 00114 #define MAKE_FILTER(name, fun) \ 00115 static std::vector<float> make_ ## name (float sigma) { \ 00116 sigma = std::max(sigma, 0.01F); \ 00117 int len = (int)ceil(sigma * WIDTH) + 1; \ 00118 std::vector<float> mask(len); \ 00119 for (int i = 0; i < len; i++) { \ 00120 mask[i] = fun; \ 00121 } \ 00122 return mask; \ 00123 } 00124 00125 MAKE_FILTER(fgauss, exp(-0.5* pow(i/sigma, 2.0))); 00126 00127 /* convolve image with gaussian filter */ 00128 Image<float> smooth(Image<float> src, float sigma) 00129 { 00130 std::vector<float> mask = make_fgauss(sigma); 00131 normalize(mask); 00132 00133 Image<float> tmp(src.getHeight(), src.getWidth(), NO_INIT); 00134 Image<float> dst(src.getWidth(), src.getHeight(), NO_INIT); 00135 convolve_even(src, tmp, mask); 00136 convolve_even(tmp, dst, mask); 00137 00138 return dst; 00139 } 00140 00141 // /* convolve image with gaussian filter */ 00142 // Image<float> smooth(Image<byte> src, float sigma) 00143 // { 00144 // Image<float> tmp = imageUCHARtoFLOAT(src); 00145 // Image<float> dst = smooth(tmp, sigma); 00146 // delete tmp; 00147 // return dst; 00148 // } 00149 00150 // /* compute laplacian */ 00151 // static image<float> *laplacian(image<float> *src) { 00152 // int width = src->width(); 00153 // int height = src->height(); 00154 // image<float> *dst = new image<float>(width, height); 00155 00156 // for (int y = 1; y < height-1; y++) { 00157 // for (int x = 1; x < width-1; x++) { 00158 // float d2x = imRef(src, x-1, y) + imRef(src, x+1, y) - 00159 // 2*imRef(src, x, y); 00160 // float d2y = imRef(src, x, y-1) + imRef(src, x, y+1) - 00161 // 2*imRef(src, x, y); 00162 // imRef(dst, x, y) = d2x + d2y; 00163 // } 00164 // } 00165 // return dst; 00166 // } 00167 00168 #endif