00001 #ifndef POLARCORRELATION_H
00002 #define POLARCORRELATION_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
00021 struct PolarCorrelationModule : public RecognitionModule
00022 {
00026 Micro& micro;
00027
00032 float correlationStrength;
00033
00037 ImageSource& src;
00038
00039 IplImage *kernel_img;
00040
00044 double *ffin, *kernelin, *ffback;
00045 fftw_plan plan, plan_kernel, planB;
00046 fftw_complex *ffout, *kernelout;
00047
00048 PolarCorrelationModule(Micro& m, ImageSource& As) :
00049 micro(m), src(As)
00050 {
00051 int w = src.img->width;
00052 int h = src.img->height;
00053
00054 ffin = (double*) fftw_malloc(w*h*sizeof(double));
00055 ffback = (double*) fftw_malloc(w*h*sizeof(double));
00056 kernelin = (double*) fftw_malloc(w*h*sizeof(double));
00057 ffout = (fftw_complex*) fftw_malloc(w*(h/2+1)*sizeof(fftw_complex));
00058 kernelout = (fftw_complex*) fftw_malloc(w*(h/2+1)*sizeof(fftw_complex));
00059
00060 kernel_img = cvCreateImage(cvSize(w,h), IPL_DEPTH_8U, 1);
00061 char wisdomfile[] = "wisdom.fftw3";
00062 FILE *f = fopen(wisdomfile, "r");
00063 if(f && fftw_import_wisdom_from_file(f)==1)
00064 {
00065 if(DEBUGLEVEL>=2) cerr << "Loaded wisdom from 'wisdom.fftw3'.\n";
00066 fclose(f);
00067 }
00068 else if(DEBUGLEVEL>=1) cerr << "Could not load wisdom from 'wisdom.fftw3'.\n";
00069
00070 plan = fftw_plan_dft_r2c_2d(w, h, (double*)ffin, (fftw_complex*)ffout, 0);
00071 planB = fftw_plan_dft_c2r_2d(w, h, (fftw_complex*)ffout, (double*)ffback, 0);
00072 f = fopen(wisdomfile, "w");
00073 if(f)
00074 {
00075 fftw_export_wisdom_to_file(f);
00076 fclose(f);
00077 }
00078
00079 paramChanged = true;
00080 }
00081
00082 void makeKernel(void)
00083 {
00084 if(!paramChanged) return;
00085 ENTER(3, endl)
00086 int w = src.img->width;
00087 int h = src.img->height;
00088
00089
00090 mypoint m(w/2,h/2);
00091 MicroAdam& adam= *dynamic_cast<MicroAdam*>(µ);
00092 int hab = 7;
00093
00094
00095 cvLine(kernel_img, m+mypoint( hab,0), m+mypoint( hab+5,-50), 255, 2);
00096 cvLine(kernel_img, m+mypoint(-hab,0), m+mypoint(-hab-5,-50), 255, 2);
00097
00098
00099 cvLine(kernel_img, m+mypoint( hab,0), m+mypoint( hab+40,0), 255, 2);
00100 cvLine(kernel_img, m+mypoint(-hab,0), m+mypoint(-hab-40,0), 255, 2);
00101
00102
00103 cvSaveImage("vorlage-polar.png", kernel_img);
00104
00105 circular_shift(kernel_img, kernel_img, w/2, h/2);
00106
00107 IplImage2fftw_real(kernel_img, (double*)kernelin, w, h);
00108 plan_kernel = fftw_plan_dft_r2c_2d(w, h,
00109 (double*)kernelin, (fftw_complex*)kernelout, 0);
00110 fftw_execute(plan_kernel);
00111 fftw_destroy_plan(plan_kernel);
00112 paramChanged = false;
00113 }
00114
00115 static int above_threshold(double v)
00116 {
00117 return v > 10*255;
00118 }
00119
00120 void processKeyFrame(void)
00121 {
00122 #ifdef DEBUG
00123 if(DEBUGLEVEL>=3) cerr << "->correlate2()\n";
00124 #endif
00125 if(!src.outputChanged && !paramChanged) return;
00126
00127 makeKernel();
00128
00129 int w = src.img->width;
00130 int h = src.img->height;
00131
00132 IplImage2fftw_real(src.img, (double*)ffin);
00133
00134 fftw_execute(plan);
00135
00136
00137 fftw_complex_multiply_conjugate((fftw_complex*)ffout, (fftw_complex*)kernelout,
00138 w, h/2+1);
00139
00140 fftw_execute(planB);
00141
00142 IplImage *backI = cvCreateImage(cvSize(src.img->width, src.img->height), IPL_DEPTH_8U, 3);
00143 doubles2IplImage(1/150.0, backI, (double*)ffback,
00144 backI->width, backI->height, above_threshold);
00145 cvSaveImage("polar-correlation.png", backI);
00146
00147 maximum max;
00148 findMaxPoint(w, h, ffback, 1.0, &max);
00149 if(max.x>=0 && max.y>=0)
00150 {
00151 micro.alpha = max.x;
00152 }
00153 else
00154 {
00155 if(DEBUGLEVEL>=2) cerr << "Correlation: no global max?\n";
00156 }
00157
00158 outputChanged = true;
00159 #ifdef DEBUG
00160 if(DEBUGLEVEL>=3) cerr << "<-correlate2()\n";
00161 #endif
00162 }
00163
00164 void processFrame(myrect *ROI)
00165 {
00166 processKeyFrame();
00167 }
00168
00169 ~PolarCorrelationModule()
00170 {
00171 fftw_destroy_plan(plan);
00172 fftw_destroy_plan(planB);
00173 cvReleaseImage(&kernel_img);
00174 fftw_free(ffin); ffin = NULL;
00175 fftw_free(ffback); ffback = NULL;
00176 fftw_free(kernelin); kernelin = NULL;
00177 fftw_free(ffout); ffout = NULL;
00178 fftw_free(kernelout); kernelout = NULL;
00179 }
00180
00181 };
00182
00183 }
00184
00185 #endif
00186