private static Image <Complex, TDepth> prepareImage <TDepth>(Image <Gray, TDepth> image, int biggestKernelWidth, int biggestKernelHeight, ConvolutionBorder options, out int fillX, out int fillY) where TDepth : struct { int FFTNumOfCols = (int)System.Math.Pow(2.0, System.Math.Ceiling(System.Math.Log(biggestKernelWidth + image.Width, 2.0))); int FFTNumOfRows = (int)System.Math.Pow(2.0, System.Math.Ceiling(System.Math.Log(biggestKernelHeight + image.Height, 2.0))); fillX = System.Math.Min(image.Width, biggestKernelWidth / 2); fillY = System.Math.Min(image.Height, biggestKernelHeight / 2); Rectangle centerRegion = new Rectangle(fillX, fillY, image.Width, image.Height); Image <Gray, TDepth> paddedImage = new Image <Gray, TDepth>(FFTNumOfCols, FFTNumOfRows); //center paddedImage.GetSubRect(centerRegion).SetValue(image); if (options == ConvolutionBorder.BorderMirror) { ParallelConvolution.MirrorBorders(image, paddedImage, fillX, fillY); } Image <Complex, TDepth> paddedImageCmplx = new Image <Complex, TDepth>(new Image <Gray, TDepth>[] { paddedImage, paddedImage.CopyBlank() }); paddedImageCmplx.FFT(FourierTransform.Direction.Forward, true); return(paddedImageCmplx); }
private static IImage prepareSourceImage(IImage src, Size kernelSize, ConvolutionBorder options, out Rectangle validRegion) { var preparedSrc = Image.Create(src.ColorInfo, src.Width + kernelSize.Width, src.Height + kernelSize.Height); Rectangle centerRegion = new Rectangle(kernelSize.Width / 2, kernelSize.Height / 2, src.Width, src.Height); preparedSrc.GetSubRect(centerRegion).SetValue(src); if (options == ConvolutionBorder.BorderMirror) { ParallelConvolution.MirrorBorders(src, preparedSrc, centerRegion.X, centerRegion.Y); } validRegion = centerRegion; return(preparedSrc); }
private static IEnumerable <Image <Gray, TDepth> > ConvolveSeparated <TDepth>(Image <Gray, TDepth> image, Image <Gray, TDepth>[] kernels, ConvolutionBorder options) where TDepth : struct /*float and double */ { int biggestKernelWidth, biggestKernelHeight; ParallelConvolution.GetTheBiggestSize(kernels, out biggestKernelWidth, out biggestKernelHeight); int fillX, fillY; var paddedIm = prepareImage(image, biggestKernelWidth, biggestKernelHeight, options, out fillX, out fillY); foreach (var kernel in kernels) { var preparedKernel = prepareKernel(kernel, paddedIm.Size); var convolvedIm = paddedIm.Mul(preparedKernel, null); yield return(getConvolutionResult(convolvedIm, fillX, fillY, image.Size, true)); } }
private static Image <Gray, TDepth> convolve <TDepth>(Image <Gray, TDepth> image, Image <Gray, TDepth>[] kernels, ConvolutionBorder options) where TDepth : struct { int biggestKernelWidth, biggestKernelHeight; ParallelConvolution.GetTheBiggestSize(kernels, out biggestKernelWidth, out biggestKernelHeight); int fillX, fillY; var paddedIm = prepareImage(image, biggestKernelWidth, biggestKernelHeight, options, out fillX, out fillY); Image <Complex, TDepth> convolvedIm = paddedIm; foreach (var kernel in kernels) { var preparedKernel = prepareKernel(kernel, convolvedIm.Size); convolvedIm = convolvedIm.Mul(preparedKernel, null); } return(getConvolutionResult(convolvedIm, fillX, fillY, image.Size, true)); }