diff --git a/cv-node/CMakeLists.txt b/cv-node/CMakeLists.txt
index 55a3dc0cc276c4d21dff2c859e5405c08552bcdb..3adda08571a6e7c9a37109106209057f703c29d0 100644
--- a/cv-node/CMakeLists.txt
+++ b/cv-node/CMakeLists.txt
@@ -1,5 +1,6 @@
 cmake_minimum_required (VERSION 3.1.0)
 include (CheckIncludeFile)
+include (CheckIncludeFileCXX)
 include (CheckFunctionExists)
 include(CheckLanguage)
 
@@ -11,23 +12,19 @@ enable_testing()
 set(THREADS_PREFER_PTHREAD_FLAG ON)
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
 
-#find_package( glog REQUIRED )
-if (WIN32)
-include_directories(${glog_DIR})
-endif (WIN32)
+find_package( glog REQUIRED )
+#if (WIN32)
+#include_directories(${glog_DIR})
+#endif (WIN32)
 find_package( OpenCV REQUIRED )
 find_package( Threads REQUIRED )
 find_package( LibSGM )
 #find_package( CUDA )
-#find_package(PkgConfig)
-#pkg_check_modules(GTKMM gtkmm-3.0)
-
-message("Cuda at ${CMAKE_CUDA_COMPILER}")
 
 check_language(CUDA)
 if (CUDA_FOUND)
 enable_language(CUDA)
-set(CMAKE_CUDA_FLAGS "-Xcompiler -Wall")
+set(CMAKE_CUDA_FLAGS "")
 set(CMAKE_CUDA_FLAGS_DEBUG "-g -DDEBUG -D_DEBUG -Wall")
 set(CMAKE_CUDA_FLAGS_RELEASE "")
 add_definitions(-DHAVE_CUDA)
@@ -38,6 +35,11 @@ endif (CUDA_FOUND)
 include_directories(${PROJECT_SOURCE_DIR}/include)
 include_directories(${PROJECT_BINARY_DIR})
 
+# Check for optional opencv components
+set(CMAKE_REQUIRED_INCLUDES "${OpenCV_DIR}/include")
+check_include_file_cxx("opencv2/viz.hpp" HAVE_VIZ)
+check_include_file_cxx("opencv2/cudastereo.hpp" HAVE_OPENCVCUDA)
+
 set(ftl_VERSION_MAJOR "1")
 set(ftl_VERSION_MINOR "0")
 set(ftl_VERSION_PATCH "0")
@@ -51,6 +53,10 @@ if (WIN32)
 	set(FTL_CACHE_ROOT "$ENV{USERPROFILE}/AppData/ftl")
 	set(FTL_DATA_ROOT "$ENV{USERPROFILE}/AppData/ftl")
 	add_definitions(-DWIN32)
+
+	set(CMAKE_CXX_FLAGS "/std:c++17")
+	set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -Wall")
+	set(CMAKE_CXX_FLAGS_RELEASE "/O2")
 endif (WIN32)
 
 if (UNIX)
@@ -59,15 +65,19 @@ if (UNIX)
 	message(STATUS "Config root is ${FTL_CONFIG_ROOT}")
 	set(FTL_CACHE_ROOT "$ENV{HOME}/.cache/ftl")
 	set(FTL_DATA_ROOT "$ENV{HOME}/.local/share/ftl")
+
+	set(CMAKE_CXX_FLAGS "-std=c++17")
+	set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -pg -Wall")
+	set(CMAKE_CXX_FLAGS_RELEASE "-O3 -msse3 -mfpmath=sse")
 endif (UNIX)
 
-add_definitions("-DFTL_CONFIG_ROOT=${FTL_CONFIG_ROOT}")
-add_definitions("-DFTL_CACHE_ROOT=${FTL_CACHE_ROOT}")
-add_definitions("-DFTL_DATA_ROOT=${FTL_DATA_ROOT}")
+#add_definitions("-DFTL_CONFIG_ROOT=${FTL_CONFIG_ROOT}")
+#add_definitions("-DFTL_CACHE_ROOT=${FTL_CACHE_ROOT}")
+#add_definitions("-DFTL_DATA_ROOT=${FTL_DATA_ROOT}")
 
-set(CMAKE_CXX_FLAGS "-std=c++17 -Wall")
-set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -pg -Wall")
-set(CMAKE_CXX_FLAGS_RELEASE "-O3 -msse3 -mfpmath=sse")
+configure_file(${CMAKE_SOURCE_DIR}/include/ftl/config.h.in
+               ${CMAKE_SOURCE_DIR}/include/ftl/config.h
+)
 
 SET(CMAKE_USE_RELATIVE_PATHS ON)
 
@@ -113,6 +123,6 @@ set_property(TARGET cv-node PROPERTY CUDA_SEPARABLE_COMPILATION ON)
 endif (CUDA_FOUND)
 
 target_include_directories(cv-node PUBLIC ${PROJECT_SOURCE_DIR}/include)
-target_link_libraries(cv-node Threads::Threads ${OpenCV_LIBS} ${LIBSGM_LIBRARIES} ${CUDA_LIBRARIES} glog)
+target_link_libraries(cv-node Threads::Threads ${OpenCV_LIBS} ${LIBSGM_LIBRARIES} ${CUDA_LIBRARIES} ${GLOG_LIBRARIES})
 
 
diff --git a/cv-node/cmake/FindGLOG.cmake b/cv-node/cmake/FindGLOG.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..3cf3a4a061a09c5e56e7ed3a2913459275f09426
--- /dev/null
+++ b/cv-node/cmake/FindGLOG.cmake
@@ -0,0 +1,39 @@
+###############################################################################
+# Find glog
+#
+
+if(WIN32)
+find_path(glog_DIR glog PATHS "C:/Program Files" "C:/Program Files (x86)")
+set(glog_DIR ${glog_DIR}/glog)
+else()
+set(glog_DIR "")
+endif()
+
+# Find lib
+set(GLOG_FOUND FALSE CACHE BOOL "" FORCE)
+find_library(GLOG_LIBRARY
+    NAMES glog libglog
+    PATHS ${glog_DIR}
+    PATH_SUFFIXES lib/
+)
+
+# Find include
+find_path(GLOG_INCLUDE_DIRS
+    NAMES glog/logging.h
+    PATHS ${glog_DIR}
+    PATH_SUFFIXES include
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(glog DEFAULT_MSG GLOG_LIBRARY GLOG_INCLUDE_DIRS)
+
+message(STATUS "(GLOG_FOUND : ${GLOG_FOUND} include: ${GLOG_INCLUDE_DIRS}, lib: ${GLOG_LIBRARY})")
+
+mark_as_advanced(GLOG_FOUND)
+
+if(GLOG_FOUND)
+	include_directories(${GLOG_INCLUDE_DIRS})
+    set(GLOG_FOUND TRUE CACHE BOOL "" FORCE)
+    set(GLOG_LIBRARIES ${GLOG_LIBRARY})
+    message(STATUS "glog found ( include: ${GLOG_INCLUDE_DIRS}, lib: ${GLOG_LIBRARY})")
+endif()
diff --git a/cv-node/include/ftl/config.h.in b/cv-node/include/ftl/config.h.in
new file mode 100644
index 0000000000000000000000000000000000000000..1ca2bb0b3c79e8ecbb3d750e1c49274d96c8287d
--- /dev/null
+++ b/cv-node/include/ftl/config.h.in
@@ -0,0 +1,16 @@
+#ifndef __FTL_CONFIG_H__
+#define __FTL_CONFIG_H__
+
+#cmakedefine HAVE_VIZ
+#cmakedefine HAVE_OPENCVCUDA
+
+#define FTL_VERSION @FTL_VERSION@
+#define FTL_VERSION_MAJOR @ftl_VERSION_MAJOR@
+#define FTL_VERSION_MINOR @ftl_VERSION_MINOR@
+#define FTL_VERSION_PATCH @ftl_VERSION_PATCH@
+
+#define FTL_CONFIG_ROOT @FTL_CONFIG_ROOT@
+#define FTL_CACHE_ROOT @FTL_CACHE_ROOT@
+#define FTL_DATA_ROOT @FTL_DATA_ROOT@
+
+#endif // __FTL_CONFIG_H__
diff --git a/cv-node/include/ftl/display.hpp b/cv-node/include/ftl/display.hpp
index 62e2aec263a9bd0467f7b12f487acdc00ec9f0bb..e0706a7bfcaf62a55a6187892f7e5676f5f7c9ea 100644
--- a/cv-node/include/ftl/display.hpp
+++ b/cv-node/include/ftl/display.hpp
@@ -4,6 +4,7 @@
 #include <nlohmann/json.hpp>
 #include <opencv2/opencv.hpp>
 #include <ftl/calibrate.hpp>
+#include <ftl/config.h>
 #include "opencv2/highgui.hpp"
 
 namespace ftl {
@@ -19,7 +20,11 @@ namespace ftl {
 		private:
 		const ftl::Calibrate &calibrate_;
 		nlohmann::json config_;
+
+		#if defined HAVE_VIZ
 		cv::viz::Viz3d *window_;
+		#endif // HAVE_VIZ
+
 		bool active_;
 	};
 };
diff --git a/cv-node/src/calibrate.cpp b/cv-node/src/calibrate.cpp
index 403ad8f9ed531e154bb43fa60f87575db41ab29c..cb66dad517aba256fbad10c66a92076441e986ee 100644
--- a/cv-node/src/calibrate.cpp
+++ b/cv-node/src/calibrate.cpp
@@ -5,6 +5,7 @@
 #include <cstdio>
 
 #include <ftl/calibrate.hpp>
+#include <ftl/config.h>
 
 #include <opencv2/core.hpp>
 #include <opencv2/core/utility.hpp>
diff --git a/cv-node/src/display.cpp b/cv-node/src/display.cpp
index 74cc94b4a460859f47e018bfebb1dbeb3efbb099..9884560ffac44969b57ddebd3e7328eff65b4b95 100644
--- a/cv-node/src/display.cpp
+++ b/cv-node/src/display.cpp
@@ -1,22 +1,29 @@
 #include <ftl/display.hpp>
+#include <glog/logging.h>
 
 using ftl::Display;
+using ftl::Calibrate;
 using namespace cv;
 
 Display::Display(const Calibrate &cal, nlohmann::json &config) : calibrate_(cal), config_(config) {
+	#if defined HAVE_VIZ
 	window_ = new cv::viz::Viz3d("FTL");
 	window_->setBackgroundColor(cv::viz::Color::white());
+	#endif // HAVE_VIZ
 	active_ = true;
 }
 
 Display::~Display() {
+	#if defined HAVE_VIZ
 	delete window_;
+	#endif // HAVE_VIZ
 }
 
 bool Display::render(const cv::Mat &rgb, const cv::Mat &depth) {
 	Mat idepth;
 
 	if (config_["points"]) {
+		#if defined HAVE_VIZ
 		cv::Mat Q_32F;
 		calibrate_.getQ().convertTo(Q_32F,CV_32F);
 		cv::Mat_<cv::Vec3f> XYZ(depth.rows,depth.cols);   // Output point cloud
@@ -32,6 +39,12 @@ bool Display::render(const cv::Mat &rgb, const cv::Mat &depth) {
 		window_->showWidget( "Depth", cloud_widget );
 
 		window_->spinOnce( 1, true );
+
+		#else // HAVE_VIZ
+
+		LOG(ERROR) << "Need OpenCV Viz module to display points";
+
+		#endif // HAVE_VIZ
 	}
 	
 	if (config_["depth"]) {
@@ -60,6 +73,10 @@ bool Display::render(const cv::Mat &rgb, const cv::Mat &depth) {
 }
 
 bool Display::active() const {
+	#if defined HAVE_VIZ
 	return active_ && !window_->wasStopped();
+	#else
+	return active_;
+	#endif
 }
 
diff --git a/cv-node/src/main.cpp b/cv-node/src/main.cpp
index ed2aa9bc25f3bdc5a456ba813c026b98d6be6fc6..7827f98cab06729a7300b7607f82a821fb60feca 100644
--- a/cv-node/src/main.cpp
+++ b/cv-node/src/main.cpp
@@ -5,6 +5,7 @@
 #include <ftl/disparity.hpp>
 #include <ftl/middlebury.hpp>
 #include <ftl/display.hpp>
+#include <ftl/config.h>
 #include <nlohmann/json.hpp>
 
 #include "opencv2/imgproc.hpp"
@@ -75,6 +76,7 @@ static void process_options(const map<string,string> &opts) {
 		
 		try {
 			auto ptr = json::json_pointer("/"+opt.first);
+			// TODO Allow strings without quotes
 			auto v = json::parse(opt.second);
 			if (v.type() != config.at(ptr).type()) {
 				LOG(ERROR) << "Incorrect type for argument " << opt.first;
@@ -87,29 +89,6 @@ static void process_options(const map<string,string> &opts) {
 	}
 }
 
-static string type2str(int type) {
-  string r;
-
-  uchar depth = type & CV_MAT_DEPTH_MASK;
-  uchar chans = 1 + (type >> CV_CN_SHIFT);
-
-  switch ( depth ) {
-    case CV_8U:  r = "8U"; break;
-    case CV_8S:  r = "8S"; break;
-    case CV_16U: r = "16U"; break;
-    case CV_16S: r = "16S"; break;
-    case CV_32S: r = "32S"; break;
-    case CV_32F: r = "32F"; break;
-    case CV_64F: r = "64F"; break;
-    default:     r = "User"; break;
-  }
-
-  r += "C";
-  r += (chans+'0');
-
-  return r;
-}
-
 static void run(const string &file) {
 	// TODO Initiate the network
 	
@@ -146,7 +125,7 @@ static void run(const string &file) {
 	
 	while (display.active()) {
 		// Read calibrated images.
-		calibrate.undistort(l,r);
+		calibrate.rectified(l,r);
 		
 		// Feed into sync buffer and network forward
 		sync->feed(LEFT, l,lsrc->getTimestamp());
@@ -179,6 +158,7 @@ int main(int argc, char **argv) {
 	}
 	process_options(options);
 	
+	// Choose normal or middlebury modes
 	if (config["middlebury"]["dataset"] == "") {
 		run((argc > 0) ? argv[0] : "");
 	} else {