BMAlgorithms.cpp 10.9 KB
Newer Older
Edwin Carlinet's avatar
Edwin Carlinet committed
1
#include <mln/core/algorithm/accumulate.hpp>
2
3
4
5
6
#include <mln/core/algorithm/copy.hpp>
#include <mln/core/algorithm/count.hpp>
#include <mln/core/algorithm/count_if.hpp>
#include <mln/core/algorithm/equal.hpp>
#include <mln/core/algorithm/fill.hpp>
Edwin Carlinet's avatar
Edwin Carlinet committed
7
#include <mln/core/algorithm/for_each.hpp>
8
9
#include <mln/core/algorithm/generate.hpp>
#include <mln/core/algorithm/paste.hpp>
Edwin Carlinet's avatar
Edwin Carlinet committed
10
#include <mln/core/algorithm/sort.hpp>
11
12
#include <mln/core/algorithm/transform.hpp>
#include <mln/core/colors.hpp>
13
#include <mln/core/image/experimental/ndimage.hpp>
14

Edwin Carlinet's avatar
Edwin Carlinet committed
15
16
17
#include <algorithm>
#include <numeric>

18

Edwin Carlinet's avatar
Edwin Carlinet committed
19
20
21
22
namespace baseline
{

  template <class V>
23
  void fill(mln::experimental::image2d<V>& ima, V value)
Edwin Carlinet's avatar
Edwin Carlinet committed
24
  {
25
26
27
28
    std::ptrdiff_t stride = ima.stride();
    V*             buffer = ima.buffer();
    int            height = ima.height();
    int            width  = ima.width();
Edwin Carlinet's avatar
Edwin Carlinet committed
29

30
    for (int i = 0; i < height; ++i, buffer += stride)
Edwin Carlinet's avatar
Edwin Carlinet committed
31
32
33
34
      std::fill(buffer, buffer + width, value);
  }

  template <class V>
35
  void copy(const mln::experimental::image2d<V>& in, mln::experimental::image2d<V>& out)
Edwin Carlinet's avatar
Edwin Carlinet committed
36
  {
37
38
39
40
41
42
    std::ptrdiff_t istride = in.stride();
    std::ptrdiff_t ostride = out.stride();
    const V*       ibuffer = in.buffer();
    V*             obuffer = out.buffer();
    int            height  = in.height();
    int            width   = in.width();
Edwin Carlinet's avatar
Edwin Carlinet committed
43

44
45
    assert(out.height() == height);
    assert(out.width() == width);
Edwin Carlinet's avatar
Edwin Carlinet committed
46

47
    for (int i = 0; i < height; ++i, ibuffer += istride, obuffer += ostride)
Edwin Carlinet's avatar
Edwin Carlinet committed
48
49
50
      std::copy(ibuffer, ibuffer + width, obuffer);
  }

51
  template <class V, class F>
52
  std::ptrdiff_t count_if(const mln::experimental::image2d<V>& in, F f)
53
  {
54
55
56
57
    std::ptrdiff_t istride = in.stride();
    const V*       ibuffer = in.buffer();
    int            height  = in.height();
    int            width   = in.width();
58
59

    std::ptrdiff_t k = 0;
60
    for (int i = 0; i < height; ++i, ibuffer += istride)
61
62
63
64
65
66
      k += std::count_if(ibuffer, ibuffer + width, f);

    return k;
  }

  template <class V>
67
  std::ptrdiff_t count(const mln::experimental::image2d<V>& in, V v)
68
  {
69
70
71
72
    std::ptrdiff_t istride = in.stride();
    const V*       ibuffer = in.buffer();
    int            height  = in.height();
    int            width   = in.width();
73
74

    std::ptrdiff_t k = 0;
75
    for (int i = 0; i < height; ++i, ibuffer += istride)
76
77
78
79
80
81
      k += std::count(ibuffer, ibuffer + width, v);

    return k;
  }

  template <class V>
82
  bool equal(const mln::experimental::image2d<V>& lhs, const mln::experimental::image2d<V>& rhs)
83
  {
84
85
86
87
88
89
90
91
    std::ptrdiff_t lhs_stride = lhs.stride();
    std::ptrdiff_t rhs_stride = rhs.stride();
    const V*       lhs_buffer = lhs.buffer();
    const V*       rhs_buffer = rhs.buffer();
    int            height     = lhs.height();
    int            width      = lhs.width();

    for (int i = 0; i < height; ++i, lhs_buffer += lhs_stride, rhs_buffer += rhs_stride)
92
93
94
95
96
      if (!std::equal(lhs_buffer, lhs_buffer + width, rhs_buffer))
        return false;

    return true;
  }
Edwin Carlinet's avatar
Edwin Carlinet committed
97
98

