@@ -360,8 +360,8 @@ Returns:
360
360
where с is the number of channels in the image.
361
361
Dense data layout is guaranteed.
362
362
+/
363
- Slice!(ubyte *, 3) movingWindowByChannel
364
- (Slice!(Universal, [3], ubyte* ) image, size_t nr, size_t nc, ubyte delegate(Slice!(Universal, [2], ubyte*)) filter )
363
+ Slice!(C *, 3) movingWindowByChannel(alias filter, C)
364
+ (Slice!(C*, 3, Universal ) image, size_t nr, size_t nc)
365
365
{
366
366
// 0. 3D
367
367
// The last dimension represents the color channel.
@@ -374,10 +374,12 @@ Slice!(ubyte*, 3) movingWindowByChannel
374
374
.windows(nr, nc)
375
375
// 3. 5D
376
376
// Unpacks the windows.
377
- .unpack
378
- .transposed!(0, 1, 4)
377
+ .unpack.unpack
379
378
// 4. 5D
380
379
// Brings the color channel dimension to the third position.
380
+ .transposed!(0, 1, 4)
381
+ // 5. 3D Composed of 2D
382
+ // Packs the last two dimensions.
381
383
.pack!2
382
384
// 2D to pixel lazy conversion.
383
385
.map!filter
@@ -397,12 +399,15 @@ Params:
397
399
Returns:
398
400
median value over the range `r`
399
401
+/
400
- T median(Range, T)(Slice!(Universal, [2], Range ) sl, T[] buf)
402
+ T median(Iterator, SliceKind kind, T)(Slice!(Iterator, 2, kind ) sl, T[] buf)
401
403
{
402
404
import std.algorithm.sorting : topN;
403
405
// copy sl to the buffer
404
406
auto retPtr = reduce!(
405
- (ptr, elem) { *ptr = elem; return ptr + 1;} )(buf.ptr, sl);
407
+ (ptr, elem) {
408
+ *ptr = elem;
409
+ return ptr + 1;
410
+ } )(buf.ptr, sl);
406
411
auto n = retPtr - buf.ptr;
407
412
buf[0 .. n].topN(n / 2);
408
413
return buf[n / 2];
@@ -414,9 +419,9 @@ The `main` function:
414
419
-------
415
420
void main(string[] args)
416
421
{
417
- import std.conv : to;
418
- import std.getopt : getopt, defaultGetoptPrinter;
419
- import std.path : stripExtension;
422
+ import std.conv: to;
423
+ import std.getopt: getopt, defaultGetoptPrinter;
424
+ import std.path: stripExtension;
420
425
421
426
uint nr, nc, def = 3;
422
427
auto helpInformation = args.getopt(
@@ -434,6 +439,12 @@ void main(string[] args)
434
439
435
440
auto buf = new ubyte[nr * nc];
436
441
442
+ if (args.length == 1)
443
+ {
444
+ import std.stdio: writeln;
445
+ writeln("No input file given");
446
+ }
447
+
437
448
foreach (name; args[1 .. $])
438
449
{
439
450
import imageformats; // can be found at code.dlang.org
@@ -442,6 +453,7 @@ void main(string[] args)
442
453
443
454
auto ret = image.pixels
444
455
.sliced(cast(size_t)image.h, cast(size_t)image.w, cast(size_t)image.c)
456
+ .universal
445
457
.movingWindowByChannel
446
458
!(window => median(window, buf))
447
459
(nr, nc);
@@ -450,7 +462,7 @@ void main(string[] args)
450
462
name.stripExtension ~ "_filtered.png",
451
463
ret.length!1,
452
464
ret.length!0,
453
- (& ret[0, 0, 0])[0 .. ret.elementCount] );
465
+ ret.field );
454
466
}
455
467
}
456
468
-------
0 commit comments