diff --git a/lib/libstereo/include/stereo.hpp b/lib/libstereo/include/stereo.hpp
index bd7b3891050a4dbe9f6dc679e6248680516ef3d5..48d58f9a0ddc34bafb1c4fa5ddd799605aed11eb 100644
--- a/lib/libstereo/include/stereo.hpp
+++ b/lib/libstereo/include/stereo.hpp
@@ -87,7 +87,7 @@ public:
 	~StereoMiSgm();
 
 	void compute(cv::InputArray l, cv::InputArray r, cv::OutputArray disparity);
-	void setPrior(const cv::Mat &disp);
+	void setPrior(cv::InputArray disp);
 
 	struct Parameters {
 		int d_min = 0;
@@ -109,6 +109,36 @@ private:
 };
 
 
+class StereoMiSgm2 {
+public:
+	StereoMiSgm2();
+	~StereoMiSgm2();
+
+	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 = 2;
+		unsigned short P2 = 8;
+		float uniqueness = std::numeric_limits<short>::max();
+		int subpixel = 1; // subpixel interpolation method
+		int paths = AggregationDirections::HORIZONTAL |
+					AggregationDirections::VERTICAL |
+					AggregationDirections::DIAGONAL;
+		bool debug = false;
+		float w1 = 1.0;
+		float w2 = 1.0;
+	};
+	Parameters params;
+
+private:
+	struct Impl;
+	Impl *impl_;
+};
+
+
 /**
  * Census + SGM + prior
  *
diff --git a/lib/libstereo/src/costs/census.cu b/lib/libstereo/src/costs/census.cu
index 05d61c3b7f471b162ae8c43378c31b81de94c94c..3930e7333e4376ec3f8cb724066ddc2e1aef6ea2 100644
--- a/lib/libstereo/src/costs/census.cu
+++ b/lib/libstereo/src/costs/census.cu
@@ -46,3 +46,24 @@ void CensusMatchingCost::set(const Array2D<uchar> &l, const Array2D<uchar> &r) {
 	parallel2D<algorithms::CensusTransform<9,7>>({l.data(), ct_l_.data()}, l.width, l.height);
 	parallel2D<algorithms::CensusTransform<9,7>>({r.data(), ct_r_.data()}, r.width, r.height);
 }
+
+void CensusMatchingCost::set(cv::InputArray l, cv::InputArray r) {
+	if (l.type() != CV_8UC1 || r.type() != CV_8UC1) { throw std::exception(); }
+	if (l.rows() != r.rows() || l.cols() != r.cols() || l.rows() != height() || l.cols() != width()) {
+		throw std::exception();
+	}
+
+	if (l.isGpuMat() && r.isGpuMat()) {
+		auto ml = l.getGpuMat();
+		auto mr = r.getGpuMat();
+		set(Array2D<uchar>(ml), Array2D<uchar>(mr));
+	}
+	else if (l.isMat() && r.isMat()) {
+		auto ml = l.getMat();
+		auto mr = r.getMat();
+		set(Array2D<uchar>(ml), Array2D<uchar>(mr));
+	}
+	else {
+		throw std::exception();
+	}
+}
diff --git a/lib/libstereo/src/costs/census.hpp b/lib/libstereo/src/costs/census.hpp
index bc20efd31fbf16d247a815b38185911b205c3c57..c8467b491961fa202adf01d25c8c42ca1fe2a0b4 100644
--- a/lib/libstereo/src/costs/census.hpp
+++ b/lib/libstereo/src/costs/census.hpp
@@ -39,17 +39,17 @@ public:
 	typedef unsigned short Type;
 
 	CensusMatchingCost() : DSBase<DataType>(0, 0, 0, 0) {};
-	CensusMatchingCost(int width, int height, int disp_min, int disp_max, int wwidth, int wheight)
+	CensusMatchingCost(int width, int height, int disp_min, int disp_max)
 		: DSBase<DataType>(width, height, disp_min, disp_max),
 			ct_l_(width, height), ct_r_(width,height),
 			//cost_max(wwidth * wheight),
-			ww_(wwidth), wh_(wheight)
+			ww_(9), wh_(7)
 		{
-			if (wwidth != 9 || wheight != 7) {
+			if (ww_ != 9 || wh_ != 7) {
 				// TODO: window size paramters (hardcoded) in matching_cost.cpp
 				throw std::exception();
 			}
-			if (wwidth*wheight > 64) {
+			if (ww_*wh_ > 64) {
 				throw std::exception(); // todo: dynamic size
 			}
 
@@ -57,6 +57,7 @@ public:
 			data().ct_r = ct_r_.data();
 		}
 
+	void set(cv::InputArray l, cv::InputArray r);
 	void set(const Array2D<uchar>& l, const Array2D<uchar>& r);
 	static constexpr short COST_MAX = 9*7; // TODO: window size paramters (hardcoded) in matching_cost.cpp
 
diff --git a/lib/libstereo/src/stereo_adcensussgm.cu b/lib/libstereo/src/stereo_adcensussgm.cu
index 9cd9838cf040ab3458fcb95a946b65f099836134..3baecec535598f673b20c5c201934f52732638d5 100644
--- a/lib/libstereo/src/stereo_adcensussgm.cu
+++ b/lib/libstereo/src/stereo_adcensussgm.cu
@@ -69,7 +69,7 @@ struct StereoADCensusSgm::Impl {
 	Impl(int width, int height, int min_disp, int max_disp) :
 		dsi(width, height, min_disp, max_disp),
 		ad_cost(width, height, min_disp, max_disp),
-		census_cost(width, height, min_disp, max_disp, 9, 7),
+		census_cost(width, height, min_disp, max_disp),
 		cost(width, height, min_disp, max_disp, ad_cost, census_cost),
 		cost_min(width, height),
 		cost_min_paths(width, height),
diff --git a/lib/libstereo/src/stereo_censussgm.cu b/lib/libstereo/src/stereo_censussgm.cu
index 7cb8f635ef5cb70b3bbcfca6bb21d4ccf298770d..f3969a5f303aa64afb0a2d6b042c0af9fba4fb04 100644
--- a/lib/libstereo/src/stereo_censussgm.cu
+++ b/lib/libstereo/src/stereo_censussgm.cu
@@ -63,8 +63,7 @@ struct StereoCensusSgm::Impl {
 	WinnerTakesAll<DSImage16U,float> wta;
 
 	Impl(int width, int height, int min_disp, int max_disp) :
-		//dsi(width, height, min_disp, max_disp),
-		cost(width, height, min_disp, max_disp, ct_windows_w, ct_windows_h),
+		cost(width, height, min_disp, max_disp),
 		cost_min(width, height),
 		cost_min_paths(width, height),
 		uncertainty(width, height),
diff --git a/lib/libstereo/src/stereo_misgm.cu b/lib/libstereo/src/stereo_misgm.cu
index aebc09a656cb9e98bb6e474e5611050adfc36f2e..6c54cce0caa8195551577f3db7233cb9b25ddc60 100644
--- a/lib/libstereo/src/stereo_misgm.cu
+++ b/lib/libstereo/src/stereo_misgm.cu
@@ -47,6 +47,7 @@ using ftl::stereo::aggregations::StandardSGM;
 
 struct StereoMiSgm::Impl {
 	MutualInformationMatchingCost cost;
+
 	Array2D<unsigned short> cost_min;
 	Array2D<unsigned short> cost_min_paths;
 	Array2D<unsigned short> uncertainty;
@@ -74,8 +75,16 @@ StereoMiSgm::StereoMiSgm() : impl_(nullptr) {
 	impl_ = new Impl(0, 0, 0, 0);
 }
 
-void StereoMiSgm::setPrior(const cv::Mat &prior) {
-	prior.copyTo(impl_->prior);
+void StereoMiSgm::setPrior(cv::InputArray prior) {
+	if (prior.rows() != impl_->cost.height() || prior.cols() != impl_->cost.width()) {
+		return;
+	}
+	if (prior.isGpuMat()) {
+		prior.getGpuMat().download(impl_->prior);
+	}
+	else {
+		prior.getMat().copyTo(impl_->prior);
+	}
 }