>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++; });
Edited last time by Chobitsu on 04/22/2025 (Tue) 14:20:24.