diff --git a/applications/reconstruct/src/main.cpp b/applications/reconstruct/src/main.cpp
index 9b2eda9debdf995873d2ff36a1795d6c744233e0..f981494cbb54c17524ee062d7ec84446ca8f4da6 100644
--- a/applications/reconstruct/src/main.cpp
+++ b/applications/reconstruct/src/main.cpp
@@ -282,11 +282,13 @@ static void run(ftl::Configurable *root) {
 			UNIQUE_LOCK(scene_A.mtx, lk);
 
 			// Apply pre-filters to all frames
-			for (int i=0; i<scene_A.frames.size(); ++i) {
+			/*for (int i=0; i<scene_A.frames.size(); ++i) {
 				auto &f = scene_A.frames[i];
 				auto s = scene_A.sources[i];
 				prefilter->apply(f, f, s, 0);
-			}
+			}*/
+
+			prefilter->apply(scene_A, scene_A, 0);
 
 			// Send all frames to GPU, block until done?
 			//scene_A.upload(Channel::Colour + Channel::Depth);  // TODO: (Nick) Add scene stream.
diff --git a/components/operators/src/operator.cpp b/components/operators/src/operator.cpp
index c877977a9bb67dfbe8179ce3588bce8dc789f85a..91dada28b6adddfcdb3e71861aca07591c57fa9c 100644
--- a/components/operators/src/operator.cpp
+++ b/components/operators/src/operator.cpp
@@ -38,6 +38,29 @@ Graph::~Graph() {
 
 }
 
+bool Graph::apply(FrameSet &in, FrameSet &out, cudaStream_t stream) {
+	if (!value("enabled", true)) return false;
+
+	if (in.frames.size() != out.frames.size()) return false;
+
+	for (auto &i : operators_) {
+		// Make sure there are enough instances
+		while (i.instances.size() < in.frames.size()) {
+			i.instances.push_back(i.maker->make());
+		}
+
+		for (int j=0; j<in.frames.size(); ++j) {
+			auto *instance = i.instances[j];
+
+			if (instance->enabled()) {
+				instance->apply(in.frames[j], out.frames[j], in.sources[j], stream);
+			}
+		}
+	}
+
+	return true;
+}
+
 bool Graph::apply(Frame &in, Frame &out, Source *s, cudaStream_t stream) {
 	if (!value("enabled", true)) return false;