  template <class V>
99
  void paste(const mln::experimental::image2d<V>& in, mln::experimental::image2d<V>& out)
Edwin Carlinet's avatar
Edwin Carlinet committed
100
  {
101
102
103
104
105
106
    std::ptrdiff_t istride = in.stride();
    std::ptrdiff_t ostride = out.stride();
    const V*       ibuffer = in.buffer();
    V*             obuffer = out.buffer();
    int            height  = in.height();
    int            width   = in.width();
Edwin Carlinet's avatar
Edwin Carlinet committed
107

108
109
    assert(out.height() == height);
    assert(out.width() == width);
Edwin Carlinet's avatar
Edwin Carlinet committed
110

111
    for (int i = 0; i < height; ++i, ibuffer += istride, obuffer += ostride)
Edwin Carlinet's avatar
Edwin Carlinet committed
112
113
114
115
      std::copy(ibuffer, ibuffer + width, obuffer);
  }

  template <class F, class U, class V>
116
  void transform(const mln::experimental::image2d<U>& in, mln::experimental::image2d<V>& out, F f)
Edwin Carlinet's avatar
Edwin Carlinet committed
117
  {
118
119
120
121
122
123
    std::ptrdiff_t istride = in.stride();
    std::ptrdiff_t ostride = out.stride();
    const U*       ibuffer = in.buffer();
    V*             obuffer = out.buffer();
    int            height  = in.height();
    int            width   = in.width();
Edwin Carlinet's avatar
Edwin Carlinet committed
124

125
126
    assert(out.height() == height);
    assert(out.width() == width);
Edwin Carlinet's avatar
Edwin Carlinet committed
127

128
    for (int i = 0; i < height; ++i, ibuffer += istride, obuffer += ostride)
Edwin Carlinet's avatar
Edwin Carlinet committed
129
130
131
132
      std::transform(ibuffer, ibuffer + width, obuffer, f);
  }

  template <class F, class U>
133
  void for_each(mln::experimental::image2d<U>& in, F f)
Edwin Carlinet's avatar
Edwin Carlinet committed
134
  {
135
136
137
138
    std::ptrdiff_t istride = in.stride();
    U*             ibuffer = in.buffer();
    int            height  = in.height();
    int            width   = in.width();
Edwin Carlinet's avatar
Edwin Carlinet committed
139

140
    for (int i = 0; i < height; ++i, ibuffer += istride)
Edwin Carlinet's avatar
Edwin Carlinet committed
141
142
143
144
      std::for_each(ibuffer, ibuffer + width, f);
  }

  template <class V, class Generator>
145
  void generate(mln::experimental::image2d<V>& ima, Generator g)
Edwin Carlinet's avatar
Edwin Carlinet committed
146
  {
147
148
149
150
    std::ptrdiff_t stride = ima.stride();
    V*             buffer = ima.buffer();
    int            height = ima.height();
    int            width  = ima.width();
Edwin Carlinet's avatar
Edwin Carlinet committed
151

152
    for (int i = 0; i < height; ++i, buffer += stride)
Edwin Carlinet's avatar
Edwin Carlinet committed
153
154
155
156
      std::generate(buffer, buffer + width, g);
  }

  template <class U, class V, class BinaryOperator>
157
  V accumulate(const mln::experimental::image2d<U>& ima, V init, BinaryOperator op)
Edwin Carlinet's avatar
Edwin Carlinet committed
158
  {
159
160
161
162
    std::ptrdiff_t stride = ima.stride();
    const U*       buffer = ima.buffer();
    int            height = ima.height();
    int            width  = ima.width();
Edwin Carlinet's avatar
Edwin Carlinet committed
163

164
    for (int i = 0; i < height; ++i, buffer += stride)
Edwin Carlinet's avatar
Edwin Carlinet committed
165
166
167
168
      init = op(init, std::accumulate(buffer, buffer + width, init, op));

    return init;
  }
169
170
} // namespace baseline

Edwin Carlinet's avatar
Edwin Carlinet committed
171

