public FloatImage Convolve(FloatImage k) { var kw = k.Width; var kh = k.Height; var kxs = kw >> 1; var kys = kh >> 1; var r = new FloatImage(_Width, _Height); float total = k.Sum(); for (var dy = 0; dy < _Height; dy++) { for (var dx = 0; dx < _Width; dx++) { var v = 0f; var sum = 0f; for (var ky = 0; ky < kh; ky++) { var sy = dy + ky - kys; if (sy < 0 || _Height <= sy) { continue; } for (var kx = 0; kx < kh; kx++) { var sx = dx + kx - kxs; if (sx < 0 || _Width <= sx) { continue; } var sv = this[sx, sy]; var kv = k[kx, ky]; v += sv * kv; sum += kv; } } r[dx, dy] = total == sum ? v : (v * total / sum); } } return(r); }
internal static FloatImage ConvolveSingle(T image, FloatImage kernel, int kernelWidth, int kernelHeight) { var kernelXRadius = kernel.Width >> 1; var kernelYRadius = kernelHeight >> 1; var r = new FloatImage(image.Width, image.Height); float total = kernel.Sum(); for (var dy = 0; dy < image.Height; dy++) { for (var dx = 0; dx < image.Width; dx++) { var v = 0f; var sum = 0f; for (var ky = 0; ky < kernelHeight; ky++) { var sy = dy + ky - kernelYRadius; if (sy < 0 || image.Height <= sy) { continue; } for (var kx = 0; kx < kernelWidth; kx++) { var sx = dx + kx - kernelXRadius; if (sx < 0 || image.Width <= sx) { continue; } var sv = image[sx, sy]; var kv = kernel[kx, ky]; v += sv * kv; sum += kv; } } r[dx, dy] = total == sum ? v : (v * total / sum); } } return(r); }