Esempio n. 1
0
 private void ProcessPlane(ImagePlane plane, ProcessingBounds bounds)
 {
     ProcessingHelper.ProcessMono(plane, bounds, (b) =>
     {
         return((byte)(b >= Threshold ? 255 : 0));
     }, PixelFilter);
 }
Esempio n. 2
0
 private void ProcessPlane(ImagePlane plane, ProcessingBounds bounds)
 {
     ProcessingHelper.ProcessMono(plane, bounds, (b) =>
     {
         return(ValueProvider.Provide());
     }, PixelFilter);
 }
Esempio n. 3
0
        private void ProcessPlane(ImagePlane plane, ProcessingBounds bounds)
        {
            var valueDic = BuildValueDictionary(Mode, plane, bounds);

            ProcessingHelper.ProcessMono(plane, bounds, (b, y, x) =>
            {
                return((Mode == SmearMode.VerticalFromTop || Mode == SmearMode.VerticalFromBottom) ? valueDic[x] : valueDic[y]);
            }, PixelFilter);
        }
Esempio n. 4
0
        private void ProcessPlane(ImagePlane plane, ProcessingBounds bounds)
        {
            if (plane.TryGetLinearAccess(out LinearAccessData data))
            {
                int startY      = bounds.StartY;
                int startX      = bounds.StartX;
                int boundsY     = startY + bounds.Height;
                int boundsX     = startX + bounds.Width;
                int imageHeight = plane.Parent.Height;
                int imageWidth  = plane.Parent.Width;
                var yInc        = (int)data.YInc;
                var xInc        = (int)data.XInc;

                unsafe
                {
                    var pBase = (byte *)data.BasePtr;
                    for (int yy = bounds.StartY; yy < boundsY; yy += PixelateSize)
                    {
                        int offsetY        = PixelateSize / 2;
                        int yyPixelateSize = yy + PixelateSize;
                        for (int xx = bounds.StartX; xx < boundsX; xx += PixelateSize)
                        {
                            int offsetX        = PixelateSize / 2;
                            int xxPixelateSize = xx + PixelateSize;

                            while (xx + offsetX >= imageWidth)
                            {
                                offsetX--;
                            }
                            while (yy + offsetY >= imageHeight)
                            {
                                offsetY--;
                            }

                            byte *pPixelatedPixel = pBase + ((yy + offsetY) * yInc) + ((xx + offsetX) * xInc);
                            for (int y = yy; y < yyPixelateSize && y < imageHeight; y++)
                            {
                                byte *pLine = pBase + yInc * y;

                                for (int x = xx; x < xxPixelateSize && x < imageWidth; x++)
                                {
                                    byte *pPixel = pLine + xInc * x;
                                    if (PixelFilter.Check(*pPixel, y * boundsY + x))
                                    {
                                        *pPixel = *pPixelatedPixel;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                throw new ArgumentException("Plane could not be accessed linearly", nameof(plane));
            }
        }
Esempio n. 5
0
        private void ProcessPlane(ImagePlane plane, int[] weights, ProcessingBounds bounds, int weightSum)
        {
            var outputPlane = ProcessingHelper.ProcessMonoKernel(plane, (kl) =>
            {
                return(ApplyWeights(kl, weights, weightSum));
            }, KernelSize, bounds, PixelFilter);

            outputPlane.CopyTo(plane.Parent.Planes[plane.Plane]);
        }
Esempio n. 6
0
        private void ProcessPlane(ImagePlane plane, ProcessingBounds bounds)
        {
            var outputPlane = ProcessingHelper.ProcessMonoKernel(plane, (kl) =>
            {
                return(kl.Where(b => b.HasValue).Min(b => b.Value));
            }, KernelSize, bounds, PixelFilter);

            outputPlane.CopyTo(plane.Parent.Planes[plane.Plane]);
        }
Esempio n. 7
0
        private void ProcessPlane(ImagePlane plane, ProcessingBounds bounds)
        {
            var outputPlane = ProcessingHelper.ProcessMonoKernel(plane, (kl) =>
            {
                var stripped = kl.Where(b => b.HasValue);
                return((byte)(stripped.Sum(b => b.Value) / stripped.Count()));
            }, KernelSize, bounds, PixelFilter);

            outputPlane.CopyTo(plane.Parent.Planes[plane.Plane]);
        }
Esempio n. 8
0
        private void ProcessPlane(ImagePlane plane, ProcessingBounds bounds)
        {
            var outputPlane = ProcessingHelper.ProcessMonoKernel(plane, (kl) =>
            {
                var stripped = kl.Where(b => b.HasValue).ToArray();
                Array.Sort(stripped);
                return(UseHigherMedian ? stripped[stripped.Length / 2].Value : stripped[(stripped.Length / 2) - 1].Value);
            }, KernelSize, bounds, PixelFilter);

            outputPlane.CopyTo(plane.Parent.Planes[plane.Plane]);
        }
        /// <summary>
        /// Processes the pixels of the given <paramref name="plane"/>
        /// in the given <paramref name="bounds"/> with the
        /// given <paramref name="processorFunc"/>.
        /// </summary>
        /// <param name="plane">The plane whose pixels to process.</param>
        /// <param name="bounds">Bounds defining which pixels to process.</param>
        /// <param name="processorFunc">Func that takes a byte, processes
        /// it and returns a byte.</param>
        /// <param name="filterChain">Optional filter chain.</param>
        public static void ProcessMono(ImagePlane plane, ProcessingBounds bounds, Func <byte, byte> processorFunc, PixelFilterChain filterChain)
        {
            if (filterChain == null || !filterChain.HasActiveFilter)
            {
                ProcessMono(plane, bounds, processorFunc);
                return;
            }
            if (processorFunc == null)
            {
                throw new ArgumentNullException(nameof(processorFunc));
            }

            if (plane.TryGetLinearAccess(out LinearAccessData data))
            {
                var yInc    = (int)data.YInc;
                var xInc    = (int)data.XInc;
                int startY  = bounds.StartY;
                int startX  = bounds.StartX;
                int boundsY = startY + bounds.Height;
                int boundsX = startX + bounds.Width;
                unsafe
                {
                    var pBase = (byte *)data.BasePtr;

                    Parallel.For(startY, boundsY, (y) =>
                    {
                        byte *pLine = pBase + yInc * y;

                        for (int x = startX; x < boundsX; x++)
                        {
                            byte *pPixel = pLine + xInc * x;
                            if (filterChain.Check(*pPixel, y * boundsY + x))
                            {
                                *pPixel = processorFunc.Invoke(*pPixel);
                            }
                        }
                    });
                }
            }
            else
            {
                throw new ArgumentException("Plane could not be accessed linear", nameof(plane));
            }
        }
Esempio n. 10
0
 private void ProcessPlane(ImagePlane plane, ProcessingBounds bounds)
 {
     ProcessingHelper.ProcessMono(plane, bounds, (b) =>
     {
         if (ShiftDirection == BitShiftDirection.Left)
         {
             int pixelValue = b << ValueProvider.Provide();
             if (WrapAround && pixelValue > 255)
             {
                 return(255);
             }
             else
             {
                 return((byte)pixelValue);
             }
         }
         else
         {
             return((byte)(b >> ValueProvider.Provide()));
         }
     }, PixelFilter);
 }
Esempio n. 11
0
        private void ProcessPlane(ImagePlane plane, ProcessingBounds bounds)
        {
            int byteCounter = 0;

            byte[] sortedBytes;

            unsafe
            {
                if (UseAOI)
                {
                    if (Mode == SortMode.Ascending)
                    {
                        sortedBytes = plane.GetAllPixelsIn(AOI).Select(p => *(byte *)p).OrderBy(i => i).ToArray();
                    }
                    else
                    {
                        sortedBytes = plane.GetAllPixelsIn(AOI).Select(p => *(byte *)p).OrderByDescending(i => i).ToArray();
                    }
                }
                else
                {
                    if (Mode == SortMode.Ascending)
                    {
                        sortedBytes = plane.AllPixels.Select(p => *(byte *)p).OrderBy(i => i).ToArray();
                    }
                    else
                    {
                        sortedBytes = plane.AllPixels.Select(p => *(byte *)p).OrderByDescending(i => i).ToArray();
                    }
                }
            }

            ProcessingHelper.ProcessMono(plane, bounds, (b) =>
            {
                return(sortedBytes[byteCounter++]);
            }, PixelFilter);
        }
Esempio n. 12
0
        private void ProcessPlane(ImagePlane plane, ProcessingBounds bounds)
        {
            var rnd         = new Random(DateTime.Now.Ticks.GetHashCode());
            int byteCounter = 0;

            byte[] shuffledBytes;

            unsafe
            {
                if (UseAOI)
                {
                    shuffledBytes = plane.GetAllPixelsIn(AOI).Select(p => *(byte *)p).OrderBy(i => rnd.Next()).ToArray();
                }
                else
                {
                    shuffledBytes = plane.AllPixels.Select(p => *(byte *)p).OrderBy(i => rnd.Next()).ToArray();
                }
            }

            ProcessingHelper.ProcessMono(plane, bounds, (b) =>
            {
                return(shuffledBytes[byteCounter++]);
            }, PixelFilter);
        }
Esempio n. 13
0
        private static IDictionary <int, byte> BuildValueDictionary(SmearMode mode, ImagePlane plane, ProcessingBounds bounds)
        {
            var dic = new Dictionary <int, byte>();

            if (mode == SmearMode.VerticalFromTop)
            {
                for (int x = bounds.StartX; x < bounds.StartX + bounds.Width; x++)
                {
                    dic.Add(x, (byte)plane.GetPixel(x, bounds.StartY));
                }
            }
            else if (mode == SmearMode.VerticalFromBottom)
            {
                for (int x = bounds.StartX; x < bounds.StartX + bounds.Width; x++)
                {
                    dic.Add(x, (byte)plane.GetPixel(x, bounds.StartY + bounds.Height - 1));
                }
            }
            else if (mode == SmearMode.HorizontalFromLeft)
            {
                for (int y = bounds.StartY; y < bounds.StartY + bounds.Height; y++)
                {
                    dic.Add(y, (byte)plane.GetPixel(bounds.StartX, y));
                }
            }
            else if (mode == SmearMode.HorizontalFromRight)
            {
                for (int y = bounds.StartY; y < bounds.StartY + bounds.Height; y++)
                {
                    dic.Add(y, (byte)plane.GetPixel(bounds.StartX + bounds.Width - 1, y));
                }
            }
            else
            {
                throw new ArgumentException("Unknown Smear Mode", nameof(mode));
            }

            return(dic);
        }
Esempio n. 14
0
        /// <summary>
        /// Processes the given rgb <paramref name="img"/> in the
        /// given <paramref name="bounds"/> with
        /// the given <paramref name="processingFunc"/>.
        /// </summary>
        /// <param name="img">Image to process.</param>
        /// <param name="processingFunc">Processing function to process
        /// the <paramref name="img"/> with.</param>
        /// <param name="bounds">Bounds defining which pixels to process.</param>
        /// <param name="filterChain">Optional filter chain.</param>
        public static void ProcessRGB(Image img, Func <RGBPixel, RGBPixel> processingFunc, ProcessingBounds bounds, PixelFilterChain filterChain)
        {
            if (filterChain == null || !filterChain.HasActiveFilter)
            {
                ProcessRGB(img, processingFunc, bounds);
                return;
            }
            if (img == null)
            {
                throw new ArgumentNullException(nameof(img));
            }
            if (img.Planes.Count < 3)
            {
                throw new ArgumentException("Image is no rgb image", nameof(img));
            }
            if (processingFunc == null)
            {
                throw new ArgumentNullException(nameof(processingFunc));
            }

            if (img.Planes[0].TryGetLinearAccess(out LinearAccessData rData) &&
                img.Planes[1].TryGetLinearAccess(out LinearAccessData gData) &&
                img.Planes[2].TryGetLinearAccess(out LinearAccessData bData))
            {
                int startY  = bounds.StartY;
                int startX  = bounds.StartX;
                int boundsY = startY + bounds.Height;
                int boundsX = startX + bounds.Width;
                var rYInc   = (int)rData.YInc;
                var gYInc   = (int)gData.YInc;
                var bYInc   = (int)bData.YInc;
                var rXInc   = (int)rData.XInc;
                var gXInc   = (int)gData.XInc;
                var bXInc   = (int)bData.XInc;

                unsafe
                {
                    var pBaseR = (byte *)rData.BasePtr;
                    var pBaseG = (byte *)gData.BasePtr;
                    var pBaseB = (byte *)bData.BasePtr;

                    Parallel.For(startY, boundsY, (y) =>
                    {
                        byte *rLine = pBaseR + rYInc * y;
                        byte *gLine = pBaseG + gYInc * y;
                        byte *bLine = pBaseB + bYInc * y;

                        for (int x = startX; x < boundsX; x++)
                        {
                            byte *rPixel = rLine + rXInc * x;
                            byte *gPixel = gLine + gXInc * x;
                            byte *bPixel = bLine + bXInc * x;

                            if (filterChain.Check(*rPixel, *gPixel, *bPixel, y * boundsY + x))
                            {
                                var result = processingFunc.Invoke(new RGBPixel(*rPixel, *gPixel, *bPixel));
                                *rPixel    = result.R;
                                *gPixel    = result.G;
                                *bPixel    = result.B;
                            }
                        }
                    });
                }
            }
Esempio n. 15
0
        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));
            }
        }
Esempio n. 16
0
        private void ProcessPlane(ImagePlane inputPlane, ImagePlane newPlane, ProcessingBounds bounds)
        {
            if (inputPlane.TryGetLinearAccess(out LinearAccessData inputData))
            {
                if (newPlane.TryGetLinearAccess(out LinearAccessData newData))
                {
                    var inputYInc = (int)inputData.YInc;
                    var inputXInc = (int)inputData.XInc;
                    var newYInc   = (int)newData.YInc;
                    var newXInc   = (int)newData.XInc;
                    int boundsY   = bounds.StartY + bounds.Height;
                    int boundsX   = bounds.StartX + bounds.Width;

                    unsafe
                    {
                        var inputPBase = (byte *)inputData.BasePtr;
                        var newPBase   = (byte *)newData.BasePtr;

                        for (int y = bounds.StartY; y < boundsY; y++)
                        {
                            byte *inputPLine = inputPBase + inputYInc * y;
                            byte *newPLine;
                            int   newY = y + ShiftY;
                            if (newY < boundsY)
                            {
                                newPLine = newPBase + newYInc * newY;
                            }
                            else if (Wrap)
                            {
                                newPLine = newPBase + newYInc * (newY - boundsY);
                            }
                            else
                            {
                                continue;
                            }

                            for (int x = bounds.StartX; x < boundsX; x++)
                            {
                                byte *inputPPixel = inputPLine + inputXInc * x;
                                byte *newPPixel;
                                int   newX = x + ShiftX;
                                if (newX < boundsX)
                                {
                                    newPPixel = newPLine + newXInc * newX;
                                }
                                else if (Wrap)
                                {
                                    newPPixel = newPLine + newXInc * (newX - boundsX);
                                }
                                else
                                {
                                    continue;
                                }

                                if (PixelFilter.Check(*inputPPixel, y * boundsY + x))
                                {
                                    *newPPixel = *inputPPixel;
                                }
                            }
                        }
                    }
                }
                else
                {
                    throw new ArgumentException("New plane could not be accessed linear");
                }
            }
            else
            {
                throw new ArgumentException("Input plane could not be accessed linear");
            }
        }
Esempio n. 17
0
 private void ProcessPlane(ImagePlane plane, Func <int, byte, byte> calculationFunc, ProcessingBounds bounds)
 {
     ProcessingHelper.ProcessMono(plane, bounds, (b) =>
     {
         return(calculationFunc(ValueProvider.Provide(), b));
     }, PixelFilter);
 }