00001 #ifndef PYRAMID_TOOL_H
00002 #define PYRAMID_TOOL_H
00003
00004 #include <iostream>
00005 #include <vector>
00006 #include <cmath>
00007 #include <values.h>
00008 #include "image.h"
00009 #include "image_funcs.h"
00010
00011 namespace mimas {
00018 class pyramid_tool
00019 {
00020 private:
00021 double a,b,c;
00022
00023 public:
00024 pyramid_tool(void);
00025 ~pyramid_tool(void);
00026 void reduceGaussian(image<double> &imagein, image<double> &imageout);
00027 void reduceGaussian(image<double> &imagein, vector < image<double> > &vectimageout, int numlevels);
00028 void expandGaussian(image<double> &imagein, image<double> &imageout);
00029 void expandGaussian(image<double> &imagein, vector < image<double> > &vectimageout, int numlevels);
00030 void buildLaplacian(image<double> &imagein, vector < image<double> > &vectimageout, int numlevels);
00031 void reconstructLaplacian(vector < image<double> > &vectimagein, image<double> &imageout);
00032
00033
00034 };
00035
00036 pyramid_tool::pyramid_tool()
00037 {
00038 a=0.4;
00039 b=0.25;
00040 c=b-a/2;
00041 }
00042
00043 pyramid_tool::~pyramid_tool()
00044 {
00045 }
00046
00047
00048 void pyramid_tool::buildLaplacian(image<double> &imagein, vector < image<double> > &vectimageout, int numlevels)
00049 {
00050 image<double> image;
00051 image<double> rimage, eimage;
00052
00053 vectimageout.clear();
00054 for (int r=0; r<numlevels; r++)
00055 vectimageout.insert(vectimageout.begin(),image);
00056
00057 image=imagein;
00058
00059 for (int r=0; r<numlevels-1; r++)
00060 {
00061 reduceGaussian(image, rimage);
00062 expandGaussian(rimage,eimage);
00063
00064 vectimageout[r].init(image.getWidth(),image.getHeight());
00065
00066 for (int j=0; j<image.getHeight(); j++)
00067 for (int i=0; i<image.getWidth(); i++)
00068 vectimageout[r].pixel(i,j)=image.pixel(i,j)-eimage.pixel(i,j);
00069
00070 image.clear();
00071 image=rimage;
00072 }
00073 vectimageout[numlevels-1]=image;
00074
00075 }
00076
00077 void pyramid_tool::reconstructLaplacian(vector < image<double> > &vectimagein, image<double> &imageout)
00078 {
00079 int numlevels=vectimagein.size();
00080
00081 if (numlevels<=0) return;
00082
00083 imageout=vectimagein[numlevels-1];
00084
00085 for (int r=numlevels-2; r>=0; r--)
00086 {
00087 image<double> eimage;
00088
00089 expandGaussian(imageout,eimage);
00090
00091 imageout.init(eimage.getWidth(),eimage.getHeight());
00092
00093 for (int j=0; j<imageout.getHeight(); j++)
00094 for (int i=0; i<imageout.getWidth(); i++)
00095 imageout.pixel(i,j) = eimage.pixel(i,j)+vectimagein[r].pixel(i,j);
00096
00097 }
00098 }
00099
00100
00101 void pyramid_tool::reduceGaussian(image<double> &imagein, vector < image<double> > &vectimageout, int numlevels)
00102 {
00103 image<double> image;
00104
00105 vectimageout.clear();
00106 for (int r=0; r<numlevels; r++)
00107 vectimageout.insert(vectimageout.begin(),image);
00108
00109 image=imagein;
00110
00111 if (numlevels>=1)
00112 vectimageout[0]=imagein;
00113
00114 for (int r=1; r<numlevels; r++)
00115 {
00116 image<double> tmpimage;
00117
00118
00119 reduceGaussian(image,vectimageout[r]);
00120
00121 image.clear();
00122 image=vectimageout[r];
00123 }
00124
00125 }
00126
00127 void pyramid_tool::expandGaussian(image<double> &imagein, vector < image<double> > &vectimageout, int numlevels)
00128 {
00129 image<double> image;
00130
00131 vectimageout.clear();
00132 for (int r=0; r<numlevels; r++)
00133 vectimageout.insert(vectimageout.begin(),image);
00134
00135 image=imagein;
00136
00137 if (numlevels>=1)
00138 vectimageout[0]=imagein;
00139
00140 for (int r=1; r<numlevels; r++)
00141 {
00142 image<double> tmpimage;
00143
00144
00145 expandGaussian(image,vectimageout[r]);
00146
00147 image.clear();
00148 image=vectimageout[r];
00149 }
00150
00151 }
00152
00153 void pyramid_tool::reduceGaussian(image<double> &imagein, image<double> &imageout)
00154 {
00155 imageout.init(imagein.getWidth()/2, imagein.getHeight()/2);
00156
00157 double gkernel[5][5]={ {c*c, b*c, a*c, b*c, c*c},
00158 {c*b, b*b, a*b, b*b, c*b},
00159 {c*a, b*a, a*a, b*a, c*a},
00160 {c*b, b*b, a*b, b*b, c*b},
00161 {c*c, b*c, a*c, b*c, c*c} };
00162
00163
00164
00165 double sumgkernel=0.0;
00166 for (int i=0; i<5; i++)
00167 for (int j=0; j<5; j++)
00168 sumgkernel+=gkernel[i][j];
00169
00170 cerr << "sumgkernel = " << sumgkernel << std::endl;
00171
00172 for (int j=0; j<imageout.getHeight(); j++)
00173 for (int i=0; i<imageout.getWidth(); i++)
00174 {
00175 double intensity=0.0;
00176 for (int y=-2; y<=2; y++)
00177 for (int x=-2; x<=2; x++)
00178 intensity+=gkernel[x+2][y+2]*imagein.getPixel(2*i+x,2*j+y);
00179
00180 imageout.pixel(i,j) = intensity / sumgkernel;
00181 }
00182 }
00183
00184 void pyramid_tool::expandGaussian(image<double> &imagein, image<double> &imageout)
00185 {
00186 imageout.init(imagein.getWidth()*2, imagein.getHeight()*2);
00187
00188 double gkernel[5][5]={ {c*c, b*c, a*c, b*c, c*c},
00189 {c*b, b*b, a*b, b*b, c*b},
00190 {c*a, b*a, a*a, b*a, c*a},
00191 {c*b, b*b, a*b, b*b, c*b},
00192 {c*c, b*c, a*c, b*c, c*c} };
00193
00194
00195
00196 double sumgkernel=0.0;
00197 for (int i=0; i<5; i++)
00198 for (int j=0; j<5; j++)
00199 sumgkernel+=gkernel[i][j];
00200
00201 cerr << "sumgkernel = " << sumgkernel << std::endl;
00202
00203 for (int j=0; j<imageout.getHeight(); j++)
00204 for (int i=0; i<imageout.getWidth(); i++)
00205 {
00206 double intensity=0.0;
00207 for (int y=-2; y<=2; y++)
00208 for (int x=-2; x<=2; x++)
00209 intensity+=gkernel[x+2][y+2]*imagein.getPixel((i-x)/2,(j-y)/2);
00210
00211 imageout.pixel(i,j) = intensity / sumgkernel;
00212 }
00213 }
00214 }
00215 #endif