172
void fill_baseline(mln::experimental::image2d<uint8_t>& ima, uint8_t v)
173
174
175
{
  baseline::fill(ima, v);
}
176
void fill_baseline(mln::experimental::image2d<mln::rgb8>& ima, mln::rgb8 v)
177
178
179
{
  baseline::fill(ima, v);
}
180
void fill(mln::experimental::image2d<uint8_t>& ima, uint8_t v)
181
{
182
  mln::fill(ima, v);
183
}
184
void fill(mln::experimental::image2d<mln::rgb8>& ima, mln::rgb8 v)
185
{
186
  mln::fill(ima, v);
187
}
Edwin Carlinet's avatar
Edwin Carlinet committed
188
189


190
void copy_baseline(const mln::experimental::image2d<uint8_t>& in, mln::experimental::image2d<uint8_t>& out)
191
192
193
{
  baseline::copy(in, out);
}
194
void copy_baseline(const mln::experimental::image2d<mln::rgb8>& in, mln::experimental::image2d<mln::rgb8>& out)
195
196
197
{
  baseline::copy(in, out);
}
198
void copy(const mln::experimental::image2d<uint8_t>& in, mln::experimental::image2d<uint8_t>& out)
199
200
201
{
  mln::experimental::copy(in, out);
}
202
void copy(const mln::experimental::image2d<mln::rgb8>& in, mln::experimental::image2d<mln::rgb8>& out)
203
204
205
{
  mln::experimental::copy(in, out);
}
Edwin Carlinet's avatar
Edwin Carlinet committed
206
207
208
209


namespace
{
210
  static auto is_uint8_15   = [](uint8_t v) { return v == 15; };
211
212
213
  static auto is_rgb8_black = [](mln::rgb8 v) { return v == mln::rgb8{0, 0, 0}; };
} // namespace

214
std::ptrdiff_t count_if_baseline(const mln::experimental::image2d<uint8_t>& in)
215
216
217
{
  return baseline::count_if(in, is_uint8_15);
}
218
std::ptrdiff_t count_if_baseline(const mln::experimental::image2d<mln::rgb8>& in)
219
220
221
{
  return baseline::count_if(in, is_rgb8_black);
}
222
std::ptrdiff_t count_if(const mln::experimental::image2d<uint8_t>& in)
223
{
224
  return mln::count_if(in, is_uint8_15);
225
}
226
std::ptrdiff_t count_if(const mln::experimental::image2d<mln::rgb8>& in)
227
{
228
  return mln::count_if(in, is_rgb8_black);
Edwin Carlinet's avatar
Edwin Carlinet committed
229
230
231
}


232
std::ptrdiff_t count_baseline(const mln::experimental::image2d<uint8_t>& in)
233
{
234
  return baseline::count(in, uint8_t(15));
235
}
236
std::ptrdiff_t count_baseline(const mln::experimental::image2d<mln::rgb8>& in)
237
238
239
{
  return baseline::count(in, mln::rgb8{0, 0, 0});
}
240
std::ptrdiff_t count(const mln::experimental::image2d<uint8_t>& in)
241
{
242
  return mln::count(in, uint8_t(15));
243
}
244
std::ptrdiff_t count(const mln::experimental::image2d<mln::rgb8>& in)
245
{
246
  return mln::count(in, mln::rgb8{0, 0, 0});
247
}
Edwin Carlinet's avatar
Edwin Carlinet committed
248
249


250
bool equal_baseline(const mln::experimental::image2d<uint8_t>& lhs, const mln::experimental::image2d<uint8_t>& rhs)
251
252
253
{
  return baseline::equal(lhs, rhs);
}
254
bool equal_baseline(const mln::experimental::image2d<mln::rgb8>& lhs, const mln::experimental::image2d<mln::rgb8>& rhs)
255
256
257
{
  return baseline::equal(lhs, rhs);
}
258
bool equal(const mln::experimental::image2d<uint8_t>& lhs, const mln::experimental::image2d<uint8_t>& rhs)
259
{
260
  return mln::equal(lhs, rhs);
261
}
262
bool equal(const mln::experimental::image2d<mln::rgb8>& lhs, const mln::experimental::image2d<mln::rgb8>& rhs)
263
{
264
  return mln::equal(lhs, rhs);
265
266
267
}


