degate  0.1.2
MedianFilter.h
Go to the documentation of this file.
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 __MEDIANFILTER_H__
00023 #define __MEDIANFILTER_H__
00024 
00025 namespace degate {
00026 
00027   /**
00028    * Policy class for image region median calculation.
00029    */
00030   template<typename ImageType, typename PixelType>
00031   struct CalculateImageMedianPolicy {
00032 
00033     /**
00034      * Calculate the median for an image region.
00035      */
00036     static inline PixelType calculate(std::shared_ptr<ImageType> src,
00037                                       unsigned int x, unsigned int y,
00038                                       unsigned int min_x,
00039                                       unsigned int max_x,
00040                                       unsigned int min_y,
00041                                       unsigned int max_y,
00042                                       unsigned int threshold) {
00043 
00044       assert(min_x < max_x && min_y < max_y);
00045       assert(min_x < src->get_width());
00046       assert(max_x < src->get_width());
00047       assert(min_y < src->get_height());
00048       assert(max_y < src->get_height());
00049 
00050       unsigned int kernel_size = (max_x - min_x) * (max_y - min_y);
00051       std::vector<PixelType> v(kernel_size);
00052 
00053       unsigned int i = 0;
00054       for(unsigned int _y = min_y; _y < max_y; _y++)
00055         for(unsigned int _x = min_x; _x < max_x; _x++, i++)
00056           v[i] = src->get_pixel(_x, _y);
00057 
00058       return median<PixelType>(v);
00059     }
00060   };
00061 
00062 
00063 
00064   /**
00065    * Policy class for image region median calculation for RGB(A) images.
00066    */
00067   template<typename ImageType>
00068   struct CalculateImageMedianPolicy<ImageType, rgba_pixel_t> {
00069 
00070     /**
00071      * Calculate the median for an RGBA image region.
00072      */
00073 
00074     static inline rgba_pixel_t calculate(std::shared_ptr<ImageType> src,
00075                                          unsigned int x, unsigned int y,
00076                                          unsigned int min_x,
00077                                          unsigned int max_x,
00078                                          unsigned int min_y,
00079                                          unsigned int max_y,
00080                                          unsigned int threshold) {
00081 
00082       assert(min_x < max_x && min_y < max_y);
00083       assert(min_x < src->get_width());
00084       assert(max_x < src->get_width());
00085       assert(min_y < src->get_height());
00086       assert(max_y < src->get_height());
00087 
00088       unsigned int kernel_size = (max_x - min_x) * (max_y - min_y);
00089       std::vector<unsigned int>
00090         v_r(kernel_size),
00091         v_g(kernel_size),
00092         v_b(kernel_size);
00093 
00094       unsigned int i = 0;
00095       for(unsigned int _y = min_y; _y < max_y; _y++) {
00096         for(unsigned int _x = min_x; _x < max_x; _x++, i++) {
00097 
00098           rgba_pixel_t p = src->get_pixel(_x, _y);
00099           v_r[i] = MASK_R(p);
00100           v_g[i] = MASK_G(p);
00101           v_b[i] = MASK_B(p);
00102         }
00103       }
00104       return MERGE_CHANNELS(median<unsigned int>(v_r),
00105                             median<unsigned int>(v_g),
00106                             median<unsigned int>(v_b), 255);
00107     }
00108   };
00109 
00110   /**
00111    * Filter an image with a median filter.
00112    */
00113 
00114   template<typename ImageTypeDst, typename ImageTypeSrc>
00115   void median_filter(std::shared_ptr<ImageTypeDst> dst,
00116                      std::shared_ptr<ImageTypeSrc> src,
00117                      unsigned int kernel_width = 3) {
00118 
00119     filter_image<ImageTypeDst, ImageTypeSrc,
00120       CalculateImageMedianPolicy<ImageTypeSrc, typename ImageTypeSrc::pixel_type> >(dst, src, kernel_width);
00121   }
00122 
00123 }
00124 #endif