diff --git a/OFCV/header/opticalflow.hpp b/OFCV/header/opticalflow.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5b3bc085414a988552bd02d039df76f7c62d13c7
--- /dev/null
+++ b/OFCV/header/opticalflow.hpp
@@ -0,0 +1,87 @@
+#pragma once
+#include <iostream>
+#include <utility>
+#include <vector>
+#include <opencv2/opencv.hpp>
+
+using namespace std;
+using namespace cv;
+
+namespace OF {
+  enum Sparse {};
+  enum Full {};
+}
+
+template<typename T>
+class OpticalFlow;
+
+template<>
+class OpticalFlow<OF::Sparse> {
+
+private:
+  Mat image_t1;
+  Mat image_t2;
+
+public:
+  OpticalFlow(const Mat &t1,const Mat &t2)
+  {
+    image_t1 = t1.clone();
+    image_t2 = t2.clone();
+  }
+
+  void calc()
+  {
+
+  }
+
+};
+
+template<>
+class OpticalFlow<OF::Full> {
+
+private:
+  Mat image_t1;
+  Mat image_t2;
+
+  Mat image_t1_GRAY;
+  Mat image_t2_GRAY;
+
+  Mat flow;
+
+  void drawOptFlowMap (const Mat& flow, Mat& cflowmap, int step, const Scalar& color) {
+    for(int y = 0; y < cflowmap.rows; y += step)
+        for(int x = 0; x < cflowmap.cols; x += step)
+        {
+            const Point2f& fxy = flow.at< Point2f>(y, x);
+            line(cflowmap, Point(x,y), Point(cvRound(x+fxy.x), cvRound(y+fxy.y)),
+                 color);
+            circle(cflowmap, Point(cvRound(x+fxy.x), cvRound(y+fxy.y)), 1, color, -1);
+        }
+    }
+
+public:
+  OpticalFlow(const Mat &t1,const Mat &t2)
+  {
+    image_t1 = t1.clone();
+    image_t2 = t2.clone();
+
+    cvtColor(image_t1,image_t1_GRAY,COLOR_BGR2GRAY);
+    cvtColor(image_t2,image_t2_GRAY,COLOR_BGR2GRAY);
+  }
+
+  void calc()
+  {
+    Mat &t1=image_t1_GRAY;
+    Mat &t2=image_t2_GRAY;
+    //calculate dense flow
+    calcOpticalFlowFarneback(t1,t2, flow, 0.5, 3, 15, 3, 5, 1.2, 0);
+  }
+
+  void draw()
+  {
+    Mat cflow = image_t1.clone();
+    //draw ever tenth row and col in green
+    drawOptFlowMap(flow, cflow, 10, CV_RGB(0, 255, 0));
+    imshow("OpticalFlowFarneback", cflow);
+  }
+};
diff --git a/OFCV/images/example_car/car_t0.png b/OFCV/images/example_car/car_t0.png
new file mode 100644
index 0000000000000000000000000000000000000000..dae8bdfb7187bf6eee34e874dacc0b45cbb70ca1
Binary files /dev/null and b/OFCV/images/example_car/car_t0.png differ
diff --git a/OFCV/images/example_car/car_t1.png b/OFCV/images/example_car/car_t1.png
new file mode 100644
index 0000000000000000000000000000000000000000..bff6e9115136ecc1a975bb82ecda69ee477bae3e
Binary files /dev/null and b/OFCV/images/example_car/car_t1.png differ
diff --git a/OFCV/source/main.cpp b/OFCV/source/main.cpp
index e55f9b5a1f132bed3c5d5588b56f075ad1157bed..9654d513be6ba160ebfa14cb8e48ffd743a1ed84 100644
--- a/OFCV/source/main.cpp
+++ b/OFCV/source/main.cpp
@@ -1,18 +1,33 @@
 #include <iostream>
+#include <chrono>
+#include <thread>
 #include <opencv2/opencv.hpp>
 
+#include "opticalflow.hpp"
+
 using namespace std;
 
 int main(int argc, char **argv)
 {
-  cout << "Hello World" << endl;
-
-  cv::Mat image;
-  image = cv::imread( argv[1], 1 );
+  cv::Mat image_t1, image_t2;
+  image_t1 = cv::imread( argv[1], 1 );
+  image_t2 = cv::imread( argv[2], 1 );
 
-  cv::namedWindow("Display Image", cv::WINDOW_AUTOSIZE );
-  cv::imshow("Display Image", image);
+  Mat &t0 = image_t1;
+  Mat &t1 = image_t2;
+  /*while(1)
+  {
+    OpticalFlow<OF::Full> test(image_t1,image_t2);
+    test.calc();
+    test.draw();
+    cv::waitKey(10);
+    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+    std::swap(t0,t1);
+  }*/
 
+  OpticalFlow<OF::Full> test(image_t1,image_t2);
+  test.calc();
+  test.draw();
   cv::waitKey(0);
 
   return 0;