diff --git a/applications/registration/src/correspondances.cpp b/applications/registration/src/correspondances.cpp
index f510e213d516a5ed18cba761251d05091ff051a0..9b41a057235e39f12075bb9a9073d70728f05b2f 100644
--- a/applications/registration/src/correspondances.cpp
+++ b/applications/registration/src/correspondances.cpp
@@ -2,6 +2,8 @@
 #include <nlohmann/json.hpp>
 #include <random>
 #include <chrono>
+#include <thread>
+#include <opencv2/xphoto.hpp>
 
 using ftl::registration::Correspondances;
 using std::string;
@@ -14,6 +16,7 @@ using pcl::PointXYZRGB;
 using nlohmann::json;
 using std::tuple;
 using std::make_tuple;
+using cv::Mat;
 
 
 Correspondances::Correspondances(Source *src, Source *targ)
@@ -86,16 +89,16 @@ static PointXYZ makePCL(Source *s, int x, int y) {
 }
 
 void Correspondances::clear() {
-	targ_cloud_.clear();
-	src_cloud_.clear();
-	src_index_ = cv::Mat(rgb1.size(), CV_32SC1, cv::Scalar(-1));
-	targ_index_ = cv::Mat(rgb2.size(), CV_32SC1, cv::Scalar(-1));
+	targ_cloud_->clear();
+	src_cloud_->clear();
+	src_index_ = cv::Mat(cv::Size(src_->parameters().width, src_->parameters().height), CV_32SC1, cv::Scalar(-1));
+	targ_index_ = cv::Mat(cv::Size(targ_->parameters().width, targ_->parameters().height), CV_32SC1, cv::Scalar(-1));
 	src_feat_.clear();
 	targ_feat_.clear();
 	log_.clear();
 }
 
