# OpenCV Optical Flow: Farneback Algorithm [Source Code]

> Opencv simple C++ tutorial and code to achieve optical flow and farneback optical flow of moving an object in OpenCV video.

- Canonical URL: https://www.funvisiontutorials.com/blog/opencv-optical-flow-farneback-cpp/
- Author: Vladimir Kucera
- Published: 2016-02-25
- Updated: 2026-02-20
- Topics: Object tracking, Modern C++, Installing & building OpenCV
- Videos: https://www.youtube.com/watch?v=Tqf2EzG0djQ

Opencv simple C++ tutorial and code to achieve optical flow and farneback optical flow of moving an object in OpenCV video. Let's check the video example and the achieved result on my blog. Working and well-described code is included.

[Image: optical flow Farneback]

### Optical Flow Farneback parameters remarks

You need 2 images at least to calculate optical flow, the previous image (prevgray) and the current image (img). !! The previous image must be initialized first !! Both images have to be grayscale.

The result is stored in flowUmat which has the same size as inputs but the format is CV\_32FC2

`calcOpticalFlowFarneback``(prevgray, img, flowUmat,` `0.4``,` `1``,` `12``,` `2``,` `8``,` `1.2``,` `0``);`

-   0.4- Image pyramid or simple image scale
-   1 is the number of pyramid layers. 1 means that flow is calculated only from the previous image.
-   12 is the window size. Flow is computed over the window larger value is more robust to the noise.
-   2 mean number of iterations of the algorithm
-   8 is polynomial degree expansion recommended value is 5 - 7
-   1.2 standard deviation used to smooth used derivatives recommended values from 1.1 - 1,5

calcOpticalFlowFarneback(prevgray, img, flowUmat, 0.4, 1, 12, 2, 8, 1.2, 0);

### calcOpticalFlowFarneback Example

My [gopro](http://www.amazon.com/GoPro-CHDHY-401-HERO4-Silver/dp/B00NIYJF6U/ref=as_li_bk_tl/?tag=computevision-20&linkId=37a89c2bd66e20c7bf1820ad73cf0a1f&linkCode=ktl) video is captured at Old Town Square in [Prague](http://www.amazon.com/DK-Eyewitness-Travel-Guide-Prague/dp/146542881X/ref=as_li_bk_tl/?tag=computevision-20&linkId=e968c56d670d5c93f32b9f42a55d466c&linkCode=ktl).

Video: https://www.youtube.com/watch?v=Tqf2EzG0djQ

### Opencv Tutorial C++ code calcOpticalFlowFarneback

```cpp
#include "opencv2\highgui.hpp"
#include "opencv2\imgproc.hpp"
#include "opencv2\objdetect\objdetect.hpp"
#include "opencv2/video/tracking.hpp"
#include <vector>
#include <stdio.h>
#include <Windows.h>
#include <iostream>
using namespace cv;
using namespace std;

int main(int argc, const char** argv)
{
 // add your file name
 VideoCapture cap("yourFile.mp4");
 Mat flow, frame;
 // some faster than mat image container
 UMat  flowUmat, prevgray;
 for (;;)

 {
  bool Is = cap.grab();
  if (Is == false) {
    // if video capture failed
   cout << "Video Capture Fail" << endl;
   break;
  }
  else {
   Mat img;
   Mat original;
   // capture frame from video file
   cap.retrieve(img, CV_CAP_OPENNI_BGR_IMAGE);
   resize(img, img, Size(640, 480));
   // save original for later
   img.copyTo(original);
   // just make current frame gray
   cvtColor(img, img, COLOR_BGR2GRAY);
   // For all optical flow you need a sequence of images.. Or at least 2 of them. Previous
                           //and current frame
   // if there is no current frame
   // go to this part and fill previous frame
   //else {
   // img.copyTo(prevgray);
   //   }
   // if previous frame is not empty.. There is a picture of previous frame. Do some
   //optical flow alg.

   if (prevgray.empty() == false ) {
    // calculate optical flow
    calcOpticalFlowFarneback(prevgray, img, flowUmat, 0.4, 1, 12, 2, 8, 1.2, 0);
    // copy Umat container to standard Mat
    flowUmat.copyTo(flow);
        // By y += 5, x += 5 you can specify the grid
    for (int y = 0; y < original.rows; y += 5) {
     for (int x = 0; x < original.cols; x += 5)  {
              // get the flow from y, x position * 10 for better visibility
              const Point2f flowatxy = flow.at<Point2f>(y, x) * 10;
              // draw line at flow direction
       line(original, Point(x, y), Point(cvRound(x + flowatxy.x), cvRound(y + flowatxy.y)), Scalar(255,0,0));
       // draw initial point
       circle(original, Point(x, y), 1, Scalar(0, 0, 0), -1);
     }
    }
    // draw the results
    namedWindow("prew", WINDOW_AUTOSIZE);
    imshow("prew", original);
    // fill previous image again
    img.copyTo(prevgray);
   }
   else {
    // fill previous image in case prevgray.empty() == true
    img.copyTo(prevgray);
   }
   int key1 = waitKey(20);
 }
 }
}
```
