diff --git a/components/operators/include/ftl/operators/operator.hpp b/components/operators/include/ftl/operators/operator.hpp
index 71d2e939ad5cb90f024a040d3f14a859c35c3936..79cd008fdba46447dd4a79e51ba6521868604aa9 100644
--- a/components/operators/include/ftl/operators/operator.hpp
+++ b/components/operators/include/ftl/operators/operator.hpp
@@ -72,6 +72,20 @@ struct ConstructionHelper : public ConstructionHelperBase {
 	}
 };
 
+template <typename T, typename... ARGS>
+struct ConstructionHelper2 : public ConstructionHelperBase {
+	explicit ConstructionHelper2(ftl::Configurable *cfg, ARGS... args) : ConstructionHelperBase(cfg) {
+		arguments_ = std::make_tuple(args...);
+	}
+	~ConstructionHelper2() {}
+	ftl::operators::Operator *make() override {
+		return new T(config, arguments_);
+	}
+
+	private:
+	std::tuple<ARGS...> arguments_;
+};
+
 struct OperatorNode {
 	ConstructionHelperBase *maker;
 	std::vector<ftl::operators::Operator*> instances;
@@ -92,6 +106,9 @@ class Graph : public ftl::Configurable {
 	template <typename T>
 	ftl::Configurable *append(const std::string &name);
 
+	template <typename T, typename... ARGS>
+	ftl::Configurable *append(const std::string &name, ARGS...);
+
 	bool apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t stream=0);
 	bool apply(ftl::rgbd::FrameSet &in, ftl::rgbd::FrameSet &out, cudaStream_t stream=0);
 	bool apply(ftl::rgbd::FrameSet &in, ftl::rgbd::Frame &out, cudaStream_t stream=0);
@@ -115,4 +132,12 @@ ftl::Configurable *ftl::operators::Graph::append(const std::string &name) {
 	return _append(new ftl::operators::detail::ConstructionHelper<T>(configs_[name]));
 }
 
+template <typename T, typename... ARGS>
+ftl::Configurable *ftl::operators::Graph::append(const std::string &name, ARGS... args) {
+	if (configs_.find(name) == configs_.end()) {
+		configs_[name] = ftl::create<ftl::Configurable>(this, name);
+	}
+	return _append(new ftl::operators::detail::ConstructionHelper2<T, ARGS...>(configs_[name], args...));
+}
+
 #endif  // _FTL_OPERATORS_OPERATOR_HPP_
diff --git a/components/operators/include/ftl/operators/opticalflow.hpp b/components/operators/include/ftl/operators/opticalflow.hpp
index e80160631e3cb3270d71da12a72e896231ebd0fd..43edf6b8440d311c0cfde052e6a9c1a6bf3b78b8 100644
--- a/components/operators/include/ftl/operators/opticalflow.hpp
+++ b/components/operators/include/ftl/operators/opticalflow.hpp
@@ -13,6 +13,7 @@ namespace operators {
 class NVOpticalFlow : public ftl::operators::Operator {
 	public:
 	explicit NVOpticalFlow(ftl::Configurable*);
+	NVOpticalFlow(ftl::Configurable*, const std::tuple<ftl::codecs::Channel,ftl::codecs::Channel> &channels);
 	~NVOpticalFlow();
 
 	inline Operator::Type type() const override { return Operator::Type::OneToOne; }
@@ -26,8 +27,8 @@ class NVOpticalFlow : public ftl::operators::Operator {
 	cv::Size size_;
 	
 	// TODO: Colour to Flow always assumed, could also calculate something else?
-	const ftl::codecs::Channel channel_in_ = ftl::codecs::Channel::Colour;
-	const ftl::codecs::Channel channel_out_ = ftl::codecs::Channel::Flow;
+	ftl::codecs::Channel channel_in_;
+	ftl::codecs::Channel channel_out_;
 
 	cv::Ptr<cv::cuda::NvidiaOpticalFlow_1_0> nvof_;
 	cv::cuda::GpuMat left_gray_;
diff --git a/components/operators/src/nvopticalflow.cpp b/components/operators/src/nvopticalflow.cpp
index 6ce98d757d076496077a13b5b0dc64f8e51560cb..08da949e00e727a3b5b76cc1fbe2fb73c3b4f210 100644
--- a/components/operators/src/nvopticalflow.cpp
+++ b/components/operators/src/nvopticalflow.cpp
@@ -10,10 +10,15 @@ using cv::Size;
 using cv::cuda::GpuMat;
 
 NVOpticalFlow::NVOpticalFlow(ftl::Configurable* cfg) :
-		ftl::operators::Operator(cfg) {
+		ftl::operators::Operator(cfg), channel_in_(ftl::codecs::Channel::Colour), channel_out_(ftl::codecs::Channel::Flow) {
 	size_ = Size(0, 0);
 }
 
+NVOpticalFlow::NVOpticalFlow(ftl::Configurable*cfg, const std::tuple<ftl::codecs::Channel,ftl::codecs::Channel> &channels) : ftl::operators::Operator(cfg) {
+	channel_in_ = std::get<0>(channels);
+	channel_out_ = std::get<1>(channels);
+}
+
 NVOpticalFlow::~NVOpticalFlow() {
 }
 
diff --git a/components/rgbd-sources/src/sources/stereovideo/stereovideo.cpp b/components/rgbd-sources/src/sources/stereovideo/stereovideo.cpp
index 3a0587ebb989ae8439212d3632e23333518a79c6..5847967700d31c2059163781ffda5641331d388c 100644
--- a/components/rgbd-sources/src/sources/stereovideo/stereovideo.cpp
+++ b/components/rgbd-sources/src/sources/stereovideo/stereovideo.cpp
@@ -76,7 +76,7 @@ void StereoVideoSource::init(const string &file) {
 
 	pipeline_input_ = ftl::config::create<ftl::operators::Graph>(host_, "input");
 	#ifdef HAVE_OPTFLOW
-	pipeline_input_->append<ftl::operators::NVOpticalFlow>("optflow");
+	pipeline_input_->append<ftl::operators::NVOpticalFlow>("optflow", Channel::Colour, Channel::Flow);
 	#endif
 
 	calib_ = ftl::create<Calibrate>(host_, "calibration", cv::Size(lsrc_->fullWidth(), lsrc_->fullHeight()), stream_);