Commit 9e9cbd4f authored by Michaël Roynard's avatar Michaël Roynard
Browse files

Migrate transform

parent 67fe3303
......@@ -299,11 +299,11 @@ void transform_baseline(const mln::image2d<mln::rgb8>& in, mln::image2d<mln::rgb
}
void transform(const mln::image2d<mln::uint8>& in, mln::image2d<mln::uint8>& out)
{
mln::experimental::transform(in, out, plus_one);
mln::transform(in, out, plus_one);
}
void transform(const mln::image2d<mln::rgb8>& in, mln::image2d<mln::rgb8>& out)
{
mln::experimental::transform(in, out, plus_one);
mln::transform(in, out, plus_one);
}
......
......@@ -398,7 +398,7 @@ BENCHMARK_F(BMAlgorithms, sort_points_buffer2d_large_int)(benchmark::State& st)
return res;
};
mln::image2d<int> tmp = mln::experimental::transform(m_input_rgb8, bit_mix);
mln::image2d<int> tmp = mln::transform(m_input_rgb8, bit_mix);
while (st.KeepRunning())
sort_points(tmp);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......
......@@ -28,121 +28,54 @@ namespace mln
/// \param input The input image.
/// \param f The unary function.
/// \param output The output image.
/// \see mln::imtransform
template <typename InputImage, typename OutputImage, class UnaryFunction>
[[deprecated]] OutputImage& transform(const Image<InputImage>& input, UnaryFunction f, Image<OutputImage>& output);
/// \overload
template <typename InputImage, typename OutputImage, class UnaryFunction>
[[deprecated]] OutputImage&& transform(const Image<InputImage>& input, UnaryFunction f, Image<OutputImage>&& output);
template <class InputImage, class OutputImage, class UnaryFunction>
void transform(InputImage in, const Image<OutputImage>& out, UnaryFunction f);
template <typename InputImage, class UnaryFunction>
[[deprecated]] unary_image_expr<UnaryFunction, InputImage> lazy_transform(InputImage&& input, UnaryFunction f);
/// \overload
template <typename InputImage, class UnaryFunction>
[[deprecated]] mln_ch_value(
InputImage, typename std::decay<typename std::result_of<UnaryFunction(mln_value(InputImage))>::type>::type)
transform(const Image<InputImage>& input, UnaryFunction f);
template <class InputImage, class UnaryFunction>
image_ch_value_t<InputImage, std::decay_t<std::invoke_result_t<UnaryFunction, image_reference_t<InputImage>>>>
transform(InputImage in, UnaryFunction f);
namespace experimental
{
template <class InputImage, class OutputImage, class UnaryFunction>
void transform(InputImage in, const Image<OutputImage>& out, UnaryFunction f);
template <class InputImage, class UnaryFunction>
image_ch_value_t<InputImage, std::decay_t<std::invoke_result_t<UnaryFunction, image_reference_t<InputImage>>>>
transform(InputImage in, UnaryFunction f);
} // namespace experimental
/******************************************/
/**** Implementation ****/
/******************************************/
namespace impl
{
template <typename I, typename J, class UnaryFunction>
void transform(const I& input, UnaryFunction f, J& output)
{
mln_viter(vin, vout, input, output);
mln_forall (vin, vout)
*vout = f(*vin);
}
} // namespace impl
template <typename InputImage, typename OutputImage, class UnaryFunction>
OutputImage& transform(const Image<InputImage>& input, UnaryFunction f, Image<OutputImage>& output)
template <class InputImage, class OutputImage, class UnaryFunction>
void transform(InputImage in, OutputImage out, UnaryFunction f)
{
OutputImage& out = exact(output);
static_assert(mln::is_a<InputImage, experimental::Image>());
static_assert(::ranges::Invocable<UnaryFunction, image_reference_t<InputImage>>());
static_assert(std::is_convertible_v<std::invoke_result_t<UnaryFunction, image_reference_t<InputImage>>,
image_value_t<OutputImage>>,
"The result of the function is not implicitely convertible to the output image value type");
mln_entering("mln::transform");
impl::transform(exact(input), f, exact(output));
mln_exiting();
return out;
}
mln_precondition(in.domain() == out.domain());
template <typename InputImage, typename OutputImage, class UnaryFunction>
OutputImage&& transform(const Image<InputImage>& input, UnaryFunction f, Image<OutputImage>&& output)
{
mln::transform(input, f, output);
return move_exact(output);
auto&& ivals = in.new_values();
auto&& ovals = out.new_values();
for (auto [r1, r2] : ranges::view::zip(ranges::rows(ivals), ranges::rows(ovals)))
::ranges::transform(r1, ::ranges::begin(r2), f);
}
template <typename InputImage, class UnaryFunction>
mln_ch_value(InputImage,
typename std::decay<typename std::result_of<UnaryFunction(mln_value(InputImage))>::type>::type)
transform(const Image<InputImage>& input, UnaryFunction f)
template <class InputImage, class UnaryFunction>
image_ch_value_t<InputImage, std::decay_t<std::invoke_result_t<UnaryFunction, image_reference_t<InputImage>>>>
transform(InputImage in, UnaryFunction f)
{
typedef typename std::decay<typename std::result_of<UnaryFunction(mln_value(InputImage))>::type>::type T;
static_assert(mln::is_a<InputImage, experimental::Image>());
static_assert(::ranges::Invocable<UnaryFunction, image_reference_t<InputImage>>());
mln_ch_value(InputImage, T) out = imchvalue<T>(exact(input));
mln::transform(input, f, out);
return out;
}
using R = std::decay_t<std::invoke_result_t<UnaryFunction, image_reference_t<InputImage>>>;
using O = image_ch_value_t<InputImage, R>;
template <typename InputImage, class UnaryFunction>
unary_image_expr<UnaryFunction, InputImage> lazy_transform(InputImage&& input, UnaryFunction f)
{
return make_unary_image_expr(std::forward<InputImage>(input), f);
// Check concretizable
O out = in.template ch_value<R>();
mln::transform(in, out, f);
return out;
}
namespace experimental
{
template <class InputImage, class OutputImage, class UnaryFunction>
void transform(InputImage in, OutputImage out, UnaryFunction f)
{
static_assert(mln::is_a<InputImage, Image>());
static_assert(::ranges::Invocable<UnaryFunction, image_reference_t<InputImage>>());
static_assert(std::is_convertible_v<std::invoke_result_t<UnaryFunction, image_reference_t<InputImage>>,
image_value_t<OutputImage>>,
"The result of the function is not implicitely convertible to the output image value type");
mln_entering("mln::experimental::transform");
mln_precondition(in.domain() == out.domain());
auto&& ivals = in.new_values();
auto&& ovals = out.new_values();
for (auto [r1, r2] : ranges::view::zip(ranges::rows(ivals), ranges::rows(ovals)))
::ranges::transform(r1, ::ranges::begin(r2), f);
}
template <class InputImage, class UnaryFunction>
image_ch_value_t<InputImage, std::decay_t<std::invoke_result_t<UnaryFunction, image_reference_t<InputImage>>>>
transform(InputImage in, UnaryFunction f)
{
static_assert(mln::is_a<InputImage, Image>());
static_assert(::ranges::Invocable<UnaryFunction, image_reference_t<InputImage>>());
using R = std::decay_t<std::invoke_result_t<UnaryFunction, image_reference_t<InputImage>>>;
using O = image_ch_value_t<InputImage, R>;
// Check concretizable
O out = in.template ch_value<R>();
mln::experimental::transform(in, out, f);
return out;
}
} // namespace experimental
} // namespace mln
......@@ -75,8 +75,9 @@ namespace mln
double x = (not std::is_floating_point<V>::value) ? (double)value_traits<V>::min() : 0.0;
double y = (not std::is_floating_point<V>::value) ? (double)value_traits<V>::max() : 1.0;
double r = (y - x) / (M - m);
mln_ch_value(I, V) out = transform(f, [m, x, r](mln_value(I) v) -> V { return static_cast<V>(x + (v - m) * r); });
double r = (y - x) / (M - m);
mln_ch_value(I, V) out =
transform(ima_f, [m, x, r](mln_value(I) v) -> V { return static_cast<V>(x + (v - m) * r); });
mln_exiting();
return out;
......
......@@ -11,6 +11,36 @@
/// \file
// FIXME:
namespace impl
{
template <typename I, typename J, class UnaryFunction>
void transform(const I& input, UnaryFunction f, J& output)
{
mln_viter(vin, vout, input, output);
mln_forall (vin, vout)
*vout = f(*vin);
}
} // namespace impl
template <typename InputImage, typename OutputImage, class UnaryFunction>
OutputImage& __transform(const mln::Image<InputImage>& input, UnaryFunction f, mln::Image<OutputImage>& output)
{
OutputImage& out = exact(output);
mln_entering("mln::transform");
impl::transform(exact(input), f, exact(output));
mln_exiting();
return out;
}
template <typename InputImage, typename OutputImage, class UnaryFunction>
OutputImage&& __transform(const mln::Image<InputImage>& input, UnaryFunction f, mln::Image<OutputImage>&& output)
{
__transform(input, f, output);
return move_exact(output);
}
namespace mln
{
......@@ -131,7 +161,8 @@ namespace mln
auto d = morpho::structural::dilate(ima, nbh, cmp);
auto e = morpho::structural::erode(ima, nbh, cmp);
mln::transform(d - e, norm, out);
// FIXME:
__transform(d - e, norm, out);
}
// Version non-fast dilate - erode
......
......@@ -15,7 +15,7 @@ TEST(Core, Algorithm_Transform)
mln::image2d<uint8_t> ref = {{2, 3, 4}, {5, 6, 7}};
auto out = mln::experimental::transform(ima, [](uint8_t x) -> uint8_t { return x + 1; });
auto out = mln::transform(ima, [](uint8_t x) -> uint8_t { return x + 1; });
ASSERT_TRUE(mln::all_of(out == ref));
}
......@@ -30,6 +30,6 @@ TEST(Core, Algorithm_Transform_LValue)
mln::image2d<uint8_t> ref = {{1, 2, 3}, {4, 5, 6}};
mln::image2d<uint8_t> out = mln::experimental::transform(ima, &V::first);
mln::image2d<uint8_t> out = mln::transform(ima, &V::first);
ASSERT_TRUE(mln::all_of(out == ref));
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment