Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

FourierSlicer.cpp

Go to the documentation of this file.
00001 #include "FourierSlicer.h"
00002 #include "General/vuLinAlg/vuVector.h"
00003 #include "vuLightfield/Converter/vuSphericLightfieldFile.h"
00004 #include "General/vuFourier/vuFourierFilter/vuTorstensFourierFilter.h"
00005 #include "General/vuMisc/vuTimer.h"
00006 #include <GL/gl.h>
00007 #include <GL/glut.h>
00008 #include <iostream>
00009 #include <stdio.h>
00010 #include <math.h>
00011 
00012 //***********************************************************************
00013 //***                     PUBLIC methods                              ***
00014 //***********************************************************************
00015 
00016 template <int S>
00017 FourierSlicer<S>::FourierSlicer(vuString fileName, dword views,
00018                                 float scale, float bias,
00019                                 vuString filterName,
00020                                 vuString timingFileName)
00021 {
00022   m_NumOfViews   = views;
00023   m_TimingStream = NULL;
00024   
00025   if (!timingFileName.isEmpty())
00026     m_TimingStream = new ofstream(timingFileName, ios::out);
00027   
00028   cerr << "calculate view directions..." << endl;
00029   // initialize sphere
00030   m_Sphere  = new vuUDSphere(views);
00031   m_Sphere->lazyCalculate();
00032 
00033   cerr << "initialize fourier volume..." << endl;
00034   // initialize raycaster
00035   m_Fourier = new vu1712_1<S>;
00036   m_Fourier->setScale(scale);
00037   m_Fourier->setBias(bias);
00038   vuFourierFilter *filter = vuTorstensFourierFilter::getFilter(filterName);
00039   if (filter == NULL) {
00040     cerr << "WARNING: Could not load filter with name: '";
00041     cerr << filterName << "' use 'd0_c3_2ef' instead." << endl;
00042     filter = vuTorstensFourierFilter::getFilter("d0_c3_2ef");
00043     filterName = "d0_c3_2ef";
00044   }
00045   m_Fourier->setFilter(filter);
00046 
00047   m_Fourier->setFileName(fileName);
00048   if (m_Fourier->read()) {
00049     m_Width  = m_Fourier->getImageWidth();
00050     m_Height = m_Fourier->getImageHeight();
00051 
00052     m_ExternalWidth  = (dword)((float)m_Width  / M_SQRT2);
00053     m_ExternalHeight = (dword)((float)m_Height / M_SQRT2);
00054 
00055     if (((m_Width  - m_ExternalWidth)  % 2) == 1) m_ExternalWidth  -= 1;
00056     if (((m_Height - m_ExternalHeight) % 2) == 1) m_ExternalHeight -= 1;
00057 
00058     cerr << endl;
00059     cerr << "********************************************************" << endl;
00060     cerr << "views     = " << views << endl;
00061     cerr << "scale     = " << scale << endl;
00062     cerr << "bias      = " << bias  << endl;
00063     cerr << "dimension = " << m_ExternalWidth << "x" << m_ExternalHeight<<endl;
00064     cerr << "channels  = " << S << endl;
00065     cerr << "filter    = " << filterName << endl;
00066     cerr << "********************************************************" << endl;
00067     cerr << endl;
00068 
00069     m_isComputed = false;
00070   }
00071   else {
00072     m_isComputed = true;
00073     cerr << "ERROR: could not load '" << fileName << "'" << endl;
00074   }
00075 
00076   if (m_TimingStream != NULL) {
00077     *m_TimingStream<<"          file: "<<fileName.getLastPathComponent()<<endl;
00078     *m_TimingStream<< "        filter: " << filterName << endl;
00079     *m_TimingStream<< "         views: " << views      << endl;
00080     *m_TimingStream<< "    dimensions: "<<m_Fourier->getXSize()<<"^3"<< endl;
00081     *m_TimingStream<< "      channels: " << S << endl;
00082     *m_TimingStream<< "implementation: template interleaved" << endl;
00083     *m_TimingStream<< endl;
00084 
00085     *m_TimingStream << "                  lookAt                      ";
00086     *m_TimingStream << "timing in ms" << endl;
00087 
00088     *m_TimingStream << "        x           y           z        ";
00089     *m_TimingStream << "slicing          fft" << endl;
00090   }
00091 }
00092 
00093 template <int S>
00094 FourierSlicer<S>::~FourierSlicer()
00095 {
00096   CHECKNDELETE(m_Fourier);
00097   CHECKNDELETE(m_Sphere);
00098   CHECKNDELETE(m_TimingStream);
00099 }
00100 
00101 template <int S>
00102 void FourierSlicer<S>::lazyCalculateAndDisplay(const char *fileName)
00103 {
00104   _lazyCalculate(fileName, true);
00105 }
00106 
00107 template <int S>
00108 void FourierSlicer<S>::lazyCalculateAndLog(const char *fileName)
00109 {
00110   _lazyCalculate(fileName, false);
00111 }
00112 
00113 template <int S>
00114 dword FourierSlicer<S>::getImageWidth()
00115 {
00116   return m_ExternalWidth;
00117 }
00118 
00119 template <int S>
00120 dword FourierSlicer<S>::getImageHeight()
00121 {
00122   return m_ExternalHeight;
00123 }
00124 
00125 
00126 
00127 //***********************************************************************
00128 //***                     PRIVATE methods                             ***
00129 //***********************************************************************
00130 
00131 //Initialize the transfer function for the data.
00132 template <int S>
00133 void FourierSlicer<S>::_initTransferFunction()
00134 {
00135   // do nothing
00136 }
00137 
00138 //Render next view
00139 template <int S>
00140 void FourierSlicer<S>::_renderView(dword idx, vuSphericView<S,byte> *view,
00141                                    bool verbose)
00142 {
00143   Point3d  point  = m_Sphere->getPointAt(idx);
00144   vuVector lookAt(point.x, point.y, point.z);
00145   vuVector up(0,1,0);
00146   vuVector right;
00147 
00148   lookAt *= -1;
00149   m_Fourier->calcViewVectors(lookAt, up, right);
00150 
00151   // render the view
00152   if (verbose) {
00153     cerr << "render view: ";
00154     cerr.width(_numberOfDigits(m_NumOfViews - 1));
00155     cerr << idx << " ";
00156   }
00157 
00158   m_Fourier->setViewVectors(lookAt, up, right);
00159   if (m_TimingStream != NULL) {
00160     double time1 = vuTimer::getMilliSecondsAsDouble();
00161     m_Fourier->interpolateSlice();
00162     double time2 = vuTimer::getMilliSecondsAsDouble();
00163     m_Fourier->transformSlice();
00164     double time3 = vuTimer::getMilliSecondsAsDouble();
00165 
00166     m_TimingStream->setf(ios::fixed|ios::showpoint);
00167     m_TimingStream->width(12);
00168     *m_TimingStream <<  lookAt[0];
00169     m_TimingStream->width(12);
00170     *m_TimingStream <<  lookAt[1];
00171     m_TimingStream->width(12);
00172     *m_TimingStream <<  lookAt[2];
00173     m_TimingStream->width(14);
00174     *m_TimingStream << time2 - time1;
00175     m_TimingStream->width(14);
00176     *m_TimingStream << time3 - time2;
00177     *m_TimingStream << endl;
00178     m_Fourier->computeUnscaledImage(false);
00179   }
00180   else
00181     m_Fourier->computeUnscaledImage();
00182   
00183   // copy view to lightfield
00184   float *src = m_Fourier->getUnscaledImage()->getBuffer();
00185   byte  *dest = view->getMap()->getBuffer();
00186   float scale = m_Fourier->getScale();
00187   float bias  = m_Fourier->getBias();
00188 
00189   dword Xborder = (m_Width  - m_ExternalWidth)  / 2;
00190   dword Yborder = (m_Height - m_ExternalHeight) / 2;
00191 
00192   src += Yborder * m_Width * S;
00193   for (dword j=0; j<m_ExternalHeight; j++) {
00194     src += Xborder * S;
00195     for (dword i=0; i<m_ExternalWidth; i++) {
00196       for (int k=0; k<S; k++) {
00197         register float tmp = *(src++) * scale + bias;
00198         if (tmp < 0.0f) tmp = 0.0f;
00199         else if (tmp > 255.0f) tmp = 255.0f;
00200         *(dest++) = (byte)tmp;
00201       }
00202     }
00203     src +=Xborder * S;
00204   }
00205 
00206   view->setLookFrom(vuVector(point.x, point.y, point.z));
00207   view->setUp(up);
00208   cerr << "Done." << endl;
00209 }
00210 
00211 template <int S>
00212 word FourierSlicer<S>::_numberOfDigits(word number)
00213 {
00214   if (number > 9999) return 5;
00215   if (number >  999) return 4;
00216   if (number >   99) return 3;
00217   if (number >    9) return 2;
00218 
00219   return 1;
00220 }
00221 
00222 template <int S>
00223 void FourierSlicer<S>::_lazyCalculate(const char *fileName, bool display)
00224 {
00225   if (!m_isComputed) {
00226     vuSphericLightfieldFile<S,byte> *outFile = NULL;
00227     vuSphericView<S,byte>           *view    = NULL;
00228 
00229     view = new vuSphericView<S,byte>(m_ExternalWidth, m_ExternalHeight);
00230 
00231     outFile = new vuSphericLightfieldFile<S,byte>(m_ExternalWidth,
00232                                                   m_ExternalHeight,
00233                                                   m_NumOfViews,fileName);
00234 
00235     outFile->open();
00236     outFile->writeHeader();
00237 
00238     if (display) {
00239       glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00240       glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00241       glutSwapBuffers();
00242     }
00243 
00244     for (dword i=0; i<m_NumOfViews; i++) {
00245       if (display) {
00246         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00247         glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00248       }
00249 
00250       _renderView(i, view);
00251       outFile->writeView(view);
00252 
00253       if (display) {
00254         view->getMap()->glRender();
00255         glutSwapBuffers();
00256       }
00257     }
00258     outFile->close();
00259     CHECKNDELETE(view);
00260     CHECKNDELETE(outFile);
00261     m_isComputed = true;
00262   }
00263 }

Generated on Wed Dec 15 21:20:28 2004 for vuVolume by  doxygen 1.3.9.1