include/cvw/pipeline.hpp
Pipeline composition via step factories and operator| chaining. More...
Namespaces
| Name |
|---|
| cvw |
| cvw::steps Namespace containing step factory functions for pipeline composition. |
| cvw::pipe_ops Namespace containing operator |
| cvw::detail Internal validation helpers used by algorithm implementations. |
Detailed Description
Pipeline composition via step factories and operator| chaining.
Author: Charliechen114514
Version: 1.0.0
Since: 1.0.0
Date: 2026-05-15
Provides three layers of pipeline support:
- steps:😗 — factory functions returning callable step objects.
- pipe_ops — operator| overloads for chaining steps with short-circuit.
- make_pipeline — composes multiple steps into a reusable callable.
Source code
cpp
#pragma once
#include "algorithms.hpp"
namespace cvw {
// ═══════════════════════════════════════════════════════════════
// steps — Factory functions returning callable step objects
// ═══════════════════════════════════════════════════════════════
namespace steps {
// ── Geometric steps ──────────────────────────────────────────
[[nodiscard]] inline auto resize(int width, int height,
int interpolation = cv::INTER_LINEAR) {
return [=](auto img) -> expected<decltype(img), AlgorithmError> {
return cvw::resize(std::move(img), width, height, interpolation);
};
}
[[nodiscard]] inline auto flip(int axis) {
return [=](auto img) -> expected<decltype(img), AlgorithmError> {
return cvw::flip(std::move(img), axis);
};
}
[[nodiscard]] inline auto rotate(double angle, bool expand = false) {
return [=](auto img) -> expected<decltype(img), AlgorithmError> {
return cvw::rotate(std::move(img), angle, expand);
};
}
// ── Color conversion steps ───────────────────────────────────
[[nodiscard]] inline auto to_gray() {
return [](Image<BGR> img) -> expected<Image<Gray>, AlgorithmError> {
return cvw::to_gray(std::move(img));
};
}
[[nodiscard]] inline auto to_gray_rgb() {
return [](Image<RGB> img) -> expected<Image<Gray>, AlgorithmError> {
return cvw::to_gray(std::move(img));
};
}
[[nodiscard]] inline auto to_bgr() {
return [](Image<Gray> img) -> expected<Image<BGR>, AlgorithmError> {
return cvw::to_bgr(std::move(img));
};
}
[[nodiscard]] inline auto yuyv_to_gray() {
return [](ImageView<YUYV> view) -> expected<Image<Gray>, AlgorithmError> {
return cvw::yuyv_to_gray(view);
};
}
// ── Filter steps ─────────────────────────────────────────────
[[nodiscard]] inline auto gaussian_blur(int kernel_size, double sigma = 0.0) {
return [=](auto img) -> expected<decltype(img), AlgorithmError> {
return cvw::gaussian_blur(std::move(img), kernel_size, sigma);
};
}
template <is_pixel_format F>
requires(F::channels == 1)
[[nodiscard]] inline auto median_blur(int kernel_size) {
return [=](Image<F> img) -> expected<Image<F>, AlgorithmError> {
return cvw::median_blur(std::move(img), kernel_size);
};
}
// ── Edge & threshold steps ───────────────────────────────────
[[nodiscard]] inline auto canny(double lo, double hi, int aperture = 3) {
return [=](Image<Gray> img) -> expected<Image<Gray>, AlgorithmError> {
return cvw::canny(std::move(img), lo, hi, aperture);
};
}
[[nodiscard]] inline auto sobel(int dx, int dy, int kernel_size = 3) {
return [=](Image<Gray> img) -> expected<Image<Float1>, AlgorithmError> {
return cvw::sobel(std::move(img), dx, dy, kernel_size);
};
}
[[nodiscard]] inline auto threshold(double thresh, double max_val,
int type = cv::THRESH_BINARY) {
return [=](Image<Gray> img) -> expected<Image<Gray>, AlgorithmError> {
return cvw::threshold(std::move(img), thresh, max_val, type);
};
}
[[nodiscard]] inline auto
adaptive_threshold(int block_size, double C,
int method = cv::ADAPTIVE_THRESH_GAUSSIAN_C) {
return [=](Image<Gray> img) -> expected<Image<Gray>, AlgorithmError> {
return cvw::adaptive_threshold(std::move(img), block_size, C, method);
};
}
// ── Normalization step ───────────────────────────────────────
[[nodiscard]] inline auto normalize(float min_val = 0.0f,
float max_val = 1.0f) {
return [=](Image<Gray> img) -> expected<Image<Float1>, AlgorithmError> {
return cvw::normalize(std::move(img), min_val, max_val);
};
}
// ── Sink step ────────────────────────────────────────────────
[[nodiscard]] inline auto save(std::string path) {
return [=](const auto& img) -> expected<void, AlgorithmError> {
return cvw::save(img, path);
};
}
} // namespace steps
// ═══════════════════════════════════════════════════════════════
// pipe_ops — operator| overloads for step chaining (opt-in)
// ═══════════════════════════════════════════════════════════════
namespace pipe_ops {
template <is_pixel_format F, typename Step>
auto operator|(Image<F> img, Step&& step) -> decltype(step(std::move(img))) {
return std::forward<Step>(step)(std::move(img));
}
template <is_pixel_format F, typename Step>
auto operator|(expected<Image<F>, AlgorithmError> input, Step&& step)
-> decltype(step(std::move(*input))) {
if (!input) {
return decltype(step(std::move(*input)))(unexpected(input.error()));
}
return std::forward<Step>(step)(std::move(*input));
}
template <typename Step>
auto operator|(expected<void, AlgorithmError> input, Step&& step)
-> decltype(std::forward<Step>(step)()) {
if (!input) {
return decltype(std::forward<Step>(step)())(unexpected(input.error()));
}
return std::forward<Step>(step)();
}
} // namespace pipe_ops
// ═══════════════════════════════════════════════════════════════
// make_pipeline — Composes multiple steps into a reusable callable
// ═══════════════════════════════════════════════════════════════
namespace detail {
inline auto make_pipeline_impl() {
return [](auto input) {
return expected<decltype(input), AlgorithmError>(std::move(input));
};
}
template <typename First, typename... Rest>
auto make_pipeline_impl(First&& first, Rest&&... rest) {
auto tail = make_pipeline_impl(std::forward<Rest>(rest)...);
return [first = std::forward<First>(first),
tail = std::move(tail)](auto input) mutable {
return first(std::move(input)).and_then([&tail](auto next) {
return tail(std::move(next));
});
};
}
} // namespace detail
template <typename... Steps>
[[nodiscard]] auto make_pipeline(Steps&&... steps) {
return detail::make_pipeline_impl(std::forward<Steps>(steps)...);
}
} // namespace cvwUpdated on 2026-05-17 at 13:22:38 +0000