source: flair-src/branches/sanscv/lib/FlairVisionFilter/src/OpticalFlow.cpp @ 325

Last change on this file since 325 was 325, checked in by Sanahuja Guillaume, 2 years ago

using pimpl

File size: 7.3 KB
Line 
1//  created:    2012/04/12
2//  filename:   OpticalFlow.cpp
3//
4//  author:     Guillaume Sanahuja
5//              Copyright Heudiasyc UMR UTC/CNRS 7253
6//
7//  version:    $Id: $
8//
9//  purpose:    calcul flux optique lk
10//
11//
12/*********************************************************************/
13
14#include "OpticalFlow.h"
15#include "OpticalFlowData.h"
16#include "VisionFilter.h"
17#include <Image.h>
18#include <Layout.h>
19#include <GroupBox.h>
20#include <SpinBox.h>
21//#include <dspcv_gpp.h>
22#include <algorithm>
23#include <OneAxisRotation.h>
24#include <Vector3D.h>
25#include <typeinfo>
26
27#define LEVEL_PYR 2
28
29using std::string;
30using std::swap;
31using namespace flair::core;
32using namespace flair::gui;
33
34class OpticalFlow_impl {
35public:
36    OpticalFlow_impl(flair::filter::OpticalFlow *self,const LayoutPosition* position,string name) {
37        this->self=self;
38        is_init=false;
39
40        GroupBox* reglages_groupbox=new GroupBox(position,name);
41        rotation=new OneAxisRotation(reglages_groupbox->NewRow(),"post rotation",OneAxisRotation::PostRotation);
42        max_features=new SpinBox(reglages_groupbox->NewRow(),"max features:",1,65535,1,1);
43       
44        try{
45            Image::Type const &imageType=dynamic_cast<Image::Type const &>(((IODevice*)(self->Parent()))->GetOutputDataType());
46            pyr=new Image(self,imageType.GetWidth(),imageType.GetHeight(),Image::Type::Format::Gray);
47            pyr_old=new Image(self,imageType.GetWidth(),imageType.GetHeight(),Image::Type::Format::Gray);
48            output=new flair::filter::OpticalFlowData(self->Parent(),max_features->Value());
49/*
50            pointsA=(CvPoint*)AllocFunction(max_features->Value()*sizeof(CvPoint));
51            pointsB=(CvPoint*)AllocFunction(max_features->Value()*sizeof(CvPoint));
52
53            found_feature=(char*)AllocFunction(max_features->Value()*sizeof(char));
54            feature_error=(unsigned int*)AllocFunction(max_features->Value()*sizeof(unsigned int));
55           
56            iplgimg = (IplImage*)AllocFunction(sizeof(IplImage));
57            iplgimg_old = (IplImage*)AllocFunction(sizeof(IplImage));
58            iplpyr = (IplImage*)AllocFunction(sizeof(IplImage));
59            iplpyr_old = (IplImage*)AllocFunction(sizeof(IplImage));
60           
61            iplpyr->width=imageType.GetWidth();
62            iplpyr->height=imageType.GetHeight();
63            iplpyr_old->width=imageType.GetWidth();
64            iplpyr_old->height=imageType.GetHeight();
65*/ 
66      } catch(std::bad_cast& bc) {
67            self->Err("io type mismatch\n");
68            pyr=NULL;
69            pyr_old=NULL;
70        }
71     
72    }
73
74    ~OpticalFlow_impl() {
75        /*
76        FreeFunction((char*)pointsA);
77        FreeFunction((char*)pointsB);
78        FreeFunction((char*)found_feature);
79        FreeFunction((char*)feature_error);
80        FreeFunction((char*)iplgimg);
81        FreeFunction((char*)iplgimg_old);
82        FreeFunction((char*)iplpyr);
83        FreeFunction((char*)iplpyr_old);*/
84    }
85   
86    void UpdateFrom(const io_data *data){
87        //Time tStart=GetTime();
88        Image *img=(Image*)data;
89        Image *img_old=((Image*)data->Prev(1));
90/*
91        iplgimg->width=img->GetDataType().GetWidth();
92        iplgimg->height=img->GetDataType().GetHeight();
93        iplgimg->imageData=img->buffer;
94       
95        iplgimg_old->width=img_old->GetDataType().GetWidth();
96        iplgimg_old->height=img_old->GetDataType().GetHeight();
97        iplgimg_old->imageData=img_old->buffer;
98       
99        iplpyr->imageData=pyr->buffer;
100        iplpyr_old->imageData=pyr_old->buffer;
101
102        unsigned int count;
103        CvSize window = {3,3};
104        CvTermCriteria termination_criteria ={CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, .3 };
105        unsigned int i;
106
107        if(max_features->ValueChanged()==true) {
108            FreeFunction((char*)pointsA);
109            FreeFunction((char*)pointsB);
110            FreeFunction((char*)found_feature);
111            FreeFunction((char*)feature_error);
112            pointsA=(CvPoint*)AllocFunction(max_features->Value()*sizeof(CvPoint));
113            pointsB=(CvPoint*)AllocFunction(max_features->Value()*sizeof(CvPoint));
114            found_feature=(char*)AllocFunction(max_features->Value()*sizeof(char));
115            feature_error=(unsigned int*)AllocFunction(max_features->Value()*sizeof(unsigned int));
116
117            output->Resize(max_features->Value());
118        }
119
120        if(is_init==false) {
121            data->GetMutex();
122            //init image old
123            dspPyrDown(iplgimg,iplpyr_old,LEVEL_PYR);
124            data->ReleaseMutex();
125            is_init=true;
126            printf("ajouter mise a 0 des points\n");
127            return;
128        }
129
130        data->GetMutex();
131        data->Prev(1)->GetMutex();
132
133        //select good features
134        count=max_features->Value();
135        dspGoodFeaturesToTrack(iplgimg_old,pointsA,&count,0.08,5);
136        //pyramide
137        dspPyrDown(iplgimg,iplpyr,LEVEL_PYR);
138        //lk
139        dspCalcOpticalFlowPyrLK(iplgimg_old,iplgimg,iplpyr_old,iplpyr,pointsA,pointsB,count,window,LEVEL_PYR,found_feature,feature_error,termination_criteria,0) ;
140
141        data->Prev(1)->ReleaseMutex();
142        data->ReleaseMutex();
143
144        //apply rotation
145        for(i=0;i<count;i++) {
146            Vector3Df tmp;
147            tmp.x=pointsA[i].x;
148            tmp.y=pointsA[i].y;
149            tmp.z=0;
150            rotation->ComputeRotation(tmp);
151            pointsA[i].x=tmp.x;
152            pointsA[i].y=tmp.y;
153
154            tmp.x=pointsB[i].x;
155            tmp.y=pointsB[i].y;
156            tmp.z=0;
157            rotation->ComputeRotation(tmp);
158            pointsB[i].x=tmp.x;
159            pointsB[i].y=tmp.y;
160        }
161
162        output->GetMutex();
163        CvPoint2D32f* pointsBf= output->PointsB();
164        for(i=0;i<count;i++) {
165            pointsBf[i].x=pointsA[i].x+((float)pointsB[i].x)/256;
166            pointsBf[i].y=pointsA[i].y+((float)pointsB[i].y)/256;
167        }
168        output->ReleaseMutex();
169
170        output->SetPointsA(pointsA);
171        output->SetFoundFeature(found_feature);
172        output->SetFeatureError(feature_error);
173        output->SetNbFeatures(count);
174
175        //rotation
176        swap(pyr,pyr_old);
177*/
178        output->SetDataTime(data->DataTime());
179        //Printf("Optical flow computation time=%f\n",(GetTime()-tStart)/(1000.*1000));
180    };
181   
182    flair::filter::OpticalFlowData *output;
183
184private:
185    flair::filter::OpticalFlow *self;
186    SpinBox *max_features;
187    OneAxisRotation* rotation;
188
189    //CvPoint* pointsA;
190    //CvPoint* pointsB;
191    char *found_feature;
192    unsigned int *feature_error;
193    Image *pyr,*pyr_old;
194    //IplImage *iplgimg,*iplgimg_old;
195    //IplImage *iplpyr,*iplpyr_old;
196
197    bool is_init;
198};
199
200
201namespace flair
202{
203namespace filter
204{
205
206OpticalFlow::OpticalFlow(const IODevice* parent,const LayoutPosition* position,string name) : IODevice(parent,name) {
207    Printf("optical flow: voir pour faire du multiple output\n");//pour pts A et B, found et error
208    pimpl_=new OpticalFlow_impl(this,position,name);
209}
210
211OpticalFlow::~OpticalFlow(void) {
212    delete pimpl_;
213}
214
215void OpticalFlow::UpdateFrom(const io_data *data) {
216    pimpl_->UpdateFrom(data);
217    ProcessUpdate(pimpl_->output);
218}
219
220OpticalFlowData* OpticalFlow::Output(void) {
221    return pimpl_->output;
222
223}
224
225DataType const &OpticalFlow::GetOutputDataType() const {
226    if(pimpl_->output!=NULL) {
227        return pimpl_->output->GetDataType();
228    } else {
229        return dummyType;
230    }
231}
232
233} // end namespace filter
234} // end namespace flair
Note: See TracBrowser for help on using the repository browser.