25 #include <OpenCLFramework/Algorithm/clfTVL1Flow.hh>
28 #undef WRITE_DBG_IMAGES
37 sigma_ = 1.0f/sqrt(8.0f);
38 tau_ = 1.0f/sqrt(8.0f);
55 programCL_ = context_->CreateProgram();
58 programCL_->AddSource(
"/OpenCLFramework/Algorithm/cl/tvl1flow.cl");
60 programCL_->AddKernel(
"Warp");
61 programCL_->AddKernel(
"UvwGrad");
62 programCL_->AddKernel(
"UpdateP");
63 programCL_->AddKernel(
"UpdateDiv");
64 programCL_->AddKernel(
"UpdateUVW");
65 programCL_->AddKernel(
"UpdateUVWold");
66 programCL_->AddKernel(
"WeightedGradX");
67 programCL_->AddKernel(
"WeightedGradY");
68 programCL_->AddKernel(
"CreateColorCoded");
72 image1_ = context_->CreateImage2D();
73 image2_ = context_->CreateImage2D();
74 debug_ = context_->CreateImage2D();
79 clfTVL1Flow::~clfTVL1Flow() {
81 for (
unsigned int i=0;i<pyramid1_.size();i++) {
89 delete image2warpedt_[i];
94 delete imageCopy2_[i];
108 void clfTVL1Flow::SetNumberOfIterations(
unsigned int iternumber)
110 maxIterations_ = iternumber;
113 void clfTVL1Flow::SetSmoothness(
const float& smoothness)
115 lambda_ = smoothness;
119 uvw_[0]->CopyToBiasImage(image);
124 programCL_->KernelSetArgument(
"CreateColorCoded", 0, *uvw_[0]);
125 programCL_->KernelSetArgument(
"CreateColorCoded", 1, *imageCopy_[0]);
127 imageCopy_[0]->GetImageDim(w,h);
128 context_->RunOn2DRange(*programCL_,
"CreateColorCoded", w,h,16,16);
129 imageCopy_[0]->CopyToBiasImage(image);
136 image1_->AllocateFromBiasImage(image,
true,
false,
true);
137 image2_->AllocateFromBiasImage(image,
true,
false,
true);
140 while (curHeight % 16 == 0) {
141 pyramid1_.push_back(newImage_(curWidth, curHeight));
142 pyramid2_.push_back(newImage_(curWidth, curHeight));
143 uvw_.push_back(newImage_(curWidth, curHeight,
true));
144 uvwX_.push_back(newImage_(curWidth, curHeight));
145 uvwY_.push_back(newImage_(curWidth, curHeight));
146 uvw0_.push_back(newImage_(curWidth, curHeight));
147 uvwOld_.push_back(newImage_(curWidth, curHeight));
148 image2warpedt_.push_back(newImage_(curWidth, curHeight));
149 imageDiv_.push_back(newImage_(curWidth, curHeight));
150 P1_.push_back(newImage_(curWidth, curHeight,
true));
151 P2_.push_back(newImage_(curWidth, curHeight,
true));
152 Ixyg_.push_back(newImage_(curWidth, curHeight));
153 imageCopy_.push_back(newImage_(curWidth, curHeight));
154 imageCopy2_.push_back(newImage_(curWidth, curHeight));
159 }
else if (numIm_ == 1) {
164 colorConvCL_->UCharRGBToFloatGreyNormalized( image1_, pyramid1_[0]);
165 colorConvCL_->UCharRGBToFloatGreyNormalized( image2_, pyramid2_[0]);
167 colorConvCL_->UCharGreyToFloatGrey( image1_, pyramid1_[0],
true);
168 colorConvCL_->UCharGreyToFloatGrey( image2_, pyramid2_[0],
true);
171 CreatePyramid_(pyramid1_);
172 CreatePyramid_(pyramid2_);
173 levels_ = (
unsigned int)pyramid1_.size();
181 for (
unsigned int i=0;i<levels_;i++) {
183 pyramid1_[i] = pyramid2_[i];
189 colorConvCL_->UCharRGBToFloatGreyNormalized( image2_, pyramid2_[0]);
191 colorConvCL_->UCharGreyToFloatGrey( image1_, pyramid1_[0],
true);
194 CreatePyramid_(pyramid2_);
196 clearFilter_->Clear(0.0f, uvw_[levels_-1]);
197 clearFilter_->Clear(0.0f, P1_[levels_-1]);
198 clearFilter_->Clear(0.0f, P2_[levels_-1]);
203 clfImage2D* clfTVL1Flow::newImage_(
unsigned int w,
unsigned int h,
bool clear) {
205 pim->
Allocate(ImageBase::ST_float, ImageBase::CM_RGBA, w, h, 0,
false,
false);
207 clearFilter_->Clear(0.0f, pim);
213 void clfTVL1Flow::CreatePyramid_(std::vector<clfImage2D *> &pyramid) {
214 for (
unsigned int i=1;i<pyramid.size();i++) {
215 downsampleCL_->FilterScale( pyramid[i-1], pyramid[i], 0.5f);
220 upsampleCL_->GetProgram()->KernelSetArgument(
"UpsampleBy2", 2, scale);
221 upsampleCL_->Filter(src,dst);
224 void clfTVL1Flow::Compute() {
225 if (numIm_ < 2)
return;
227 for (
int level = (
int)pyramid1_.size() -1;level>=0;level--) {
228 if (level != (
int) pyramid1_.size() -1) {
230 Upsample_(uvw_[level+1], uvw_[level], 2.0f);
231 Upsample_(P1_[level+1], P1_[level]);
232 Upsample_(P2_[level+1], P2_[level]);
237 #ifdef WRITE_DBG_IMAGES
239 pyramid1_[level]->CopyToBiasImage(debug);
240 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-im0.mip", debug);
241 pyramid2_[level]->CopyToBiasImage(debug);
242 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-im1.mip", debug);
243 uvw_[level]->CopyToBiasImage(debug);
244 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-uvw.mip", debug);
245 uvwX_[level]->CopyToBiasImage(debug);
246 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-uvwX.mip", debug);
247 uvwY_[level]->CopyToBiasImage(debug);
248 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-uvwY.mip", debug);
249 image2warpedt_[level]->CopyToBiasImage(debug);
250 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-image2warpedt_.mip", debug);
251 Ixyg_[level]->CopyToBiasImage(debug);
252 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-Ixyg_.mip", debug);
253 P1_[level]->CopyToBiasImage(debug);
254 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-p1_.mip", debug);
255 P2_[level]->CopyToBiasImage(debug);
256 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-p2_.mip", debug);
257 imageDiv_[level]->CopyToBiasImage(debug);
258 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-div_.mip", debug);
259 Ixyg_[level]->CopyToBiasImage(debug);
260 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-grad.mip", debug);
261 #endif // WRITE_DBG_IMAGES
265 void clfTVL1Flow::Warp_(
unsigned int level) {
277 programCL_->KernelSetArgument(
"WeightedGradX", 0, *image1);
278 programCL_->KernelSetArgument(
"WeightedGradX", 1, *tmp);
279 context_->RunOn2DRange(*programCL_,
"WeightedGradX", w,h, 16,16);
283 programCL_->KernelSetArgument(
"WeightedGradY", 0, *image1);
284 programCL_->KernelSetArgument(
"WeightedGradY", 1, *tmp);
285 programCL_->KernelSetArgument(
"WeightedGradY", 2, *Ixyg);
286 programCL_->KernelSetArgument(
"WeightedGradY", 3, gamma_);
287 context_->RunOn2DRange(*programCL_,
"WeightedGradY", w,h, 16,16);
290 programCL_->KernelSetArgument(
"Warp", 0, *image1);
291 programCL_->KernelSetArgument(
"Warp", 1, *image2);
292 programCL_->KernelSetArgument(
"Warp", 2, *uvw);
293 programCL_->KernelSetArgument(
"Warp", 3, *warped);
294 context_->RunOn2DRange(*programCL_,
"Warp", w,h,16,16);
298 void clfTVL1Flow::ComputeFlow_(
unsigned int level) {
314 programCL_->KernelSetArgument(
"UvwGrad", 0, *uvwold);
315 programCL_->KernelSetArgument(
"UvwGrad", 1, *uvwX);
316 programCL_->KernelSetArgument(
"UvwGrad", 2, *uvwY);
318 programCL_->KernelSetArgument(
"UpdateP", 0, *tmp);
319 programCL_->KernelSetArgument(
"UpdateP", 1, *tmp2);
320 programCL_->KernelSetArgument(
"UpdateP", 2, *uvwX);
321 programCL_->KernelSetArgument(
"UpdateP", 3, *uvwY);
322 programCL_->KernelSetArgument(
"UpdateP", 4, *p1);
323 programCL_->KernelSetArgument(
"UpdateP", 5, *p2);
324 programCL_->KernelSetArgument(
"UpdateP", 6, sigma_);
326 programCL_->KernelSetArgument(
"UpdateDiv", 0, *p1);
327 programCL_->KernelSetArgument(
"UpdateDiv", 1, *p2);
328 programCL_->KernelSetArgument(
"UpdateDiv", 2, *div);
330 programCL_->KernelSetArgument(
"UpdateUVW", 0, *uvwold);
331 programCL_->KernelSetArgument(
"UpdateUVW", 1, *div);
332 programCL_->KernelSetArgument(
"UpdateUVW", 2, *uvw0);
333 programCL_->KernelSetArgument(
"UpdateUVW", 3, *Ixyg);
334 programCL_->KernelSetArgument(
"UpdateUVW", 4, *warped);
336 programCL_->KernelSetArgument(
"UpdateUVW", 5, *uvw);
337 programCL_->KernelSetArgument(
"UpdateUVW", 6, tau_);
338 programCL_->KernelSetArgument(
"UpdateUVW", 7, lambda_);
339 programCL_->KernelSetArgument(
"UpdateUVW", 8, gamma_);
341 programCL_->KernelSetArgument(
"UpdateUVWold", 0, *tmp);
342 programCL_->KernelSetArgument(
"UpdateUVWold", 1, *uvw);
343 programCL_->KernelSetArgument(
"UpdateUVWold", 2, *uvwold);
353 for (
unsigned int j=0;j<warps_;j++) {
359 for (
unsigned int k=0;k<maxIterations_;k++) {
361 context_->RunOn2DRange(*programCL_,
"UvwGrad", w,h,16,16);
366 context_->RunOn2DRange(*programCL_,
"UpdateP", w,h,16,16);
368 context_->RunOn2DRange(*programCL_,
"UpdateDiv", w,h,16,16);
372 context_->RunOn2DRange(*programCL_,
"UpdateUVW", w,h,16,16);
375 context_->RunOn2DRange(*programCL_,
"UpdateUVWold", w,h, 16,16);
377 #ifdef WRITE_DBG_IMAGES
381 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-"+FileHandling::LeadingZeroString(k,2)+
"-uvwold.mip", debug);
383 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-"+FileHandling::LeadingZeroString(k,2)+
"-uvw.mip", debug);
385 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-"+FileHandling::LeadingZeroString(k,2)+
"-p1.mip", debug);
387 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-"+FileHandling::LeadingZeroString(k,2)+
"-p2.mip", debug);
389 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-"+FileHandling::LeadingZeroString(k,2)+
"-div.mip", debug);
391 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-"+FileHandling::LeadingZeroString(k,2)+
"-Ixyg.mip", debug);
393 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-"+FileHandling::LeadingZeroString(k,2)+
"-uvwX.mip", debug);
395 ImageIO::Save(
"cbg-"+FileHandling::LeadingZeroString(level,2)+
"-"+FileHandling::LeadingZeroString(k,2)+
"-uvwY.mip", debug);
397 #endif // WRITE_DBG_IMAGES
void GetImageDim(unsigned int &width, unsigned int &height) const
void Allocate(BIAS::ImageBase::EStorageType st, BIAS::ImageBase::EColorModel cm, unsigned int width, unsigned int height, unsigned int stride=0, bool readonly=false, bool writeonly=false, const void *hostptr=NULL, bool copy=false)
Allocation of a memory buffer as 2D image, either call directly or use wrapper for BIAS::ImageBase...
unsigned int GetWidth() const
clfDeviceInfo GetDeviceInfo(unsigned int device=0)
unsigned int GetHeight() const
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
enum EColorModel GetColorModel() const
void CopyToBiasImage(BIAS::ImageBase &image, unsigned int originX=0, unsigned int originY=0, unsigned int regionX=0, unsigned int regionY=0)
void WriteToImage(const void *data, unsigned int originX=0, unsigned int originY=0, unsigned int regionX=0, unsigned int regionY=0, bool blocking=true)
write from host memory to image
void CopyToImage(clfImage2D &outputimage, unsigned int srcoriginX=0, unsigned int srcoriginY=0, unsigned int dstoriginX=0, unsigned int dstoriginY=0, unsigned int regionX=0, unsigned int regionY=0, bool blocking=true)
virtual int Build(unsigned int size)