DirectionOpticalFlowChannel.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef DIRECTION_OPTICALFLOW_CHANNEL_C_DEFINED
00038 #define DIRECTION_OPTICALFLOW_CHANNEL_C_DEFINED
00039
00040 #include "Channels/DirectionOpticalFlowChannel.H"
00041
00042 #include "rutz/trace.h"
00043 #include "Image/Image.H"
00044 #include "Raster/Raster.H"
00045
00046 #define OF_WINDOW_SIZE 4
00047 #define OF_VALUE_RADIUS 1
00048
00049
00050
00051
00052
00053
00054 DirectionOpticalFlowChannel::DirectionOpticalFlowChannel
00055 (OptionManager& mgr,
00056 const uint dirIndex, const double direction,
00057 const OpticalFlowType type):
00058 SingleChannel(mgr, "", "", MOTIONSPATIOTEMPORAL,
00059 rutz::make_shared(new GaussianPyrBuilder<float>(1))),
00060 itsDirIndex("DirectionChannelDirectionIndex", this, dirIndex),
00061 itsDirection("DirectionChannelDirection", this, direction),
00062 itsOpticalFlowType(type)
00063 {
00064 GVX_TRACE(__PRETTY_FUNCTION__);
00065
00066 setDescriptiveName(sformat("DirectionSpeed(%d)", int(direction)));
00067 setTagName(sformat("dir_%d", dirIndex));
00068 }
00069
00070
00071 void DirectionOpticalFlowChannel::start1()
00072 {
00073 GVX_TRACE(__PRETTY_FUNCTION__);
00074 itsLevelSpec.setVal(LevelSpec(0,0,0,0,4) );
00075 SingleChannel::start1();
00076 }
00077
00078
00079 void DirectionOpticalFlowChannel::start2()
00080 {
00081 GVX_TRACE(__PRETTY_FUNCTION__);
00082
00083 }
00084
00085
00086 DirectionOpticalFlowChannel::~DirectionOpticalFlowChannel()
00087 {
00088 GVX_TRACE(__PRETTY_FUNCTION__);
00089 }
00090
00091
00092 bool DirectionOpticalFlowChannel::outputAvailable() const
00093 {
00094 return itsDirectionalOpticalFlow.initialized();
00095 }
00096
00097
00098
00099 void DirectionOpticalFlowChannel::setLucasKanadeOpticalFlow
00100 (rutz::shared_ptr<OpticalFlow> flow)
00101 {
00102 ASSERT(itsOpticalFlowType == LucasKanade);
00103 itsOpticalFlow = flow;
00104 }
00105
00106
00107 void DirectionOpticalFlowChannel::doInput(const InputFrame& inframe)
00108 {
00109 GVX_TRACE(__PRETTY_FUNCTION__);
00110
00111 if (!this->started())
00112 CLFATAL("must be start()-ed before using receiving any input");
00113
00114
00115
00116 SingleChannel::doInput(inframe);
00117
00118
00119 switch(itsOpticalFlowType)
00120 {
00121 case LucasKanade:
00122 if(itsOpticalFlow.is_invalid())
00123 LFATAL("need to provide optical flow. "
00124 "Use setLucasKanadeOpticalFlow(flow)");
00125 computeDirectionalOpticalFlow();
00126 break;
00127 case HornSchunck:
00128 break;
00129 default: LERROR("Unknown optical flow mode");
00130 }
00131 }
00132
00133
00134 void DirectionOpticalFlowChannel::computeDirectionalOpticalFlow()
00135 {
00136 Dims d = itsOpticalFlow->getImageDims();
00137 itsDirectionalOpticalFlow =
00138 Image<float>(d.w()/ OF_WINDOW_SIZE, d.h()/ OF_WINDOW_SIZE, ZEROS);
00139
00140
00141
00142
00143 std::vector<rutz::shared_ptr<FlowVector> > flow =
00144 itsOpticalFlow->getFlowVectors();
00145
00146 for(uint i = 0; i < flow.size(); i++)
00147 {
00148 Point2D<int> pt1((int)flow[i]->p1.i, (int)flow[i]->p1.j);
00149 Point2D<int> pt2((int)flow[i]->p2.i, (int)flow[i]->p2.j);
00150
00151 float ang = flow[i]->angle;
00152
00153 float fval = flow[i]->val;
00154
00155
00156 float rv = getResponseValue(ang);
00157 computeDirectionalOpticalFlow(pt1.i, pt1.j, rv*fval);
00158
00159
00160
00161 }
00162 }
00163
00164
00165 float DirectionOpticalFlowChannel::getResponseValue(float angle)
00166 {
00167 float pangle = itsDirection.getVal();
00168
00169
00170 float nangle = fmod(angle +360.0, 360.0);
00171
00172
00173 float diff1 = fabs(nangle - pangle);
00174 float diff2 = 360.0 - diff1;
00175 float diff = diff1; if(diff1 > diff2) diff = diff2;
00176
00177
00178 float val = 0.0;
00179 float stdang = 15.0;
00180
00181
00182 if(diff >= 0 && diff < stdang)
00183 val = (stdang - diff)/stdang * 0.2 + 0.8;
00184
00185
00186 else if(diff >= stdang && diff < 2*stdang)
00187 val = (2*stdang - diff)/stdang * 0.8 + 0.0;
00188
00189
00190 else
00191 val = 0.0;
00192
00193 return val;
00194 }
00195
00196
00197 void DirectionOpticalFlowChannel::computeDirectionalOpticalFlow
00198 (uint i, uint j, float val)
00199 {
00200
00201 uint ii = i/OF_WINDOW_SIZE;
00202 uint jj = j/OF_WINDOW_SIZE;
00203
00204
00205
00206
00207 uint ri = OF_VALUE_RADIUS;
00208 uint rj = OF_VALUE_RADIUS;
00209
00210 uint width = itsDirectionalOpticalFlow.getWidth();
00211 uint height = itsDirectionalOpticalFlow.getHeight();
00212
00213 uint lm = 0; if(ii > ri-1) lm = ii - ri;
00214 uint rm = width-1; if(ii < width-1-ri) rm = ii + ri;
00215 uint tm = 0; if(jj > rj-1) tm = jj - rj;
00216 uint bm = height-1; if(jj < height-1-ri) bm = jj + rj;
00217
00218
00219 float max = double (ri*2);
00220 for(uint bi = lm; bi <= rm; bi++)
00221 {
00222 for(uint bj = tm; bj <= bm; bj++)
00223 {
00224
00225 float di = float(bi) - float(ii);
00226 float dj = float(bj) - float(jj);
00227 float w = 1.0 - (sqrt(di*di + dj*dj))/max;
00228 float ov = itsDirectionalOpticalFlow.getVal(bi, bj);
00229 itsDirectionalOpticalFlow.setVal(bi, bj, ov+w*val);
00230
00231 }
00232 }
00233 }
00234
00235
00236 Image<float> DirectionOpticalFlowChannel::getDirectionalOpticalFlow()
00237 {
00238 return itsDirectionalOpticalFlow;
00239 }
00240
00241
00242
00243
00244
00245
00246
00247 #endif // DIRECTION_OPTICALFLOW_CHANNEL_C_DEFINED