diff --git a/apps/ar_cubes/Makefile b/apps/ar_cubes/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..cb9be454905e90580b2b824041ade7de54b42078
--- /dev/null
+++ b/apps/ar_cubes/Makefile
@@ -0,0 +1,20 @@
+include ../../../ar_sandbox_lib/dep.mk
+
+API_PATH=../../../ar_sandbox_lib
+CFLAGS=-std=c++11 -Wall -Wextra -g
+CCP=g++
+DBG_GPROF=-pg
+
+all: ar_cubes
+
+ar_cubes: ar_cubes.o
+	$(CCP) $^ -o $@ -L$(API_PATH)/build -lsandbox $(DEP_SANDBOX)
+
+%.o: %.cpp
+	$(CCP) $(CFLAGS) -I$(API_PATH)/inc -c $< -o $@ 
+
+run:
+	./ar_cubes
+
+clean:
+	rm -f *.o ar_cubes
diff --git a/apps/ar_cubes/ar_cubes b/apps/ar_cubes/ar_cubes
new file mode 100755
index 0000000000000000000000000000000000000000..0de4a51f93a0f702946c8def7a0e6dc3066e84d8
Binary files /dev/null and b/apps/ar_cubes/ar_cubes differ
diff --git a/apps/ar_cubes/ar_cubes.cpp b/apps/ar_cubes/ar_cubes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..925a058ecc83763f1235251d7a8925d5e225f1c7
--- /dev/null
+++ b/apps/ar_cubes/ar_cubes.cpp
@@ -0,0 +1,98 @@
+
+#include "ar_cubes.h"
+
+int main(){
+
+    Sandbox sandbox;
+    char *sandbox_conf_file = (char*)"../../sandbox_conf.yaml";
+  
+    if(sandbox.loadConfigFrom(sandbox_conf_file)){
+        std::cout << "Failed to load the configuration" << std::endl;
+        return 1;
+    }
+    
+    if(sandbox.init()){
+        std::cout << "Failed to initilize sandbox" << std::endl;
+        return 1;
+    }
+
+    arCubes(sandbox);
+}
+
+void arCubes(Sandbox &sandbox){
+
+    char wn[] = "Cubes";
+    cv::namedWindow(wn, CV_WINDOW_NORMAL);
+    cv::setWindowProperty(wn, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
+
+    cv::Mat gray;
+
+    
+    cv::Mat blue;
+    sandbox.captureFrame();
+    cv::Mat src = sandbox.getColorFrame();
+    cv::Mat dst = cv::Mat::zeros(src.rows, src.cols,  CV_8UC3);
+    cv::Mat z = cv::Mat::zeros(src.rows, src.cols, CV_8UC1);
+    
+    std::vector<std::vector<cv::Point>> contours;
+    std::vector<cv::Mat1b> channels;
+
+
+    do{
+        sandbox.captureFrame();
+        src = sandbox.getColorFrame();
+        dst = cv::Mat::zeros(src.rows, src.cols, CV_8UC3);
+        contours.clear();
+        channels.clear();
+
+        cv::extractChannel(src, blue, 2);
+        cv::threshold(blue, blue, 240, 255, cv::THRESH_TOZERO);
+        
+        channels.push_back(z);
+        channels.push_back(z);
+        channels.push_back(blue);
+
+        cv::merge(channels, dst);
+
+        //cv::cvtColor(src, gray, CV_RGB2GRAY, 0);
+        //cv::threshold(gray, gray, 127,255,0);
+        cv::findContours( blue, contours,  cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
+        //cv::cvtColor(red, dst, CV_GRAY2RGB, 0);
+        std::cout << "total " << contours.size() << std::endl;
+        for (int i = 0; i < static_cast<int>(contours.size()); ++i) {
+            //std::vector<cv::Point> approx = contours.at(i);
+            std::vector<cv::Point> approx;
+            double epsilon = 0.1*cv::arcLength(contours.at(i),true);
+            cv::approxPolyDP(contours.at(i), approx, epsilon, true);
+
+            std::cout << "count " << approx.size() << std::endl;
+            cv::drawContours(dst, (std::vector<std::vector<cv::Point>>){approx}, 0, cv::Scalar(0,255,0));
+        }
+        cv::cvtColor(dst, dst, CV_RGB2BGR);
+        cv::imshow(wn, dst);
+
+    } while (cv::waitKey(10) != 27);
+
+    
+    cv::destroyAllWindows();
+
+    // https://docs.opencv.org/trunk/dd/d49/tutorial_py_contour_features.html
+
+    /*
+    for cnt in contours:
+            approx = cv2.approxPolyDP(cnt, 0.01*cv2.arcLength(cnt, True), True)
+            cv2.drawContours(img, [approx], 0, (0), 5)
+            x = approx.ravel()[0]
+            y = approx.ravel()[1]
+            if len(approx) == 3:
+                cv2.putText(img, "Triangle", (x, y), font, 1, (0))
+            elif len(approx) == 4:
+                cv2.putText(img, "Rectangle", (x, y), font, 1, (0))
+            elif len(approx) == 5:
+                cv2.putText(img, "Pentagon", (x, y), font, 1, (0))
+            elif 6 < len(approx) < 15:
+                cv2.putText(img, "Ellipse", (x, y), font, 1, (0))
+            else:
+                cv2.putText(img, "Circle", (x, y), font, 1, (0))
+    */
+}
diff --git a/apps/ar_cubes/ar_cubes.h b/apps/ar_cubes/ar_cubes.h
new file mode 100644
index 0000000000000000000000000000000000000000..ca0276bca68ee77d74ddfe611e4f05db985e002e
--- /dev/null
+++ b/apps/ar_cubes/ar_cubes.h
@@ -0,0 +1,12 @@
+#ifndef APP_AR_CUBES_H
+#define APP_AR_CUBES_H
+
+#include <sandbox.h>
+#include <opencv2/opencv.hpp>
+
+#define ESCAPE_CHAR 27
+
+
+void arCubes(Sandbox &sandbox);
+
+#endif
diff --git a/apps/ar_cubes/ar_cubes.o b/apps/ar_cubes/ar_cubes.o
new file mode 100644
index 0000000000000000000000000000000000000000..1e14d5913aa969050610a4a1546741a86dad88ef
Binary files /dev/null and b/apps/ar_cubes/ar_cubes.o differ
diff --git a/apps/display_levels/display_levels.cpp b/apps/display_levels/display_levels.cpp
index dc3ed3c1156342fb578927fd2cf41ae6a267d7a4..cd02a4d868b4cddda481a62f6ffa85daeb100e2b 100644
--- a/apps/display_levels/display_levels.cpp
+++ b/apps/display_levels/display_levels.cpp
@@ -25,20 +25,17 @@ int main(){
         return 1;
     }
 
-    displayLevels(sandbox);
+    displayLevels( sandbox, sandbox.getProjection()->getDistanceTopSandbox(), 0.17f );
 }
 
 
 /*
 *   Show levels of the sandbox in color
+*   top => distance from camera to the top of the sandbox
 */
-void displayLevels(Sandbox &sandbox){
-
-    float sandboxHeight = 0.17f;
-    // top => distance from camera to the top of the sandbox
-    float top = sandbox.getProjection()->getDistanceTopSandbox();
+void displayLevels(Sandbox &sandbox, float top, float height){
         
-    // Needed because the values retrives from depth frames can change a bit although nothing has changed physically
+    // Needed because the values retrive from depth frames can change a bit although nothing has changed physically
     const float DEPTH_MARGIN_ERROR = 0.01f;
 
     char windowName[] = "Sandbox";
@@ -46,28 +43,37 @@ void displayLevels(Sandbox &sandbox){
     cv::setWindowProperty(windowName, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
     
     sandbox.captureFrame();
-    static cv::Mat depth_cache = sandbox.getDepthFrame();
-
+    cv::Mat depth_cache = sandbox.getDepthFrame(); 
     cv::Mat new_depth = cv::Mat(depth_cache.size(), CV_32F);
     cv::Mat colorized = cv::Mat(depth_cache.size(), CV_8UC3);
-    cv::Mat res = cv::Mat(depth_cache.size(), CV_8UC3);
+    cv::Mat_<cv::Vec3b> res = cv::Mat(depth_cache.size(), CV_8UC3);
+    
+    //cv::Mat_<cv::Vec3b> img = cv::imread("index.png");
+
 /*
     std::chrono::milliseconds start_ms = std::chrono::duration_cast< std::chrono::milliseconds >( std::chrono::system_clock::now().time_since_epoch() );
     int cpt_frame = 0;
-*/ 
+*/
     do{
     //for(int i=0; i<200; i++){
         sandbox.captureFrame();
-        sandbox.getDepthFrame().copyTo(new_depth);
+        new_depth = sandbox.getDepthFrame();
         new_depth.copyTo( depth_cache, (cv::abs(depth_cache-new_depth) > DEPTH_MARGIN_ERROR) );
 
-        colorizeDepth(depth_cache, top, sandboxHeight).copyTo(colorized);
+        colorized = colorizeDepth(depth_cache, top, height);
         cv::cvtColor(colorized, res, CV_RGB2BGR);
-        sandbox.adjustProjection(res).copyTo(res);
 
+        //std::chrono::milliseconds start_adj_ms = std::chrono::duration_cast< std::chrono::milliseconds >( std::chrono::system_clock::now().time_since_epoch() );
+        //cv::Mat_<cv::Vec3b> result = sandbox.adjustProjection(res);
+        
+        //std::chrono::milliseconds now_adj_ms = std::chrono::duration_cast< std::chrono::milliseconds >( std::chrono::system_clock::now().time_since_epoch() );
+        //std::cout << "Adjust : " << (now_adj_ms - start_adj_ms).count() << std::endl;
+        //result.copyTo(res);
+
+        res = sandbox.adjustProjection(res);
         cv::imshow(windowName, res);
 
-/*        
+        /*
         cpt_frame++;
         std::chrono::milliseconds now_ms = std::chrono::duration_cast< std::chrono::milliseconds >( std::chrono::system_clock::now().time_since_epoch() );
         if(now_ms-start_ms > std::chrono::milliseconds(1000)){
@@ -75,7 +81,7 @@ void displayLevels(Sandbox &sandbox){
             cpt_frame = 0;
             start_ms = std::chrono::duration_cast< std::chrono::milliseconds >( std::chrono::system_clock::now().time_since_epoch() );
         }
-*/        
+        */
 
     //}
     } while (cv::waitKey(10) != ESCAPE_CHAR);
@@ -100,10 +106,7 @@ cv::Mat colorizeDepth(cv::Mat depth, float sandboxTop, float sandboxHeight){
     for(int j=0; j<depth.rows; j++){
         for(int i=0; i<depth.cols; i++){
 
-            cv::Scalar color = floatToColor(normalizedDepth.at<float>(j,i), 0.0f, sandboxHeight);
-            res.at<cv::Vec3b>(j,i)[0] = color[0];
-            res.at<cv::Vec3b>(j,i)[1] = color[1];
-            res.at<cv::Vec3b>(j,i)[2] = color[2];
+            res.at<cv::Vec3b>(j,i) = floatToColor(normalizedDepth.at<float>(j,i), 0.0f, sandboxHeight);
         }
     }
 
@@ -121,7 +124,7 @@ cv::Mat colorizeDepth(cv::Mat depth, float sandboxTop, float sandboxHeight){
 *   Color order :
 *       blue > cyan > green > yellow > red
 */
-cv::Scalar floatToColor(float value, float min, float max){
+cv::Vec3b floatToColor(float value, float min, float max){
 
     const uint CHANNEL_MAX = 255;
 
@@ -157,5 +160,5 @@ cv::Scalar floatToColor(float value, float min, float max){
     uint8_t g = static_cast<uint8_t>( initColors[index][1] + coeffColors[index][1] * (color % (CHANNEL_MAX+1)) );
     uint8_t b = static_cast<uint8_t>( initColors[index][2] + coeffColors[index][2] * (color % (CHANNEL_MAX+1)) );
 
-    return cv::Scalar(r,g,b);
+    return cv::Vec3b(r,g,b);
 }
diff --git a/apps/display_levels/display_levels.h b/apps/display_levels/display_levels.h
index d1d57f618829236670796d6449540564e52c6a9d..1ef26d5228da1436a0ca3b45d9602653a28c6e1e 100644
--- a/apps/display_levels/display_levels.h
+++ b/apps/display_levels/display_levels.h
@@ -7,9 +7,9 @@
 #define ESCAPE_CHAR 27
 
 
-void displayLevels(Sandbox &sandbox);
+void displayLevels(Sandbox &sandbox, float top, float height);
 
-cv::Scalar floatToColor(float value, float min, float max);
+cv::Vec3b floatToColor(float value, float min, float max);
 cv::Mat colorizeDepth(cv::Mat depth, float sandboxTop, float sandboxHeight);
 
 #endif
diff --git a/apps/display_levels/index.jpeg b/apps/display_levels/index.jpeg
deleted file mode 100644
index 8b2033b95fb39f91dc2560c86a0a628facc9d2de..0000000000000000000000000000000000000000
Binary files a/apps/display_levels/index.jpeg and /dev/null differ
diff --git a/beamer_config.sh b/beamer_config.sh
index b47b842a5a7d44abd5e913303ec4aa7c907ca15f..f1eaabfb40b9937a422e751cbd8e4f2c61830f86 100755
--- a/beamer_config.sh
+++ b/beamer_config.sh
@@ -1,7 +1,8 @@
-SCREEN=eDP-1
+SCREEN=DVI-D-0
 SCN_RES=1920x1080
-BEAMER=HDMI-1
+BEAMER=HDMI-0
 BM_RES=1400x1050
+#1024x768
 
 
 xrandr --output $SCREEN --rate 60 --mode $SCN_RES --fb $SCN_RES --panning $SCN_RES* \
diff --git a/sandbox_conf.yaml b/sandbox_conf.yaml
index 84bb9d952455aab2ef3d91d2705e82209cf4e104..d9273d5433f1c18fe0718654e506556f86121713 100644
--- a/sandbox_conf.yaml
+++ b/sandbox_conf.yaml
@@ -1,26 +1,26 @@
 AdjustingMatrix:
   width: 3
   height: 2
-  matrix: [0.9998824, -0.0153356194, 3.71817994, 0.0153356194, 0.9998824, -4.87917471]
+  matrix: [0.999961376, -0.00879086927, 1.49442828, 0.00879086927, 0.999961376, -1.9889971]
 DistanceTopSandbox:
-  distance: 1.10
+  distance: 0.985000074
 CroppingMask:
-  x: 176
-  y: 121
-  width: 320
-  height: 240
+  x: 150
+  y: 93
+  width: 455
+  height: 338
 BeamerResolution:
   width: 1400
   height: 1050
 BeamerPosition:
-  x: 0.008
-  y: 0.25
-  z: 0
+  x: 0.05
+  y: 0.2
+  z: -0.3
 FrameProcessProfil:
-  contrast: 2.2999999999999936
-  brightness: -75
+  contrast: 1.8100000000000001
+  brightness: -163
   minDistance: 60
   cannyEdgeThreshold: 137
   houghAccThreshold: 30
   minRadius: 4
-  maxRadius: 9
+  maxRadius: 11
diff --git a/sandbox_conf_hd.yaml b/sandbox_conf_hd.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7b62676f75ab762c90a714258d1173830a8cc989
--- /dev/null
+++ b/sandbox_conf_hd.yaml
@@ -0,0 +1,26 @@
+AdjustingMatrix:
+  width: 3
+  height: 2
+  matrix: [0.9998824, -0.0153356194, 3.71817994, 0.0153356194, 0.9998824, -4.87917471]
+DistanceTopSandbox:
+  distance: 0.985000074
+CroppingMask:
+  x: 278
+  y: 29
+  width: 834
+  height: 632
+BeamerResolution:
+  width: 1024
+  height: 768
+BeamerPosition:
+  x: 0.0498280413
+  y: 0.143917277
+  z: -0.190710485
+FrameProcessProfil:
+  contrast: 1.8100000000000001
+  brightness: -163
+  minDistance: 60
+  cannyEdgeThreshold: 137
+  houghAccThreshold: 30
+  minRadius: 4
+  maxRadius: 11
diff --git a/sandbox_conf_sd.yaml b/sandbox_conf_sd.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4c8a92cec080e9813548e3ae9d6cedfa0dbcb54a
--- /dev/null
+++ b/sandbox_conf_sd.yaml
@@ -0,0 +1,26 @@
+AdjustingMatrix:
+  width: 3
+  height: 2
+  matrix: [0.9998824, -0.0153356194, 3.71817994, 0.0153356194, 0.9998824, -4.87917471]
+DistanceTopSandbox:
+  distance: 0.985000074
+CroppingMask:
+  x: 176
+  y: 121
+  width: 320
+  height: 240
+BeamerResolution:
+  width: 1024
+  height: 768
+BeamerPosition:
+  x: 0.0498280413
+  y: 0.143917277
+  z: -0.190710485
+FrameProcessProfil:
+  contrast: 1.8100000000000001
+  brightness: -163
+  minDistance: 60
+  cannyEdgeThreshold: 137
+  houghAccThreshold: 30
+  minRadius: 4
+  maxRadius: 11