Esempio n. 1
0
        /// <summary>
        /// Processes the <paramref name="inputImage"/>.
        /// </summary>
        /// <param name="inputImage">Image to process.</param>
        /// <returns>Processed image.</returns>
        public override Image Process(Image inputImage)
        {
            if (inputImage == null)
            {
                throw new ArgumentNullException(nameof(inputImage));
            }

            int[] factors = MakeBinominalFactors(KernelSize.GetKernelNumber());
            int[] weights = MakeWeights(factors);

            var bounds    = this.GetProcessingBounds(inputImage);
            int weightSum = weights.Sum();

            if (ProcessAllPlanes)
            {
                foreach (var plane in inputImage.Planes)
                {
                    ProcessPlane(plane, weights, bounds, weightSum);
                }
            }
            else
            {
                ProcessPlane(inputImage.Planes[PlaneIndex], weights, bounds, weightSum);
            }

            return(inputImage);
        }
Esempio n. 2
0
        /// <summary>
        /// Calculate a laplace kernel for the given <paramref name="kernelSize"/>.
        /// </summary>
        /// <param name="kernelSize">Kernel size to calculate laplace kernel for.</param>
        /// <returns>Calculated laplace kernel.</returns>
        private static int[] CalculateKernel(KernelSize kernelSize)
        {
            int kernelNum     = kernelSize.GetKernelNumber();
            int fullKernelNum = kernelNum * kernelNum;
            var kernel        = new int[fullKernelNum];

            for (int i = 0; i < kernel.Length; i++)
            {
                kernel[i] = 1;
            }
            kernel[(int)System.Math.Floor(fullKernelNum / 2.0)] = 1 - fullKernelNum;

            return(kernel);
        }
        public static ImagePlane ProcessMonoKernel(ImagePlane plane, Func <byte?[], byte> processingFunc, KernelSize kernel, ProcessingBounds bounds)
        {
            if (plane.TryGetLinearAccess(out LinearAccessData data))
            {
                var newImage = Image.FromPlanes(MappingOption.CopyPixels, plane);
                var newData  = newImage.Planes[0].GetLinearAccess();
                var yInc     = (int)data.YInc;
                var xInc     = (int)data.XInc;
                var newYInc  = (int)newData.YInc;
                var newXInc  = (int)newData.XInc;

                int boundHeight = plane.Parent.Height - 1;
                int boundWidth  = plane.Parent.Width - 1;
                int startY      = bounds.StartY;
                int startX      = bounds.StartX;
                int boundsY     = startY + bounds.Height;
                int boundsX     = startX + bounds.Width;

                int kernelSize    = kernel.GetKernelNumber();
                int kernelArrSize = kernelSize * kernelSize;
                var kernelFac     = (int)System.Math.Floor(kernelSize / 2.0);

                unsafe
                {
                    var pBase    = (byte *)data.BasePtr;
                    var pBaseNew = (byte *)newData.BasePtr;

                    Parallel.For(startY, boundsY, (y) =>
                    {
                        var kernelValues = new byte?[kernelArrSize];
                        var pLine        = pBase + y * yInc;
                        int newLineInc   = newYInc * y;

                        for (int x = startX; x < boundsX; x++)
                        {
                            int kernelCounter = -1;
                            var pMiddle       = pLine + xInc * x;
                            for (int kRow = -kernelFac; kRow <= kernelFac; kRow++)
                            {
                                byte *pKLine = pMiddle + kRow * yInc;
                                int yKRow    = y + kRow;
                                for (int kColumn = -kernelFac; kColumn <= kernelFac; kColumn++)
                                {
                                    kernelCounter++;
                                    int xKColumn = x + kColumn;
                                    if (yKRow < 0 || yKRow > boundHeight || xKColumn < 0 || xKColumn > boundWidth)
                                    {
                                        continue;
                                    }

                                    byte *pPixel = pKLine + kColumn * xInc;
                                    kernelValues[kernelCounter] = *pPixel;
                                }
                            }

                            if (kernelValues.Any(b => b.HasValue))
                            {
                                var pTargetLine  = pBaseNew + newLineInc;
                                var pTargetPixel = pTargetLine + newXInc * x; // current "middle pixel" in the target image
                                *pTargetPixel    = processingFunc.Invoke(kernelValues);
                            }
                        }
                    });
                }

                return(newImage.Planes[0]);
            }
            else
            {
                throw new ArgumentException("Plane could not be accessed linear", nameof(plane));
            }
        }