>>662
>image-processing related
cv::Mat tr_apply_mask(const cv::Mat& img_main, const cv::Mat& img_mask);
cv::Mat tr_blur(const cv::Mat& src, int size);
cv::Mat tr_to_grayscale(const cv::Mat& src);
cv::Mat tr_adaptthresh(const cv::Mat& img, int block_size, int diff);
cv::Mat tr_reducecolors(const cv::Mat& img, int num_colors) cv::Mat
    tr_oilpainting(const cv::Mat& img, int size, int dyn_ratio);
auto tr_cartoonify(const cv::Mat& src, int blur_size, int num_colors,
                   int block_size, int diff);
auto error_to_exception();
std::vector<std::byte> read_file(const fs::directory_entry& file);
void write_file(const char* filename, const std::vector<unsigned char>& data);
exec::task<int> process_files(const char* in_folder_name,
                              const char* out_folder_name, int blur_size,
                              int num_colors, int block_size, int diff);
int main()
{
  auto everything =
      process_files("data", "out", blur_size, num_colors, block_size, diff);
  auto [processed] = stdexec::sync_wait(std::move(everything)).value();
  printf("Processed images: %d\n", processed);
  return 0;
}
auto tr_cartoonify(const cv::Mat& src, int blur_size, int num_colors,
                   int block_size, int diff)
{
  auto                 sched = exec::get_system_scheduler();
  stdexec::sender auto snd =
      stdexec::when_all(
          stdexec::transfer_just(sched, src) | error_to_exception() |
              stdexec::then([=](const cv::Mat& src) {
                auto blurred = tr_blur(src, blur_size);
                auto gray    = tr_to_grayscale(blurred);
                return tr_adaptthresh(gray, block_size, diff);
              }),
          stdexec::transfer_just(sched, src) | error_to_exception() |
              stdexec::then([=](const cv::Mat& src) {
                return tr_reducecolors(src, num_colors);
              })) |
      stdexec::then([](const cv::Mat& edges, const cv::Mat& reduced_colors) {
        return tr_apply_mask(reduced_colors, edges);
      });
  return snd;
}
auto error_to_exception()
{
  return stdexec::let_error([](auto e) {
    if constexpr (std::same_as<decltype((e)), std::exception_ptr>)
      return stdexec::just_error(e);
    else
      return stdexec::just_error(
          std::make_exception_ptr(std::runtime_error("other error")));
  });
}
exec::task<int> process_files(const char* in_folder_name,
                              const char* out_folder_name, int blur_size,
                              int num_colors, int block_size, int diff)
{
  exec::async_scope        scope;
  exec::static_thread_pool io_pool(1);
  auto                     io_sched  = io_pool.get_scheduler();
  auto                     cpu_sched = exec::get_system_scheduler();
  int                      processed = 0;
  for (const auto& entry : fs::directory_iterator(in_folder_name)) {
    auto extension = entry.path().extension();
    if (! entry.is_regular_file() ||
        (extension != ".jpg") && (extension != ".jpeg"))
      continue;
    auto in_filename = entry.path().string();
    auto out_filename =
        (fs::path(out_folder_name) / entry.path().filename()).string();
    printf(“Processing % s\n”, in_filename.c_str());
    auto file_content =
        co_await (stdexec::schedule(io_sched) |
                  stdexec::then([=] { return read_file(entry); }));
    stdexec::sender auto work = ... scope.spawn(std::move(work));
  }
  co_await scope.on_empty();
  co_return processed;
}
stdexec::sender auto work =
    stdexec::transfer_just(cpu_sched, cv::_InputArray::rawIn(file_content)) |
    error_to_exception() |
    stdexec::then([=](cv::InputArray file_content) -> cv::Mat {
      return cv::imdecode(file_content, cv::IMREAD_COLOR);
    }) |
    stdexec::let_value([=](const cv::Mat& img) {
      return tr_cartoonify(img, blur_size, num_colors, block_size, diff);
    }) |
    stdexec::then([=](const cv::Mat& img) {
      std::vector<unsigned char> out_image_content;
      if (! cv::imencode(extension, img, out_image_content)) {
        throw std::runtime_error("cannot encode image");
      }
      return out_image_content;
    }) |
    stdexec::continues_on(io_sched) |
    stdexec::then([=](const std::vector<unsigned char>& bytes) {
      write_file(out_filename.c_str(), bytes);
    }) |
    stdexec::then([=] { printf("Written %s\n", out_filename.c_str()); }) |
    stdexec::then([&] { processed++; });
 Last edited  by chobitsu