diff --git a/lib/libstereo/CMakeLists.txt b/lib/libstereo/CMakeLists.txt
index 4031f68d9c2c3c3d4656e7c574ccbbe854394c4a..a5fe73958e3a2910d1aea58ef813a2b3bab0623f 100644
--- a/lib/libstereo/CMakeLists.txt
+++ b/lib/libstereo/CMakeLists.txt
@@ -42,6 +42,7 @@ if (LIBSTEREO_SHARED)
                 src/algorithms/stablesgm.cu
                 src/algorithms/tcensussgm.cu
                 src/algorithms/hcensussgm.cu
+                src/algorithms/brefcensussgm.cu
                 #src/stereo_hier_census.cu
                 src/stereo_wcensussgm.cu
                 src/stereo_census_adaptive.cu
@@ -73,6 +74,7 @@ else()
                 src/algorithms/stablesgm.cu
                 src/algorithms/tcensussgm.cu
                 src/algorithms/hcensussgm.cu
+                src/algorithms/brefcensussgm.cu
                 #src/stereo_hier_census.cu
                 src/stereo_wcensussgm.cu
                 src/stereo_census_adaptive.cu
diff --git a/lib/libstereo/include/stereo.hpp b/lib/libstereo/include/stereo.hpp
index df5676e6f67a71c58cc0cbded7f7ba2086a1fae3..ea40a6386b7d8f85276718a9ffd2ce9b689bfcff 100644
--- a/lib/libstereo/include/stereo.hpp
+++ b/lib/libstereo/include/stereo.hpp
@@ -85,6 +85,37 @@ private:
 	Impl *impl_;
 };
 
+/**
+ * Bilateral filtering for reference pixel. Doesn't make things better
+ */
+class StereoBRefCensusSgm {
+public:
+	StereoBRefCensusSgm();
+	~StereoBRefCensusSgm();
+
+	void compute(cv::InputArray l, cv::InputArray r, cv::OutputArray disparity);
+	void setPrior(cv::InputArray disp) {};
+
+	struct Parameters {
+		int d_min = 0;
+		int d_max = 0;
+		unsigned short P1 = 5;
+		unsigned short P2 = 25;
+		float uniqueness = std::numeric_limits<unsigned short>::max();
+		int subpixel = 1; // subpixel interpolation method
+		bool lr_consistency = true;
+		int paths = AggregationDirections::HORIZONTAL |
+					AggregationDirections::VERTICAL |
+					AggregationDirections::DIAGONAL;
+		bool debug = false;
+	};
+	Parameters params;
+
+private:
+	struct Impl;
+	Impl *impl_;
+};
+
 /**
  * STABLE Binary descriptor. This is a general implementation.
  * 
diff --git a/lib/libstereo/middlebury/main.cpp b/lib/libstereo/middlebury/main.cpp
index caceb4e5237ef509c258d596c1d2f51dad0110a7..0c627989d7088fdbbfd17f5befaeb87e2a1c048f 100644
--- a/lib/libstereo/middlebury/main.cpp
+++ b/lib/libstereo/middlebury/main.cpp
@@ -27,6 +27,19 @@ static void run_censussgm(MiddleburyData &data, cv::Mat &disparity) {
 	stereo.compute(data.imL, data.imR, disparity);
 }
 
+static void run_brefcensussgm(MiddleburyData &data, cv::Mat &disparity) {
+	auto stereo = StereoBRefCensusSgm();
+	stereo.params.P1 = 12;
+	stereo.params.P2 = 32;
+
+	stereo.params.d_min = data.calib.vmin;
+	stereo.params.d_max = data.calib.vmax;
+	stereo.params.subpixel = 1;
+	stereo.params.lr_consistency = true;
+	stereo.params.debug = false;
+	stereo.compute(data.imL, data.imR, disparity);
+}
+
 static void run_stablesgm(MiddleburyData &data, cv::Mat &disparity) {
 	auto stereo = StereoStableSgm();
 	stereo.params.P1 = 8;
@@ -179,6 +192,7 @@ static const std::map<std::string, std::function<void(MiddleburyData&, cv::Mat&)
 	{ "tcensussgm", run_tcensussgm },
 	{ "hcensussgm", run_hcensussgm },
 	{ "wcensussgm", run_wcensussgm },
+	{ "brefcensus", run_brefcensussgm },
 	//{ "misgm", run_misgm },
 	{ "varcensus", run_varcensus },
 	{ "stablesgm", run_stablesgm },
diff --git a/lib/libstereo/src/algorithms/brefcensussgm.cu b/lib/libstereo/src/algorithms/brefcensussgm.cu
new file mode 100644
index 0000000000000000000000000000000000000000..141388f3d570785bdff2e508fe5c044fbd03878c
--- /dev/null
+++ b/lib/libstereo/src/algorithms/brefcensussgm.cu
@@ -0,0 +1,48 @@
+#include "stereo.hpp"
+#include "stereosgm.hpp"
+#include "../costs/census.hpp"
+#include <opencv2/cudaimgproc.hpp>
+#include <opencv2/highgui.hpp>
+
+struct StereoBRefCensusSgm::Impl : public StereoSgm<CensusMatchingCost, StereoBRefCensusSgm::Parameters> {
+	Array2D<uchar> l;
+    Array2D<uchar> r;
+    Array2D<uchar> bl;
+    Array2D<uchar> br;
+
+	Impl(StereoBRefCensusSgm::Parameters &params, int width, int height, int dmin, int dmax) :
+        StereoSgm(params, width, height, dmin, dmax), l(width, height), r(width, height),
+        bl(width, height), br(width, height) {}
+};
+
+StereoBRefCensusSgm::StereoBRefCensusSgm() : impl_(nullptr) {
+	impl_ = new Impl(params, 0, 0, 0, 0);
+}
+
+void StereoBRefCensusSgm::compute(cv::InputArray l, cv::InputArray r, cv::OutputArray disparity) {
+
+	cudaSetDevice(0);
+
+	if (l.rows() != impl_->cost.height() || r.cols() != impl_->cost.width()) {
+		delete impl_; impl_ = nullptr;
+		impl_ = new Impl(params, l.cols(), l.rows(), params.d_min, params.d_max);
+	}
+
+	mat2gray(l, impl_->l);
+    mat2gray(r, impl_->r);
+    
+    cv::cuda::bilateralFilter(impl_->l.toGpuMat(), impl_->bl.toGpuMat(), 5, 50, 100);
+    cv::cuda::bilateralFilter(impl_->r.toGpuMat(), impl_->br.toGpuMat(), 5, 50, 100);
+
+	impl_->cost.set(impl_->bl, impl_->br, impl_->l, impl_->r);
+
+	cudaSafeCall(cudaDeviceSynchronize());
+	impl_->compute(disparity);
+}
+
+StereoBRefCensusSgm::~StereoBRefCensusSgm() {
+	if (impl_) {
+		delete impl_;
+		impl_ = nullptr;
+	}
+}