00001 #ifndef CORRELATION_H
00002 #define CORRELATION_H
00003
00004 #include "../fftwext.h"
00005 #include "recognition.h"
00006 #include "imagesource.h"
00007 #include "../micro.h"
00008 #include <iostream>
00009
00010
00011 extern "C"
00012 {
00013 #include <opencv/highgui.h>
00014 }
00015
00016 using namespace std;
00017
00018 namespace seemicro
00019 {
00020
00032 struct CorrelationModule : public RecognitionModule
00033 {
00037 Micro& micro;
00038
00043 float correlationStrength;
00044
00048 ImageSource& src;
00049
00054 Micro *kparams;
00055
00064 int arm_auch;
00065
00066 IplImage *kernel_img;
00067
00071 double *ffin, *kernelin, *ffback;
00072 fftw_plan plan, plan_kernel, planB;
00073 fftw_complex *ffout, *kernelout;
00074
00075 CorrelationModule(Micro& m, ImageSource& As, Micro *Ak) :
00076 micro(m), src(As), kparams(Ak)
00077 {
00078 int w = src.img->width;
00079 int h = src.img->height;
00080
00081 ffin = (double*) fftw_malloc(w*h*sizeof(double));
00082 ffback = (double*) fftw_malloc(w*h*sizeof(double));
00083 kernelin = (double*) fftw_malloc(w*h*sizeof(double));
00084 ffout = (fftw_complex*) fftw_malloc(w*(h/2+1)*sizeof(fftw_complex));
00085 kernelout = (fftw_complex*) fftw_malloc(w*(h/2+1)*sizeof(fftw_complex));
00086
00087 kernel_img = cvCreateImage(cvSize(w,h), IPL_DEPTH_8U, 1);
00088 char wisdomfile[] = "wisdom.fftw3";
00089 FILE *f = fopen(wisdomfile, "r");
00090 if(f && fftw_import_wisdom_from_file(f)==1)
00091 {
00092 if(DEBUGLEVEL>=2) cerr << "Loaded wisdom from 'wisdom.fftw3'.\n";
00093 fclose(f);
00094 }
00095 else if(DEBUGLEVEL>=1) cerr << "Could not load wisdom from 'wisdom.fftw3'.\n";
00096
00097 plan = fftw_plan_dft_r2c_2d(w, h, (double*)ffin, (fftw_complex*)ffout, 0);
00098 planB = fftw_plan_dft_c2r_2d(w, h, (fftw_complex*)ffout, (double*)ffback, 0);
00099 f = fopen(wisdomfile, "w");
00100 if(f)
00101 {
00102 fftw_export_wisdom_to_file(f);
00103 fclose(f);
00104 }
00105
00106 kparams->mitte.p.x = w/2;
00107 kparams->mitte.p.y = h/2;
00108 kparams->radius = w/4;
00109 kparams->alpha = 0;
00110
00111 micro.mitteValid = false;
00112
00113 arm_auch = false;
00114 paramChanged = true;
00115 }
00116
00117 void makeKernel(void)
00118 {
00119 if(!paramChanged) return;
00120 int w = src.img->width;
00121 int h = src.img->height;
00122 kparams->mitte.p.x = w/2;
00123 kparams->mitte.p.y = h/2;
00124 #ifdef DEBUG
00125 if(DEBUGLEVEL>=3) cerr << "entered makeKernel():" << *kparams << endl;
00126 #endif
00127 kparams->draw(kernel_img, 0, 0.0, 1, arm_auch);
00128
00129
00130
00131 circular_shift(kernel_img, kernel_img, w/2, h/2);
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 IplImage2fftw_real(kernel_img, (double*)kernelin, w, h);
00144 plan_kernel = fftw_plan_dft_r2c_2d(w, h,
00145 (double*)kernelin, (fftw_complex*)kernelout, 0);
00146 fftw_execute(plan_kernel);
00147 fftw_destroy_plan(plan_kernel);
00148 micro.mitteValid = false;
00149 paramChanged = false;
00150
00151 #ifdef DEBUG
00152 if(DEBUGLEVEL>=3) cerr << "<-makeKernel()\n";
00153 #endif
00154 }
00155
00156 void makeKernel(Micro& p)
00157 {
00158 *kparams = p;
00159 paramChanged = true;
00160 makeKernel();
00161 }
00162
00163 void processKeyFrame(void)
00164 {
00165 #ifdef DEBUG
00166 if(DEBUGLEVEL>=3) cerr << "->correlate()\n";
00167 #endif
00168 if(!src.outputChanged && !paramChanged) return;
00169
00170 makeKernel();
00171
00172 int w = src.img->width;
00173 int h = src.img->height;
00174 IplImage2fftw_real(src.img, (double*)ffin);
00175 micro.mitteValid = false;
00176
00177 fftw_execute(plan);
00178
00179
00180
00181
00182 fftw_complex_multiply_conjugate((fftw_complex*)ffout, (fftw_complex*)kernelout,
00183 w, h/2+1);
00184
00185 fftw_execute(planB);
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 maximum max;
00199 findMaxPoint(w, h, ffback, 1.0, &max);
00200 if(max.x>=0 && max.y>=0)
00201 {
00202 micro.mitte.p.x = max.x;
00203 micro.mitte.p.y = max.y;
00204 micro.mitteValid = true;
00205 correlationStrength = max.v;
00206 }
00207 else
00208 {
00209 micro.mitteValid = false;
00210 if(DEBUGLEVEL>=2) cerr << "Correlation: no global max?\n";
00211 }
00212
00213 micro.radius = kparams->radius;
00214 outputChanged = true;
00215 #ifdef DEBUG
00216 if(DEBUGLEVEL>=3) cerr << "<-correlate()\n";
00217 #endif
00218 }
00219
00224 void processFrame(myrect *ROI)
00225 {
00226 }
00227
00228 ~CorrelationModule()
00229 {
00230 fftw_destroy_plan(plan);
00231 fftw_destroy_plan(planB);
00232 cvReleaseImage(&kernel_img);
00233 fftw_free(ffin); ffin = NULL;
00234 fftw_free(ffback); ffback = NULL;
00235 fftw_free(kernelin); kernelin = NULL;
00236 fftw_free(ffout); ffout = NULL;
00237 fftw_free(kernelout); kernelout = NULL;
00238 }
00239
00240 };
00241
00242 }
00243
00244 #endif
00245