-void Correspondance::clearCorrespondances() {
+void Correspondances::clearCorrespondances() {
 	src_feat_.clear();
 	targ_feat_.clear();
 	log_.clear();
@@ -109,10 +112,10 @@ bool Correspondances::capture(cv::Mat &rgb1, cv::Mat &rgb2) {
 	vector<vector<Mat>> buffer(2, vector<Mat>(buffer_size));
 
 	for (size_t i = 0; i < buffer_size; ++i) {
-		current->source()->grab();
-		current->target()->grab();
-		current->source()->getFrames(rgb1, d1);
-		current->target()->getFrames(rgb2, d2);
+		src_->grab();
+		targ_->grab();
+		src_->getFrames(rgb1, d1);
+		targ_->getFrames(rgb2, d2);
 		buffer[0][i] = d1;
 		buffer[1][i] = d2;
 
@@ -129,10 +132,11 @@ bool Correspondances::capture(cv::Mat &rgb1, cv::Mat &rgb2) {
 	cv::imshow("smooth d1", d1_v);
 	cv::imshow("smooth d2", d2_v);
 
-	Ptr<xphoto::WhiteBalancer> wb;
-	wb = xphoto::createSimpleWB();
+	// Should be done in RGB-Depth source class
+	/*cv::Ptr<cv::xphoto::WhiteBalancer> wb;
+	wb = cv::xphoto::createSimpleWB();
 	wb->balanceWhite(rgb1, rgb1);
-	wb->balanceWhite(rgb2, rgb2);
+	wb->balanceWhite(rgb2, rgb2);*/
 
 	// Build point clouds
 	clear();
@@ -142,8 +146,8 @@ bool Correspondances::capture(cv::Mat &rgb1, cv::Mat &rgb2) {
 	for (int y=0; y<rgb1.rows; y++) {
 		//unsigned char *rgb1ptr = rgb1.ptr(y);
 		//unsigned char *rgb2ptr = rgb2.ptr(y);
-		float *d1ptr = d1.ptr(y);
-		float *d2ptr = d2.ptr(y);
+		float *d1ptr = (float*)d1.ptr(y);
+		float *d2ptr = (float*)d2.ptr(y);
 
 		for (int x=0; x<rgb1.cols; x++) {
 			float d1_value = d1ptr[x];
@@ -151,15 +155,23 @@ bool Correspondances::capture(cv::Mat &rgb1, cv::Mat &rgb2) {
 
 			if (d1_value < 39.0f) {
 				// Make PCL points with specific depth value
-				pcl::PointXYZ p1 = src_->point(x,y,d1_value);
-				src_cloud_.push_back(p1);
+				pcl::PointXYZ p1;
+				Eigen::Vector4f p1e = src_->point(x,y,d1_value);
+				p1.x = p1e[0];
+				p1.y = p1e[1];
+				p1.z = p1e[2];
+				src_cloud_->push_back(p1);
 				src_index_.at<int>(y,x) = six++;
 			}
 
 			if (d2_value < 39.0f) {
 				// Make PCL points with specific depth value
-				pcl::PointXYZ p2 = src_->point(x,y,d2_value);
-				targ_cloud_.push_back(p2);
+				pcl::PointXYZ p2;
+				Eigen::Vector4f p2e = src_->point(x,y,d2_value);
+				p2.x = p2e[0];
+				p2.y = p2e[1];
+				p2.z = p2e[3];
+				targ_cloud_->push_back(p2);
 				targ_index_.at<int>(y,x) = tix++;
 			}
 		}
@@ -188,19 +200,12 @@ bool Correspondances::add(int tx, int ty, int sx, int sy) {
 
 void Correspondances::removeLast() {
 	uptodate_ = false;
-	targ_feat_->erase(targ_feat_->end()-1);
-	src_feat_->erase(src_feat_->end()-1);
+	targ_feat_.erase(targ_feat_.end()-1);
+	src_feat_.erase(src_feat_.end()-1);
 	log_.pop_back();
 }
 
 double Correspondances::estimateTransform(Eigen::Matrix4f &T) {
-	//Eigen::Matrix4f transform = transform_ * T;
-	uptodate_ = true;
-	//int n_points = targ_cloud_->size();
-
-	//vector<int> idx(n_points);
-	//for (int i = 0; i < n_points; i++) { idx[i] = i; }
-
 	pcl::registration::TransformationValidationEuclidean<PointXYZ, PointXYZ> validate;
 	pcl::registration::TransformationEstimationSVD<PointXYZ,PointXYZ> svd;
 
@@ -209,8 +214,6 @@ double Correspondances::estimateTransform(Eigen::Matrix4f &T) {
 }
 
 double Correspondances::estimateTransform(Eigen::Matrix4f &T, const vector<int> &src_feat, const vector<int> &targ_feat) {
-	uptodate_ = true;
-
 	pcl::registration::TransformationValidationEuclidean<PointXYZ, PointXYZ> validate;
 	pcl::registration::TransformationEstimationSVD<PointXYZ,PointXYZ> svd;
 
@@ -236,7 +239,7 @@ double Correspondances::findBestSubset(Eigen::Matrix4f &tr, int K, int N) {
 	Eigen::Matrix4f bestT;
 
 	std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
-	std::uniform_int_distribution<int> distribution(0,p.size()-1);
+	std::uniform_int_distribution<int> distribution(0,src_feat_.size()-1);
 	//int dice_roll = distribution(generator);
 	auto dice = std::bind ( distribution, rng );
 
@@ -265,7 +268,6 @@ double Correspondances::findBestSubset(Eigen::Matrix4f &tr, int K, int N) {
 
 		if (scoreT < score) {
 			score = scoreT;
-			best = ps;
 			bestT = T;
 		}
 	}
@@ -278,6 +280,6 @@ double Correspondances::findBestSubset(Eigen::Matrix4f &tr, int K, int N) {
 }
 
 Eigen::Matrix4f Correspondances::transform() {
-	if (!uptodate_) estimateTransform();
+	if (!uptodate_) estimateTransform(transform_);
 	return (parent_) ? parent_->transform() * transform_ : transform_;
 }
diff --git a/applications/registration/src/correspondances.hpp b/applications/registration/src/correspondances.hpp
index 6a58dfb18783a450f2c70acd869906afe7174cc6..5f4b397d70ea46a3861a17a2e20c44176c40220a 100644
--- a/applications/registration/src/correspondances.hpp
+++ b/applications/registration/src/correspondances.hpp
@@ -60,9 +60,10 @@ class Correspondances {
 	 * 
 	 * @return Validation score of the transform.
 	 */
-	double estimateTransform();
+	double estimateTransform(Eigen::Matrix4f &);
+	double estimateTransform(Eigen::Matrix4f &T, const std::vector<int> &src_feat, const std::vector<int> &targ_feat);
 
-	double findBest(Eigen::Matrix4f &tr, const std::vector<std::tuple<int,int,int,int>> &p, int K, int N);
+	double findBestSubset(Eigen::Matrix4f &tr, int K, int N);
 
 	void convertToPCL(const std::vector<std::tuple<int,int,int,int>> &p, std::vector<std::pair<pcl::PointXYZ, pcl::PointXYZ>> &p2);
 
@@ -83,7 +84,10 @@ class Correspondances {
 	Eigen::Matrix4f transform_;
 	bool uptodate_;
 	std::vector<std::tuple<int,int,int,int>> log_;
-	cv::Mat &index_;
+	cv::Mat src_index_;
+	cv::Mat targ_index_;
+	std::vector<int> targ_feat_;
+	std::vector<int> src_feat_;
 };
 
 }
diff --git a/applications/registration/src/manual.cpp b/applications/registration/src/manual.cpp
index 98926415e3f4ed86d02bdc177ee4294104096161..543cb8ef6ede6ac172f8510a979dc01022fd95ff 100644
--- a/applications/registration/src/manual.cpp
+++ b/applications/registration/src/manual.cpp
@@ -14,7 +14,6 @@
 #include <opencv2/imgcodecs.hpp>
 #include <opencv2/videoio.hpp>
 #include <opencv2/highgui.hpp>
-#include <opencv2/xphoto.hpp>
 
 #include <map>
 
@@ -223,10 +222,10 @@ void ftl::registration::manual(ftl::Configurable *root) {
 			tsdepth.convertTo(sdepth, CV_8U, 255.0f / 10.0f);
 			applyColorMap(sdepth, sdepth, cv::COLORMAP_JET);
 
-			Ptr<xphoto::WhiteBalancer> wb;
+			/*Ptr<xphoto::WhiteBalancer> wb;
 			wb = xphoto::createSimpleWB();
 			wb->balanceWhite(tsrgb, srgb);
-			wb->balanceWhite(ttrgb, trgb);
+			wb->balanceWhite(ttrgb, trgb);*/
 
 			// Apply points and labels...
 			auto &points = current->screenPoints();
@@ -261,23 +260,24 @@ void ftl::registration::manual(ftl::Configurable *root) {
 			curtarget = key-48;
 			if (curtarget >= sources.size()) curtarget = 0;
 			current = corrs[sources[curtarget]->getURI()];
-			feat.clear();
-			pclfeat.clear();
 			lastScore = 1000.0;
 		} else if (key == 'd') {
 			depthtoggle = !depthtoggle;
 		} else if (key == 'c') {
-			feat.clear();
-			pclfeat.clear();
+			current->clear();
 			lastScore = 1000.0;
 		}else if (key == 'a') {
+			Eigen::Matrix4f t;
 			if (current->add(lastTX,lastTY,lastSX,lastSY)) {
 				lastTX = lastTY = lastSX = lastSY = 0;
-				lastScore = current->estimateTransform();
+				lastScore = current->estimateTransform(t);
+				current->setTransform(t);
 			}
 		} else if (key == 'u') {
 			current->removeLast();
-			lastScore = current->estimateTransform();
+			Eigen::Matrix4f t;
+			lastScore = current->estimateTransform(t);
+			current->setTransform(t);
 		} else if (key == 's') {
 			// Save
 			map<string, Eigen::Matrix4f> transforms;
@@ -301,13 +301,13 @@ void ftl::registration::manual(ftl::Configurable *root) {
 				insearch = true;
 				LOG(INFO) << "Features matched = " << feat.size();
 
-				ftl::pool.push([&lastScore,&insearch,current,&feat,&pclfeat](int id) {
+				ftl::pool.push([&lastScore,&insearch,current](int id) {
 					LOG(INFO) << "START";
 					lastScore = 1000.0;
 					do {
 						Eigen::Matrix4f tr;
-						float s = current->findBest(tr, feat, pclfeat, 20, 100);
-						//LOG(INFO) << "SCORE = " << s;
+						float s = current->findBestSubset(tr, 20, 10);
+						LOG(INFO) << "SCORE = " << s;
 						if (s < lastScore) {
 							lastScore = s;
 							current->setTransform(tr);
@@ -326,21 +326,19 @@ void ftl::registration::manual(ftl::Configurable *root) {
 				insearch = false;
 			}
 		} else if (key == 'f') {
-			Mat f1,f2;
-			current->capture(f1,f2);
-
-			vector<tuple<int,int,int,int>> tfeat;
-			if (!insearch && ftl::registration::featuresSIFT(f1, f2, tfeat, 10)) {
-				vector<tuple<int,int,int,int>> tfeat2;
-				for (int j=0; j<tfeat.size(); j++) {
-					auto [sx,sy,tx,ty] = tfeat[j];
-					tfeat2.push_back(std::make_tuple(tx,ty,sx,sy));
+			if (!insearch) {
+				Mat f1,f2;
+				current->capture(f1,f2);
+
+				vector<tuple<int,int,int,int>> feat;
+				if (ftl::registration::featuresSIFT(f1, f2, feat, 2)) {
+					for (int j=0; j<feat.size(); j++) {
+						auto [sx,sy,tx,ty] = feat[j];
+						current->add(tx, ty, sx, sy);
+					}
 				}
-				current->setPoints(tfeat2);
-				feat.insert(feat.end(), tfeat.begin(), tfeat.end());
 
-				//vector<std::pair<pcl::PointXYZ, pcl::PointXYZ>> tpclfeat;
-				current->convertToPCL(tfeat,pclfeat);
+				LOG(INFO) << "Found " << current->screenPoints().size() << " features";
 			} else {
 				LOG(ERROR) << "Can't add features whilst searching...";
 			}