diff --git a/cv-node/config/config.json b/cv-node/config/config.json
index 9a768db7d2359bb35a592c0704a3d7cf54dcae6c..257a38777bbc8e3e5a5e528cb37497712316fa04 100644
--- a/cv-node/config/config.json
+++ b/cv-node/config/config.json
@@ -1,7 +1,8 @@
 {
 	"source": {
 		"flip": false,
-		"nostereo": false
+		"nostereo": false,
+		"scale": 1.0
 	},
 	"calibrate": false,
 	"calibration": {
@@ -24,7 +25,7 @@
 		"flip_vertical": false
 	},
 	"camera": {
-		"name": "Pansonic Lumix DMC-FZ300",
+		"name": "Panasonic Lumix DMC-FZ300",
 		"focal_length": 25,
 		"sensor_width": 6.17,
 		"base_line": 0.1
diff --git a/cv-node/include/ftl/calibrate.hpp b/cv-node/include/ftl/calibrate.hpp
index 1982b4dc192816d6f2e4ac8d8f5df2eabd371886..2539864f0b2a6a87c6a9601b3b1d6585be3d14fc 100644
--- a/cv-node/include/ftl/calibrate.hpp
+++ b/cv-node/include/ftl/calibrate.hpp
@@ -75,6 +75,8 @@ class Calibrate {
 	
 	bool isCalibrated();
 	
+	const cv::Mat &getQ() const { return Q_; }
+	
 	private:
 	bool _recalibrate(std::vector<std::vector<cv::Point2f>> *imagePoints,
 		cv::Mat *cameraMatrix, cv::Mat *distCoeffs, cv::Size *imageSize);
@@ -87,6 +89,7 @@ class Calibrate {
 	bool calibrated_;
 	std::vector<cv::Mat> map1_;
 	std::vector<cv::Mat> map2_;
+	cv::Mat Q_;
 };
 };
 
diff --git a/cv-node/include/ftl/local.hpp b/cv-node/include/ftl/local.hpp
index 6209eb24b07bb3d61490e2e061757d87822e5603..f4c98f357f8da25c2cfac8d9058bf99362db2ab3 100644
--- a/cv-node/include/ftl/local.hpp
+++ b/cv-node/include/ftl/local.hpp
@@ -32,6 +32,7 @@ class LocalSource {
 	//float fps_;
 	bool flip_;
 	bool nostereo_;
+	float downsize_;
 	cv::VideoCapture *camera_a_;
 	cv::VideoCapture *camera_b_;
 };
diff --git a/cv-node/src/algorithms/rtcensus.cpp b/cv-node/src/algorithms/rtcensus.cpp
index 86b7768588caef401372a0203a722361562188ab..23939ed0021d5f4009da4db3be805c39e7be11dd 100644
--- a/cv-node/src/algorithms/rtcensus.cpp
+++ b/cv-node/src/algorithms/rtcensus.cpp
@@ -134,7 +134,7 @@ static cv::Mat d_sub(vector<uint16_t> &dsi, size_t w, size_t h, size_t ds) {
 static cv::Mat consistency(cv::Mat &d_sub_r, cv::Mat &d_sub_l) {
 	size_t w = d_sub_r.cols;
 	size_t h = d_sub_r.rows;
-	Mat result = Mat::zeros(Size(w,h), CV_64FC1);
+	Mat result = Mat::zeros(Size(w,h), CV_32FC1);
 	
 	for (size_t v=0; v<h; v++) {
 	for (size_t u=0; u<w; u++) {
@@ -143,8 +143,8 @@ static cv::Mat consistency(cv::Mat &d_sub_r, cv::Mat &d_sub_l) {
 		
 		auto b = d_sub_r.at<double>(v,u-a);
 		
-		if (std::abs(a-b) <= 1.0) result.at<double>(v,u) = std::abs((a+b)/2);
-		else result.at<double>(v,u) = 0.0;
+		if (std::abs(a-b) <= 1.0) result.at<float>(v,u) = std::abs((a+b)/2);
+		else result.at<float>(v,u) = 0.0f;
 	}
 	}
 	
diff --git a/cv-node/src/calibrate.cpp b/cv-node/src/calibrate.cpp
index ef2e6fcb7dcf78220a54c80c1aac257de51b42fc..ca5bea249353b1028b94b8732128c70bfe876534 100644
--- a/cv-node/src/calibrate.cpp
+++ b/cv-node/src/calibrate.cpp
@@ -203,7 +203,7 @@ bool Calibrate::_loadCalibration() {
 	float scale = 1.0f;
 
     Rect roi1, roi2;
-    Mat Q;
+    
     // reading intrinsic parameters
     FileStorage fs(FTL_CONFIG_ROOT "/intrinsics.yml", FileStorage::READ);
     if(!fs.isOpened())
@@ -231,8 +231,13 @@ bool Calibrate::_loadCalibration() {
     Mat R, T, R1, P1, R2, P2;
     fs["R"] >> R;
     fs["T"] >> T;
+    fs["R1"] >> R1;
+    fs["R2"] >> R2;
+    fs["P1"] >> P1;
+    fs["P2"] >> P2;
+    fs["Q"] >> Q_;
 
-    stereoRectify( M1, D1, M2, D2, img_size, R, T, R1, R2, P1, P2, Q, CALIB_ZERO_DISPARITY, -1, img_size, &roi1, &roi2 );
+    stereoRectify( M1, D1, M2, D2, img_size, R, T, R1, R2, P1, P2, Q_, CALIB_ZERO_DISPARITY, -1, img_size, &roi1, &roi2 );
 
     Mat map11, map12, map21, map22;
     initUndistortRectifyMap(M1, D1, R1, P1, img_size, CV_16SC2, map1_[0], map2_[0]);
@@ -293,18 +298,18 @@ bool Calibrate::recalibrate() {
 		else
 		    LOG(ERROR) << "Error: can not save the intrinsic parameters";
 
-		Mat R1, R2, P1, P2, Q;
+		Mat R1, R2, P1, P2;
 		Rect validRoi[2];
 
 		stereoRectify(cameraMatrix[0], distCoeffs[0],
 		              cameraMatrix[1], distCoeffs[1],
-		              imageSize[0], R, T, R1, R2, P1, P2, Q,
+		              imageSize[0], R, T, R1, R2, P1, P2, Q_,
 		              CALIB_ZERO_DISPARITY, 1, imageSize[0], &validRoi[0], &validRoi[1]);
 
 		fs.open(FTL_CONFIG_ROOT "/extrinsics.yml", FileStorage::WRITE);
 		if( fs.isOpened() )
 		{
-		    fs << "R" << R << "T" << T << "R1" << R1 << "R2" << R2 << "P1" << P1 << "P2" << P2 << "Q" << Q;
+		    fs << "R" << R << "T" << T << "R1" << R1 << "R2" << R2 << "P1" << P1 << "P2" << P2 << "Q" << Q_;
 		    fs.release();
 		}
 		else
diff --git a/cv-node/src/local.cpp b/cv-node/src/local.cpp
index 13eddcf32d901677bbfe4a128309886ce481d156..4342d9581fde66909fb9c1105d645d0d037c03d4 100644
--- a/cv-node/src/local.cpp
+++ b/cv-node/src/local.cpp
@@ -14,7 +14,10 @@ using std::string;
 using namespace std::chrono;
 
 LocalSource::LocalSource(nlohmann::json &config)
-		: timestamp_(0.0), flip_(config["flip"]), nostereo_(config["nostereo"]) {
+	:	timestamp_(0.0),
+		flip_(config["flip"]),
+		nostereo_(config["nostereo"]),
+		downsize_(config.value("scale",1.0f)) {
 	// Use cameras
 	camera_a_ = new VideoCapture((flip_) ? 1 : 0);
 	if (!nostereo_) camera_b_ = new VideoCapture((flip_) ? 0 : 1);
@@ -40,7 +43,10 @@ LocalSource::LocalSource(nlohmann::json &config)
 }
 
 LocalSource::LocalSource(const string &vid, nlohmann::json &config)
-		: timestamp_(0.0), flip_(config["flip"]), nostereo_(config["nostereo"]) {
+	:	timestamp_(0.0),
+		flip_(config["flip"]),
+		nostereo_(config["nostereo"]),
+		downsize_(config.value("scale",1.0f)) {
 	if (vid == "") {
 		LOG(FATAL) << "No video file specified";
 		camera_a_ = nullptr;
@@ -186,6 +192,11 @@ bool LocalSource::get(cv::Mat &l, cv::Mat &r) {
 		}
 	}
 	
+	if (downsize_ != 1.0f) {
+		cv::resize(l, l, cv::Size(l.cols * downsize_,l.rows * downsize_), 0, 0, cv::INTER_LINEAR);
+		cv::resize(r, r, cv::Size(r.cols * downsize_,r.rows * downsize_), 0, 0, cv::INTER_LINEAR);
+	}
+	
 	return true;
 }
 
diff --git a/cv-node/src/main.cpp b/cv-node/src/main.cpp
index c4c804dc391bfff7cb8daf1e388343a3128051ca..afa9be6571abb2da57fbf75cd750b5973ef4ad60 100644
--- a/cv-node/src/main.cpp
+++ b/cv-node/src/main.cpp
@@ -121,9 +121,14 @@ int main(int argc, char **argv) {
     // Choose and configure disparity algorithm
     auto disparity = Disparity::create(config["disparity"]);
 	
-	Mat l, r, filtered_disp;
+	Mat l, r, disparity32F, lbw, rbw;
 	
-	while (true) {
+	cv::viz::Viz3d myWindow("FTL");
+	
+	float fact = (float)(config["camera"]["focal_length"]) / (float)(config["camera"]["sensor_width"]);
+	Mat rot_vec = Mat::zeros(1,3,CV_32F);
+	
+	while (!myWindow.wasStopped()) {
 		// Read calibrated images.
 		calibrate.undistort(l,r);
 		
@@ -135,29 +140,57 @@ int main(int argc, char **argv) {
 		sync->get(LEFT,l);
 		sync->get(RIGHT,r);
 		
-		// Downscale
-		//cv::resize(l, l, cv::Size(l.cols * 0.75,l.rows * 0.75), 0, 0, INTER_LINEAR);
-		//cv::resize(r, r, cv::Size(r.cols * 0.75,r.rows * 0.75), 0, 0, INTER_LINEAR);
-		
 		// Black and white
-        cvtColor(l,  l,  COLOR_BGR2GRAY);
-        cvtColor(r, r, COLOR_BGR2GRAY);
+        cvtColor(l,  lbw,  COLOR_BGR2GRAY);
+        cvtColor(r, rbw, COLOR_BGR2GRAY);
         
-        disparity->compute(l,r,filtered_disp);
+        disparity->compute(lbw,rbw,disparity32F);
 		LOG(INFO) << "Disparity complete ";
 		
+		disparity32F.convertTo(disparity32F, CV_32F);
+		
 		// TODO Send RGB+D data somewhere
 		
-		//left_disp = (fact * (double)l.cols * 0.1) / filtered_disp;
+		// Convert disparity to depth
+		disparity32F = (fact * (float)l.cols * 0.1f) / disparity32F;
 
-		normalize(filtered_disp, filtered_disp, 0, 255, NORM_MINMAX, CV_8U);
+		//normalize(filtered_disp, filtered_disp, 0, 255, NORM_MINMAX, CV_8U);
+		
+		//cv::imshow("Disparity",filtered_disp);
+		//Mat i3d;
+		//const Mat &Q = calibrate.getQ();
+		cv::Mat Q_32F;
+		calibrate.getQ().convertTo(Q_32F,CV_32F);
+		cv::Mat_<cv::Vec3f> XYZ(disparity32F.rows,disparity32F.cols);   // Output point cloud
+		reprojectImageTo3D(disparity32F, XYZ, Q_32F, true);
 		
-		cv::imshow("Disparity",filtered_disp);
+		//cv::imshow("Points",XYZ);
+		
+		cv::viz::WCloud cloud_widget = cv::viz::WCloud( XYZ, l );
+    	cloud_widget.setRenderingProperty( cv::viz::POINT_SIZE, 2 );
+    	
+    	/* Rotation using rodrigues */
+        /// Rotate around (1,1,1)
+        rot_vec.at<float>(0,0) = 0.0f;
+        rot_vec.at<float>(0,1) = 0.0f;
+        rot_vec.at<float>(0,2) = CV_PI * 1.0f;
+
+        Mat rot_mat;
+        Rodrigues(rot_vec, rot_mat);
+
+        /// Construct pose
+        Affine3f pose(rot_mat, Vec3f(0, 0, 0));
+
+		//myWindow.showWidget( "coosys", viz::WCoordinateSystem() );
+		myWindow.showWidget( "Depth", cloud_widget );
+		myWindow.setWidgetPose("Depth", pose);
+
+		myWindow.spinOnce( 30, true );
 		
-		if(cv::waitKey(10) == 27){
+		//if(cv::waitKey(10) == 27){
             //exit if ESC is pressed
-            break;
-        }
+        //    break;
+        //}
 	}
 }