|
degate 0.1.1
|
00001 /* -*-c++-*- 00002 00003 This file is part of the IC reverse engineering tool degate. 00004 00005 Copyright 2008, 2009, 2010 by Martin Schobert 00006 00007 Degate is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation, either version 3 of the License, or 00010 any later version. 00011 00012 Degate is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with degate. If not, see <http://www.gnu.org/licenses/>. 00019 00020 */ 00021 00022 #ifndef __BACKGROUNDCLASSIFIER_H__ 00023 #define __BACKGROUNDCLASSIFIER_H__ 00024 00025 #include <Image.h> 00026 #include <degate_exceptions.h> 00027 #include <TypeConstraints.h> 00028 #include <ImageManipulation.h> 00029 #include <ImageHistogram.h> 00030 00031 #include <fstream> 00032 #include <iostream> 00033 #include <boost/format.hpp> 00034 00035 #include <list> 00036 #include <vector> 00037 #include <adaboost.hpp> 00038 00039 namespace degate { 00040 00041 typedef std::pair<unsigned int, unsigned int> coord_type; 00042 typedef std::list<coord_type> coord_list; 00043 00044 00045 class BackgroundClassifierBase : public Classifier<coord_type> { 00046 public: 00047 virtual ~BackgroundClassifierBase() {} 00048 virtual void add_background_areas(std::list<BoundingBox> const& bg_areas) = 0; 00049 virtual void add_foreground_areas(std::list<BoundingBox> const& fg_areas) = 0; 00050 virtual int recognize(coord_type & v) = 0; 00051 }; 00052 00053 00054 typedef std::vector<Classifier<coord_type> *> classifier_list_type; 00055 00056 00057 00058 template<class ImageType, typename HistogramType> 00059 class BackgroundClassifier : public BackgroundClassifierBase { 00060 00061 private: 00062 00063 const std::tr1::shared_ptr<ImageType> img; 00064 HistogramType hist_bg, hist_fg; 00065 const unsigned int width; 00066 const unsigned int threshold; 00067 const std::string cl_name; 00068 00069 public: 00070 00071 00072 BackgroundClassifier(std::tr1::shared_ptr<ImageType> _img, 00073 unsigned int _width, 00074 unsigned int _threshold, 00075 std::string const& _name) : 00076 img(_img), 00077 width(_width), 00078 threshold(_threshold), 00079 cl_name(_name) { 00080 } 00081 00082 00083 std::string get_name() const { 00084 return cl_name; 00085 } 00086 00087 00088 void add_background_areas(std::list<BoundingBox> const& bg_areas) { 00089 00090 for(std::list<BoundingBox>::const_iterator iter = bg_areas.begin(); 00091 iter != bg_areas.end(); ++iter) { 00092 hist_bg.add_area(img, *iter); 00093 } 00094 } 00095 00096 00097 void add_foreground_areas(std::list<BoundingBox> const& fg_areas) { 00098 00099 00100 for(std::list<BoundingBox>::const_iterator iter = fg_areas.begin(); 00101 iter != fg_areas.end(); ++iter) { 00102 hist_fg.add_area(img, *iter); 00103 } 00104 } 00105 00106 00107 /** 00108 * @todo Cache data 00109 */ 00110 int recognize(coord_type & v) { 00111 unsigned int sum = 0; 00112 00113 int radius = width >> 1; 00114 int x = v.first, y = v.second; 00115 00116 if((x > radius && x < (int)img->get_width() - radius) && 00117 (y > radius && y < (int)img->get_height() - radius)) { 00118 00119 for(int _y = -radius; _y < radius; _y++) 00120 for(int _x = -radius; _x < radius; _x++) { 00121 rgba_pixel_t p = img->get_pixel(x + _x, y + _y); 00122 if(hist_fg.get_for_rgb(p) > hist_bg.get_for_rgb(p)) sum++; 00123 } 00124 } 00125 00126 00127 if(sum >= threshold) return 1; 00128 else return -1; 00129 } 00130 }; 00131 00132 00133 /* 00134 template<class ImageType> 00135 class GradientClassifier : public Classifier<coord_type> { 00136 00137 private: 00138 const std::tr1::shared_ptr<ImageType> img; 00139 const unsigned int width; 00140 public: 00141 00142 BackgroundClassifier(std::tr1::shared_ptr<ImageType> _img, 00143 unsigned int _width) {} 00144 00145 std::string get_name() const { 00146 return "gradient"; 00147 } 00148 int recognize(coord_type & v) { 00149 unsigned int sum = 0; 00150 00151 int radius = width >> 1; 00152 int x = v.first, y = v.second; 00153 00154 if((x > radius && x < (int)img->get_width() - radius) && 00155 (y > radius && y < (int)img->get_height() - radius)) { 00156 00157 std::vector<double> col_sum(width), row_sum(width); 00158 00159 00160 for(int _y = -radius; _y < radius; _y++) 00161 for(int _x = -radius; _x < radius; _x++) { 00162 00163 00164 rgba_pixel_t p = img->get_pixel(x + _x, y + _y); 00165 double gs = RGBA_TO_GS_BY_VAL(p); 00166 00167 col_sum[_x + radius] = gs; 00168 row_sum[_y + radius] = gs; 00169 } 00170 } 00171 00172 bool col_iter_ok = true; 00173 for(unsigned int i = 0; i < col_sum.size() - 1; i++) { 00174 if(col_sum[i] > 00175 } 00176 00177 } 00178 00179 }; 00180 00181 00182 */ 00183 00184 00185 00186 00187 /* 00188 class BackgroundClassifier { 00189 private: 00190 00191 unsigned int wire_diameter; 00192 00193 HueImageHistogram bg_hue, fg_hue; 00194 SaturationImageHistogram bg_sat, fg_sat; 00195 LightnessImageHistogram bg_l, fg_l; 00196 RedChannelImageHistogram bg_r, fg_r; 00197 GreenChannelImageHistogram bg_g, fg_g; 00198 BlueChannelImageHistogram bg_b, fg_b; 00199 HueStdDevImageHistogram bg_stdev_hue, fg_stdev_hue; 00200 SaturationStdDevImageHistogram bg_stdev_sat, fg_stdev_sat; 00201 LightnessStdDevImageHistogram bg_stdev_l, fg_stdev_l; 00202 00203 00204 public: 00205 00206 BackgroundClassifier(unsigned int _wire_diameter) : 00207 wire_diameter(_wire_diameter), 00208 bg_stdev_hue(wire_diameter), 00209 fg_stdev_hue(wire_diameter), 00210 bg_stdev_sat(wire_diameter), 00211 fg_stdev_sat(wire_diameter), 00212 bg_stdev_l(wire_diameter), 00213 fg_stdev_l(wire_diameter) { 00214 } 00215 00216 virtual ~BackgroundClassifier() {} 00217 00218 template<class ImageType> 00219 void add_background_areas(std::tr1::shared_ptr<ImageType> img, 00220 std::list<BoundingBox> const& bg_areas) { 00221 00222 for(std::list<BoundingBox>::const_iterator iter = bg_areas.begin(); iter != bg_areas.end(); ++iter) { 00223 bg_hue.add_area<ImageType>(img, *iter); 00224 bg_sat.add_area<ImageType>(img, *iter); 00225 bg_l.add_area<ImageType>(img, *iter); 00226 bg_r.add_area<ImageType>(img, *iter); 00227 bg_g.add_area<ImageType>(img, *iter); 00228 bg_b.add_area<ImageType>(img, *iter); 00229 //bg_stdev_hue.add_area<ImageType>(img, *iter); 00230 //bg_stdev_sat.add_area<ImageType>(img, *iter); 00231 //bg_stdev_l.add_area<ImageType>(img, *iter); 00232 } 00233 } 00234 00235 template<class ImageType> 00236 void add_foreground_areas(std::tr1::shared_ptr<ImageType> img, 00237 std::list<BoundingBox> const& fg_areas) { 00238 00239 00240 for(std::list<BoundingBox>::const_iterator iter = fg_areas.begin(); iter != fg_areas.end(); ++iter) { 00241 fg_hue.add_area<ImageType>(img, *iter); 00242 fg_sat.add_area<ImageType>(img, *iter); 00243 fg_l.add_area<ImageType>(img, *iter); 00244 fg_r.add_area<ImageType>(img, *iter); 00245 fg_g.add_area<ImageType>(img, *iter); 00246 fg_b.add_area<ImageType>(img, *iter); 00247 //fg_stdev_hue.add_area<ImageType>(img, *iter); 00248 //fg_stdev_sat.add_area<ImageType>(img, *iter); 00249 //fg_stdev_l.add_area<ImageType>(img, *iter); 00250 } 00251 } 00252 00253 00254 double get_probability(rgba_pixel_t pix) { 00255 00256 double p_fg = fg_hue.get(rgba_to_hue(pix)) * 00257 fg_sat.get(rgba_to_saturation(pix)) * 00258 fg_l.get(rgba_to_lightness(pix)) * 00259 00260 fg_r.get(MASK_R(pix)) * 00261 fg_g.get(MASK_G(pix)) * 00262 fg_b.get(MASK_B(pix)) 00263 00264 ; 00265 00266 double p_bg = bg_hue.get(rgba_to_hue(pix)) * 00267 bg_sat.get(rgba_to_saturation(pix)) * 00268 bg_l.get(rgba_to_lightness(pix)) * 00269 bg_r.get(MASK_R(pix)) * 00270 bg_g.get(MASK_G(pix)) * 00271 bg_b.get(MASK_B(pix)) 00272 ; 00273 00274 return p_fg - p_bg; 00275 } 00276 00277 void save_histograms(std::string const& directory) { 00278 00279 bg_hue.save_histogram(join_pathes(directory, "histogram_bg_hue.dat")); 00280 bg_sat.save_histogram(join_pathes(directory, "histogram_bg_sat.dat")); 00281 bg_l.save_histogram(join_pathes(directory, "histogram_bg_l.dat")); 00282 bg_r.save_histogram(join_pathes(directory, "histogram_bg_r.dat")); 00283 bg_g.save_histogram(join_pathes(directory, "histogram_bg_g.dat")); 00284 bg_b.save_histogram(join_pathes(directory, "histogram_bg_b.dat")); 00285 //bg_stdev_hue.save_histogram(join_pathes(directory, "histogram_bg_stddev_hue.dat")); 00286 //bg_stdev_sat.save_histogram(join_pathes(directory, "histogram_bg_stddev_sat.dat")); 00287 //bg_stdev_l.save_histogram(join_pathes(directory, "histogram_bg_stddev_l.dat")); 00288 00289 fg_hue.save_histogram(join_pathes(directory, "histogram_fg_hue.dat")); 00290 fg_sat.save_histogram(join_pathes(directory, "histogram_fg_sat.dat")); 00291 fg_l.save_histogram(join_pathes(directory, "histogram_fg_l.dat")); 00292 fg_r.save_histogram(join_pathes(directory, "histogram_fg_r.dat")); 00293 fg_g.save_histogram(join_pathes(directory, "histogram_fg_g.dat")); 00294 fg_b.save_histogram(join_pathes(directory, "histogram_fg_b.dat")); 00295 //fg_stdev_hue.save_histogram(join_pathes(directory, "histogram_fg_stddev_hue.dat")); 00296 //fg_stdev_sat.save_histogram(join_pathes(directory, "histogram_fg_stddev_sat.dat")); 00297 //fg_stdev_l.save_histogram(join_pathes(directory, "histogram_fg_stddev_l.dat")); 00298 00299 } 00300 00301 }; 00302 */ 00303 } 00304 00305 #endif
1.7.4