diff --git a/SDK/CPP/public/samples/fusion_evaluator/main.cpp b/SDK/CPP/public/samples/fusion_evaluator/main.cpp
index d73bde963be2495de9984fbd1de5211556463bef..691e0e2906069d4dc1080a734ac99cd09cb666c5 100644
--- a/SDK/CPP/public/samples/fusion_evaluator/main.cpp
+++ b/SDK/CPP/public/samples/fusion_evaluator/main.cpp
@@ -16,6 +16,8 @@ int main(int argc, char **argv)
 {
 	bool do_fusion = true;
 	bool do_eval = true;
+	int frameno = 0;
+	int sourceno = 0;
 	voltu::Channel display_channel = voltu::Channel::kColour;
 	std::list<std::string> paths;
 
@@ -23,23 +25,33 @@ int main(int argc, char **argv)
 
 	for (const auto &s : opts)
 	{
-		cout << "ARGS " << s.first << " " << s.second << endl; 
 		if (s.first == "--no-fusion")
 		{
 			do_fusion = false;
 		}
 		else if (s.first == "--display")
 		{
-			cout << "DISPLAY = " << s.second << endl;
 			if (s.second == "\"normals\"")
 			{
 				display_channel = voltu::Channel::kNormals;
 			}
+			else if (s.second == "\"depth\"")
+			{
+				display_channel = voltu::Channel::kDepth;
+			}
 		}
 		else if (s.first == "--no-eval")
 		{
 			do_eval = false;
 		}
+		else if (s.first == "--frame")
+		{
+			frameno = std::stoi(s.second);
+		}
+		else if (s.first == "--source")
+		{
+			sourceno = std::stoi(s.second);
+		}
 		else if (s.first[0] != '-')
 		{
 			paths.push_back(s.first);
@@ -70,7 +82,11 @@ int main(int argc, char **argv)
 		return -1;
 	}
 
-	//room->waitNextFrame(5000);
+	for (int i=0; i<frameno; ++i)
+	{
+		room->waitNextFrame(5000);
+		room->getFrame();
+	}
 	auto frame = room->getFrame();
 
 	auto pipe = vtu->createPipeline();
@@ -96,8 +112,10 @@ int main(int argc, char **argv)
 		return -1;
 	}
 
+	int srccount = 0;
 	for (auto img : imgset)
 	{
+		if (srccount++ < sourceno) continue;
 		cv::Mat m;
 		voltu::cv::visualise(img, m);
 		cv::imshow(string("Image-") + img->getName(), m);
diff --git a/SDK/CPP/public/voltu_cv.cpp b/SDK/CPP/public/voltu_cv.cpp
index 31cd29aa6f85a77ee3baf23541d918ea5046b01a..e9951dc37959b0ea89b22c1d2f6432690619f4ef 100644
--- a/SDK/CPP/public/voltu_cv.cpp
+++ b/SDK/CPP/public/voltu_cv.cpp
@@ -49,8 +49,12 @@ void voltu::cv::visualise(voltu::ImagePtr img, ::cv::Mat &mat)
 		::cv::Mat tmp;
 		voltu::cv::convert(img, tmp);
 
-		::cv::normalize(tmp, tmp, 0, 255, ::cv::NORM_MINMAX);
-		tmp.convertTo(tmp, CV_8U);
+		float maxdepth = 8.0f;  // TODO: Get from intrinsics
+
+		//::cv::normalize(tmp, tmp, 0, 255, ::cv::NORM_MINMAX);
+		tmp.convertTo(tmp, CV_8U, 255.0f / maxdepth);
+		::cv::Mat mask = tmp > 0;
+		::cv::subtract(::cv::Scalar(255), tmp, tmp, mask);
 		
 		//#if OPENCV_VERSION >= 40102
 		//cv::applyColorMap(tmp, mat, cv::COLORMAP_TURBO);
diff --git a/components/operators/src/fusion/fusion.cpp b/components/operators/src/fusion/fusion.cpp
index 606df89d69a166f32441ef2fdf600b458d50e1ee..b1b10634216156c97c8cee6e2d7b54fa3939303a 100644
--- a/components/operators/src/fusion/fusion.cpp
+++ b/components/operators/src/fusion/fusion.cpp
@@ -38,6 +38,9 @@ bool Fusion::apply(ftl::rgbd::FrameSet &in, ftl::rgbd::FrameSet &out, cudaStream
 
 	for (size_t i=0; i<in.frames.size(); ++i) {
 		if (!in.hasFrame(i)) continue;
+
+		if (!in.frames[i].hasChannel(Channel::Colour) || !in.frames[i].hasChannel(Channel::Depth)) continue;
+
 		const GpuMat &col = in.frames[i].get<GpuMat>(Channel::Colour);
 		const GpuMat &d = in.frames[i].get<GpuMat>(Channel::Depth);
 
@@ -71,12 +74,16 @@ bool Fusion::apply(ftl::rgbd::FrameSet &in, ftl::rgbd::FrameSet &out, cudaStream
 		for (size_t i=0; i < in.frames.size(); ++i) {
 			if (!in.hasFrame(i)) continue;
 
+			if (!in.frames[i].hasChannel(Channel::Colour) || !in.frames[i].hasChannel(Channel::Depth)) continue;
+
 			auto &f = in.frames[i].cast<ftl::rgbd::Frame>();
 
 			for (size_t j=0; j < in.frames.size(); ++j) {
 				if (i == j) continue;
 				if (!in.hasFrame(j)) continue;
 
+				if (!in.frames[j].hasChannel(Channel::Colour) || !in.frames[j].hasChannel(Channel::Depth)) continue;
+
 				auto &ref = in.frames[j].cast<ftl::rgbd::Frame>();
 
 				auto transformR = MatrixConversion::toCUDA(ref.getPose().cast<float>().inverse() * f.getPose().cast<float>());
@@ -101,6 +108,7 @@ bool Fusion::apply(ftl::rgbd::FrameSet &in, ftl::rgbd::FrameSet &out, cudaStream
 	for (int iters=0; iters < mls_iters; ++iters) {
 	for (size_t i=0; i<in.frames.size(); ++i) {
 		if (!in.hasFrame(i)) continue;
+		if (!in.frames[i].hasChannel(Channel::Normals) || !in.frames[i].hasChannel(Channel::Depth)) continue;
 
 		auto &f1 = in.frames[i].cast<ftl::rgbd::Frame>();
 
@@ -120,6 +128,7 @@ bool Fusion::apply(ftl::rgbd::FrameSet &in, ftl::rgbd::FrameSet &out, cudaStream
 		for (size_t j=0; j<in.frames.size(); ++j) {
 			if (!in.hasFrame(j)) continue;
 			//if (i == j) continue;
+			if (!in.frames[j].hasChannel(Channel::Normals) || !in.frames[j].hasChannel(Channel::Depth)) continue;
 
 			//LOG(INFO) << "Running phase1";