1 module rip.processing.convolution; 2 3 private 4 { 5 import std.algorithm; 6 import std.math; 7 import std.range; 8 9 import rip.concepts.color; 10 import rip.concepts.ranges; 11 import rip.concepts.surface; 12 import rip.processing.filters.linear; 13 } 14 15 // Точечная свертка 16 auto elementaryConvolution(Signal, Filter)(Signal signal, Filter filter) 17 { 18 19 RGBColor result = new RGBColor(0, 0, 0); 20 21 auto data = zip(signal, filter); 22 alias PairType = ElementType!(typeof(data)); 23 24 auto conv = delegate(PairType pair) { 25 if(pair[1] != 0) { 26 if(pair[1] < 0) 27 result -= pair[0] * abs(pair[1]); 28 29 else if(pair[1] != 1) 30 result += pair[0] * pair[1]; 31 else 32 result += pair[0]; 33 } 34 }; 35 36 data.each!conv; 37 38 return result; 39 } 40 41 // Свертка сигнала с линейным фильтром 42 auto convolution(Signal)(Signal signal, LinearFilter filter) 43 { 44 // Выполнение свертки на одном фрагменте диапазона окрестностей 45 auto performConvolution(Signal)(Signal signal, LinearFilter filter) 46 { 47 return filter.getOffset + filter.getDivider * elementaryConvolution(signal, filter.getKernel); 48 } 49 50 auto convolutionRange = map!(a => performConvolution(a, filter))(signal).array; 51 return convolutionRange; 52 } 53 54 auto convolve(Surface surface, LinearFilter filter) 55 { 56 auto image = surface 57 .createFences(filter.getWidth, filter.getHeight) 58 .convolution(filter) 59 .toSurface(surface.getWidth!int, surface.getHeight!int); 60 return image; 61 } 62 63 auto convolveNew(Surface surface, LinearFilter filter) 64 { 65 auto image = surface 66 .createFencesNew(filter.getWidth, filter.getHeight) 67 .convolution(filter) 68 .toSurface(surface.getWidth!int, surface.getHeight!int); 69 return image; 70 }