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

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