268
void paste_baseline(const mln::experimental::image2d<uint8_t>& in, mln::experimental::image2d<uint8_t>& out)
269
270
271
{
  baseline::paste(in, out);
}
272
void paste_baseline(const mln::experimental::image2d<mln::rgb8>& in, mln::experimental::image2d<mln::rgb8>& out)
273
274
275
{
  baseline::paste(in, out);
}
276
void paste(const mln::experimental::image2d<uint8_t>& in, mln::experimental::image2d<uint8_t>& out)
277
{
278
  mln::paste(in, out);
279
}
280
void paste(const mln::experimental::image2d<mln::rgb8>& in, mln::experimental::image2d<mln::rgb8>& out)
281
{
282
  mln::paste(in, out);
283
}
Edwin Carlinet's avatar
Edwin Carlinet committed
284
285
286
287


namespace
{
288
289
290
291
  static auto plus_one         = [](auto x) -> decltype(x) { return x + 1; };
  static auto plus_one_inplace = [](auto& x) { x += 1; };
} // namespace

292
void transform_baseline(const mln::experimental::image2d<uint8_t>& in, mln::experimental::image2d<uint8_t>& out)
293
294
295
{
  baseline::transform(in, out, plus_one);
}
296
void transform_baseline(const mln::experimental::image2d<mln::rgb8>& in, mln::experimental::image2d<mln::rgb8>& out)
297
298
299
{
  baseline::transform(in, out, plus_one);
}
300
void transform(const mln::experimental::image2d<uint8_t>& in, mln::experimental::image2d<uint8_t>& out)
301
{
302
  mln::transform(in, out, plus_one);
303
}
304
void transform(const mln::experimental::image2d<mln::rgb8>& in, mln::experimental::image2d<mln::rgb8>& out)
305
{
306
  mln::transform(in, out, plus_one);
Edwin Carlinet's avatar
Edwin Carlinet committed
307
308
309
}


310
void for_each_baseline(mln::experimental::image2d<uint8_t>& in)
311
312
313
{
  baseline::for_each(in, plus_one_inplace);
}
314
void for_each_baseline(mln::experimental::image2d<mln::rgb8>& in)
315
316
317
{
  baseline::for_each(in, plus_one_inplace);
}
318
void for_each(mln::experimental::image2d<uint8_t>& in)
319
{
320
  mln::for_each(in, plus_one_inplace);
321
}
322
void for_each(mln::experimental::image2d<mln::rgb8>& in)
323
{
324
  mln::for_each(in, plus_one_inplace);
325
}
Edwin Carlinet's avatar
Edwin Carlinet committed
326
327


328
329
330
331
332
333
namespace
{
  static int  cpt            = 0;
  static auto iota_generator = []() -> int { return cpt++; };
} // namespace

Edwin Carlinet's avatar
Edwin Carlinet committed
334

335
void generate_baseline(mln::experimental::image2d<uint8_t>& ima)
336
337
338
{
  baseline::generate(ima, iota_generator);
}
339
void generate(mln::experimental::image2d<uint8_t>& ima)
340
{
341
  mln::generate(ima, iota_generator);
342
}
Edwin Carlinet's avatar
Edwin Carlinet committed
343
344


345
346
#include <mln/accu/accumulators/sum.hpp>

347
int accumulate_baseline(const mln::experimental::image2d<uint8_t>& ima)
348
349
350
{
  return baseline::accumulate(ima, 0, std::plus<>{});
}
351
int accumulate(const mln::experimental::image2d<uint8_t>& ima)
352
{
353
  return mln::accumulate(ima, 0, std::plus<>{});
354
}
355
int accumulate_accu(const mln::experimental::image2d<uint8_t>& ima)
356
{
357
  return mln::accumulate(ima, mln::accu::features::sum<int>());
358
}
Edwin Carlinet's avatar
Edwin Carlinet committed
359

360
using point_t = mln::image_point_t<mln::experimental::image2d<uint8_t>>;
Edwin Carlinet's avatar
Edwin Carlinet committed
361

362
std::vector<point_t> sort_points(const mln::experimental::image2d<uint8_t>& ima)
363
364
365
{
  return mln::experimental::sort_points(ima);
}
366
std::vector<point_t> sort_points(const mln::experimental::image2d<int>& ima)
367
368
369
{
  return mln::experimental::sort_points(ima);
}
370
std::vector<point_t> sort_points(const mln::experimental::image2d<mln::rgb8>& ima)
371
372
373
{
  return mln::experimental::sort_points(ima, mln::lexicographicalorder_less<mln::rgb8>());
}