egami
C++ Image Processing program
/homes/esi30/DCS339/coursework/src/Processes/convolution.hpp
Go to the documentation of this file.
00001 #ifndef PROCESSES_CONVOLUTION_HPP_INCLUDED
00002 #define PROCESSES_CONVOLUTION_HPP_INCLUDED
00003 
00004 #include <cmath>
00005 #include <array>
00006 
00007 #include "../progress.hpp"
00008 #include "../display_unit.hpp"
00009 
00010 template<int N>
00011 class Advancement{
00012     public:
00013         Advancement(){}
00014         void advance(double d){ p.advance(d); }
00015     private:
00016         Progress p;
00017 };
00018 
00019 template<>
00020 class Advancement<1>{
00021     public:
00022         void advance(double){}
00023 };
00024 
00025 template<int N>
00026 Image_unit* apply(const Image_unit *in, const std::array<std::array<double, 2*N+1>, 2*N+1> &kernel, double divisor){
00027     Advancement<N> adv;
00028     Image_unit *out=new Image_unit(*in);
00029 
00030     for(unsigned y=0; y<out->height(); ++y){
00031         adv.advance(static_cast<double>(y)/out->height());
00032         for(unsigned x=0; x<out->width(); ++x){
00033             double vr=0, vg=0, vb=0;
00034             for(int dy=-N; dy<=N; ++dy)
00035                 for(int dx=-N; dx<=N; ++dx){
00036                     // @todo error if the kernel is bigger than the image
00037                     vr+=in->m_red(y+dy, x+dx)*kernel[dy+N][dx+N];
00038                     vg+=in->m_green(y+dy, x+dx)*kernel[dy+N][dx+N];
00039                     vb+=in->m_blue(y+dy, x+dx)*kernel[dy+N][dx+N];
00040                 }
00041             vr/=divisor;
00042             vg/=divisor;
00043             vb/=divisor;
00044             vr=vr<0?0:vr>255?255:vr;
00045             vg=vg<0?0:vg>255?255:vg;
00046             vb=vb<0?0:vb>255?255:vb;
00047             out->red(y, x, vr);
00048             out->green(y, x, vg);
00049             out->blue(y, x, vb);
00050         }
00051     }
00052     return out;
00053 }
00054 
00055     /* Iterator version :
00056 
00057     for(Image::const_iterator it=in->begin(); it!=in->end(); ++it){
00058         double vr=0, vg=0, vb=0;
00059         for(int dy=-N; dy<=N; ++dy)
00060             for(int dx=-N; dx<=N; ++dx){
00061                 Image::const_iterator ti(it+dy*in->width()+dx);
00062                 if(ti.valid()){
00063                     vr+=ti->r*kernel[dy+N][dx+N];
00064                     vg+=ti->g*kernel[dy+N][dx+N];;
00065                     vb+=ti->b*kernel[dy+N][dx+N];;
00066                 }
00067             }
00068         
00069         Image::iterator to=(out->begin()+(it-in->begin()));
00070         to->r=static_cast<unsigned char>(std::abs(vr/divisor));
00071         to->g=static_cast<unsigned char>(std::abs(vg/divisor));
00072         to->b=static_cast<unsigned char>(std::abs(vb/divisor));
00073     }
00074     */
00075 
00076 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends