diff --git a/components/rgbd-sources/src/algorithms/fixstars_sgm.cpp b/components/rgbd-sources/src/algorithms/fixstars_sgm.cpp
index 80f7abd92a56a3c260f342fb789cd7cdaebba492..24d1435cd67d14208992d74649f3334136488466 100644
--- a/components/rgbd-sources/src/algorithms/fixstars_sgm.cpp
+++ b/components/rgbd-sources/src/algorithms/fixstars_sgm.cpp
@@ -2,6 +2,7 @@
 
 #include "fixstars_sgm.hpp"
 #include <glog/logging.h>
+#include <opencv2/cudastereo.hpp>
 
 using ftl::algorithms::FixstarsSGM;
 using cv::Mat;
@@ -10,6 +11,8 @@ using cv::Mat;
 
 FixstarsSGM::FixstarsSGM(nlohmann::json &config) : Disparity(config) {
 	ssgm_ = nullptr;
+	use_filter_ = config.value("use_filter", false);
+	filter_ = cv::cuda::createDisparityBilateralFilter(max_disp_, config.value("filter_radius", 25), config.value("filter_iter", 1));
 }
 
 void FixstarsSGM::compute(const cv::Mat &l, const cv::Mat &r, cv::Mat &disp) {
@@ -26,7 +29,7 @@ void FixstarsSGM::compute(const cv::Mat &l, const cv::Mat &r, cv::Mat &disp) {
 			sgm::StereoSGM::Parameters(10,120,0.95f,true));
 	}
 
-	disp = Mat(cv::Size(l.cols, l.rows), CV_16UC1);
+	disp = Mat(cv::Size(l.cols, l.rows), CV_16SC1);
 
 	//auto start = std::chrono::high_resolution_clock::now();
 	ssgm_->execute(lbw.data, rbw.data, disp.data);
@@ -35,8 +38,20 @@ void FixstarsSGM::compute(const cv::Mat &l, const cv::Mat &r, cv::Mat &disp) {
 	//LOG(INFO) << "CUDA sgm in " << elapsed.count() << "s";
 	
 	// todo: fix libSGM (return float data or provide mask separately)
-	// (256 << 5) coded in libSGM consistency check
+	// disparity values set to (256 << 5) in libSGM consistency check 
 	Mat bad_pixels = (disp == (256 << 5)); 
+	disp.setTo(0, bad_pixels);
+	
+	if (use_filter_) {
+		cv::cuda::GpuMat l_gpu, disp_gpu, disp_gpu_out;
+		// parameters need benchmarking, impact of image
+		// quick tests show with parameters (max_disp_, 25, 3)
+		// roughly 50% in disparity calculation and 50% in filter
+		disp_gpu.upload(disp);
+		l_gpu.upload(l);
+		filter_->apply(disp_gpu, l_gpu, disp_gpu_out);
+		disp_gpu_out.download(disp);
+	}
+	
 	disp.convertTo(disp, CV_32F, 1.0f/16.0f);
-	disp.setTo(0, bad_pixels); // decide how bad values should be represented
 }
\ No newline at end of file
diff --git a/components/rgbd-sources/src/algorithms/fixstars_sgm.hpp b/components/rgbd-sources/src/algorithms/fixstars_sgm.hpp
index 76ca631855eb47955a7695747e04b5045995bf6c..1e78aba89e2efe23f546cd28bed31b3eab80ae0b 100644
--- a/components/rgbd-sources/src/algorithms/fixstars_sgm.hpp
+++ b/components/rgbd-sources/src/algorithms/fixstars_sgm.hpp
@@ -9,6 +9,7 @@
 #include <opencv2/opencv.hpp>
 #include <libsgm.h>
 #include "../disparity.hpp"
+#include <opencv2/cudastereo.hpp>
 
 namespace ftl {
 namespace algorithms {
@@ -32,6 +33,8 @@ class FixstarsSGM : public ftl::Disparity {
 	}
 
 	private:
+	bool use_filter_;
+	cv::Ptr<cv::cuda::DisparityBilateralFilter> filter_;
 	sgm::StereoSGM *ssgm_;
 };
 };
diff --git a/config/config.json b/config/config.json
index 215a704c3c3bc0eb282df45d22a79dd3defb7099..300c4335205161c7966a23c9e5d51fddb36957f3 100644
--- a/config/config.json
+++ b/config/config.json
@@ -51,7 +51,10 @@
 			"gamma": 0.0,
 			"window_size": 5,
 			"sigma": 1.5,
-			"lambda": 8000.0
+			"lambda": 8000.0,
+			"use_filter": true,
+			"filter_radius": 20,
+			"filter_iter": 3
 		},
 		"display": {
 			"flip_vert": false,