updated GPU version of TVL1
authorVladislav Vinogradov <vlad.vinogradov@itseez.com>
Fri, 29 Mar 2013 07:36:36 +0000 (11:36 +0400)
committerVladislav Vinogradov <vlad.vinogradov@itseez.com>
Mon, 8 Apr 2013 11:18:26 +0000 (15:18 +0400)
modules/gpu/include/opencv2/gpu.hpp
modules/gpu/perf/perf_video.cpp
modules/gpu/src/tvl1flow.cpp
modules/gpu/test/test_optflow.cpp

index 88703fe..84de397 100644 (file)
@@ -1810,6 +1810,8 @@ public:
      */
     int iterations;
 
+    double scaleStep;
+
     bool useInitialFlow;
 
 private:
index dd39aa8..a8e828e 100644 (file)
@@ -434,6 +434,9 @@ PERF_TEST_P(ImagePair, Video_OpticalFlowDual_TVL1,
         cv::Mat flow;
 
         cv::Ptr<cv::DenseOpticalFlow> alg = cv::createOptFlow_DualTVL1();
+        alg->set("medianFiltering", 1);
+        alg->set("innerIterations", 1);
+        alg->set("outerIterations", 300);
 
         TEST_CYCLE() alg->calc(frame0, frame1, flow);
 
index 49dd8ca..df9df9f 100644 (file)
@@ -63,6 +63,7 @@ cv::gpu::OpticalFlowDual_TVL1_GPU::OpticalFlowDual_TVL1_GPU()
     warps          = 5;
     epsilon        = 0.01;
     iterations     = 300;
+    scaleStep      = 0.8;
     useInitialFlow = false;
 }
 
@@ -112,8 +113,8 @@ void cv::gpu::OpticalFlowDual_TVL1_GPU::operator ()(const GpuMat& I0, const GpuM
     // create the scales
     for (int s = 1; s < nscales; ++s)
     {
-        gpu::pyrDown(I0s[s - 1], I0s[s]);
-        gpu::pyrDown(I1s[s - 1], I1s[s]);
+        gpu::resize(I0s[s-1], I0s[s], Size(), scaleStep, scaleStep);
+        gpu::resize(I1s[s-1], I1s[s], Size(), scaleStep, scaleStep);
 
         if (I0s[s].cols < 16 || I0s[s].rows < 16)
         {
@@ -123,11 +124,11 @@ void cv::gpu::OpticalFlowDual_TVL1_GPU::operator ()(const GpuMat& I0, const GpuM
 
         if (useInitialFlow)
         {
-            gpu::pyrDown(u1s[s - 1], u1s[s]);
-            gpu::pyrDown(u2s[s - 1], u2s[s]);
+            gpu::resize(u1s[s-1], u1s[s], Size(), scaleStep, scaleStep);
+            gpu::resize(u2s[s-1], u2s[s], Size(), scaleStep, scaleStep);
 
-            gpu::multiply(u1s[s], Scalar::all(0.5), u1s[s]);
-            gpu::multiply(u2s[s], Scalar::all(0.5), u2s[s]);
+            gpu::multiply(u1s[s], Scalar::all(scaleStep), u1s[s]);
+            gpu::multiply(u2s[s], Scalar::all(scaleStep), u2s[s]);
         }
         else
         {
@@ -159,8 +160,8 @@ void cv::gpu::OpticalFlowDual_TVL1_GPU::operator ()(const GpuMat& I0, const GpuM
         gpu::resize(u2s[s], u2s[s - 1], I0s[s - 1].size());
 
         // scale the optical flow with the appropriate zoom factor
-        gpu::multiply(u1s[s - 1], Scalar::all(2), u1s[s - 1]);
-        gpu::multiply(u2s[s - 1], Scalar::all(2), u2s[s - 1]);
+        gpu::multiply(u1s[s - 1], Scalar::all(1/scaleStep), u1s[s - 1]);
+        gpu::multiply(u2s[s - 1], Scalar::all(1/scaleStep), u2s[s - 1]);
     }
 }
 
index 595e46c..ca4c462 100644 (file)
@@ -435,13 +435,16 @@ GPU_TEST_P(OpticalFlowDual_TVL1, Accuracy)
     d_alg(loadMat(frame0, useRoi), loadMat(frame1, useRoi), d_flowx, d_flowy);
 
     cv::Ptr<cv::DenseOpticalFlow> alg = cv::createOptFlow_DualTVL1();
+    alg->set("medianFiltering", 1);
+    alg->set("innerIterations", 1);
+    alg->set("outerIterations", d_alg.iterations);
     cv::Mat flow;
     alg->calc(frame0, frame1, flow);
     cv::Mat gold[2];
     cv::split(flow, gold);
 
-    EXPECT_MAT_SIMILAR(gold[0], d_flowx, 3e-3);
-    EXPECT_MAT_SIMILAR(gold[1], d_flowy, 3e-3);
+    EXPECT_MAT_SIMILAR(gold[0], d_flowx, 4e-3);
+    EXPECT_MAT_SIMILAR(gold[1], d_flowy, 4e-3);
 }
 
 INSTANTIATE_TEST_CASE_P(GPU_Video, OpticalFlowDual_TVL1, testing::Combine(