00001 #ifndef STEREO_H
00002 #define STEREO_H
00003
00004 #include <cmath>
00005 #include <float.h>
00006 #include <fstream>
00007 #include <iostream>
00008 #include "image.h"
00009 #include "image_fileoutput.h"
00010 #include "multi_array_op.h"
00011
00012 namespace mimas {
00013 template<typename T>
00014 class stereo : public image <T>
00015 {
00016
00017
00018
00019 protected:
00020 image<double> depthMap;
00021
00022 public:
00023 bool fillgaps;
00024 int xsearch, ysearch;
00025 int xwinsize, ywinsize;
00026 void stereoMap(image<T> &leftImage, image<T> &rightImage);
00027 void writeNormalisedDepthMapToFilePGM(char *fn);
00028 stereo()
00029 {
00030 xsearch=21;
00031 ysearch=5;
00032 xwinsize=5;
00033 ywinsize=2;
00034 fillgaps=false;
00035 }
00036 ~stereo()
00037 {
00038 }
00039 };
00040
00041 template<typename T>
00042 void stereo<T>::stereoMap(image<T> &leftImage, image<T> &rightImage)
00043 {
00044
00045
00046
00047
00048 int x,y,i,j;
00049 int offx, offy;
00050
00051
00052 if (!fillgaps)
00053 {
00054 depthMap.init(leftImage.getWidth(),leftImage.getHeight());
00055 }
00056
00057 for (y=ysearch+ywinsize/2; y<leftImage.getHeight()-ysearch-ywinsize/2; y++)
00058 {
00059 #ifndef NDEBUG
00060 std::cerr << "y = " << y << std::endl;
00061 #endif
00062 for (x=xsearch+xwinsize/2; x<leftImage.getWidth()-xsearch-xwinsize/2; x++)
00063 {
00064 int xpoint, ypoint;
00065 double minEnergy, energy;
00066 int energy1, energy2, energy3;
00067 double depth;
00068
00069 minEnergy=DBL_MAX;
00070
00071 for (i=x-xsearch/2; i<=x+xsearch/2; i++)
00072 for (j=y-ysearch/2; j<=y+ysearch/2; j++)
00073 {
00074
00075
00076 energy1=0;
00077 energy2=0;
00078 energy3=0;
00079 for (offx=-xwinsize/2; offx<=xwinsize/2; offx++)
00080 for (offy=-ywinsize/2; offy<=ywinsize/2; offy++)
00081 {
00082
00083
00084
00085 energy1+=( (leftImage.pixel(x+offx,y+offy)-rightImage.pixel(i+offx,j+offy)) *
00086 (leftImage.pixel(x+offx,y+offy)-rightImage.pixel(i+offx,j+offy)) );
00087 energy2+=leftImage.pixel(x+offx,y+offy)*leftImage.pixel(x+offx,y+offy);
00088 energy3+=rightImage.pixel(i+offx,j+offy)*rightImage.pixel(i+offx,j+offy);
00089
00090
00091 }
00092
00093 energy=(double)energy1/sqrt((double)energy2*(double)energy3);
00094
00095 if (energy<minEnergy)
00096 {
00097 minEnergy=energy;
00098 xpoint=i;
00099 ypoint=j;
00100 }
00101
00102 }
00103
00104 depth=(double)( ((x-xpoint)*(x-xpoint)) + ( (y-ypoint)*(y-ypoint) ));
00105 depth=sqrt(depth);
00106
00107 if (minEnergy<1e-16) depth=0.0;
00108
00109
00110
00111 if (fillgaps)
00112 {
00113 if (depthMap.pixel(x,y)<1e-1)
00114 depthMap.pixel(x,y) = (double)depth;
00115 }
00116 else
00117 depthMap.pixel(x,y) = (double)depth;
00118
00119
00120
00121
00122 }
00123 }
00124 }
00125
00126
00127 template<typename T>
00128 void stereo<T>::writeNormalisedDepthMapToFilePGM(char *fn)
00129 {
00130 int i,j;
00131 double maxIntensity;
00132
00133 maxIntensity=DBL_MIN;
00134 for (i=0; i<depthMap.getWidth(); i++)
00135 for (j=0; j<depthMap.getHeight(); j++)
00136 if (maxIntensity<depthMap.pixel(i,j)) maxIntensity=depthMap.pixel(i,j);
00137
00138 #ifndef NDEBUG
00139 std::cerr << "maxIntensity = " << maxIntensity << endl;
00140 #endif
00141
00142 image< double > tempImage;
00143 tempImage.init( depthMap.getWidth(), depthMap.getHeight() );
00144 tempImage.rawData() = depthMap.rawData() * 255.0 / maxIntensity;
00145
00146 std::ofstream outFile( fn, std::ios::binary );
00147 outFile << tempImage;
00148 }
00149 }
00150
00151 #endif