Example #1
0
        //create disk with radius
        private static int[,] DiskProcess(int radius)
        {
            int[,] result = new int[(radius * 2) + 1, (radius * 2) + 1];

            ArrGen <int> d = new ArrGen <int>();

            if (HelpMe(radius, radius))
            {
                //if (radius == 0)
                //    result = new int[1; 1] { { 1 } };
                if (radius == 1)
                {
                    result = new int[3, 3] {
                        { 0, 1, 0 }, { 1, 1, 1 }, { 0, 1, 0 }
                    }
                }
                ;
                else if (radius == 3)
                {
                    result = d.ArrOfSingle(5, 5, 1);
                }
                else
                {
                    if (radius != 2)
                    {
                        result = new int[(radius * 2) - 1, (radius * 2) - 1];
                    }

                    result = d.ArrOfSingle(result.GetLength(0), result.GetLength(0), 1);

                    for (int i = 0; i < result.GetLength(0); i++)
                    {
                        for (int j = 0; j < result.GetLength(0); j++)
                        {
                            if (i == 0 || i == result.GetLength(0) - 1)
                            {
                                if (j < 2 || j > result.GetLength(0) - 3)
                                {
                                    result[i, j] = 0;
                                }
                            }
                            else if (i == 1 || i == result.GetLength(0) - 2)
                            {
                                if (j < 1 || j > result.GetLength(0) - 2)
                                {
                                    result[i, j] = 0;
                                }
                            }
                        }
                    }
                }
            }

            return(result);
        }
Example #2
0
        //create line with lenght and diretion
        private static int[,] LineProcess(int size, LineStructElementDegree lineType)
        {
            int[,] resultH = new int [1, size];
            int[,] resultV = new int [size, 1];
            int[,] tempRes = new int [size, size];
            ArrGen <int> d = new ArrGen <int>();

            if (HelpMe(size, size))
            {
                switch (lineType)
                {
                case LineStructElementDegree.horizontal:
                    resultH = d.ArrOfSingle(1, size, 1);
                    return(resultH);

                case LineStructElementDegree.vertical:
                    resultV = d.ArrOfSingle(size, 1, 1);
                    return(resultV);

                case LineStructElementDegree.plus45:
                    int m = size - 1;
                    int n = 0;
                    for (int i = 0; i < size; i++)
                    {
                        for (int j = 0; j < size; j++)
                        {
                            if (i == n && j == m)
                            {
                                tempRes[i, j] = 1;
                            }
                        }
                        m--;
                        n++;
                    }
                    return(tempRes);

                case LineStructElementDegree.minus45:
                    for (int i = 0; i < size; i++)
                    {
                        for (int j = 0; j < size; j++)
                        {
                            if (i == j)
                            {
                                tempRes[i, j] = 1;
                            }
                        }
                    }
                    return(tempRes);
                }
            }

            return(tempRes);
        }
Example #3
0
        //create octagon with dist from center point 1 to each direction
        private static int[,] OctagonProcess(int dist)
        {
            ArrGen <int> d = new ArrGen <int>();

            int[,] result = d.ArrOfSingle((dist * 2) + 1, (dist * 2) + 1, 1);

            var baka = dist / 3 * 2;

            if (HelpMe(dist, dist))
            {
                for (int i = 0; i < result.GetLength(0); i++)
                {
                    for (int j = 0; j < result.GetLength(0); j++)
                    {
                        if (i < baka && j < baka - i || i < baka && j >= result.GetLength(0) - baka + i)
                        {
                            result[i, j] = 0;
                        }
                        else if (i >= result.GetLength(0) - baka && j <= baka - (result.GetLength(0) - i) ||
                                 i >= result.GetLength(0) - baka && j >= result.GetLength(0) - (i - (baka * 2 + 1)) - 1)
                        {
                            result[i, j] = 0;
                        }
                    }
                }
            }

            return(result);
        }
Example #4
0
        //create diamond with dist from center point 1 to each direction
        private static int[,] DiamondProcess(int dist)
        {
            int[,] result = new int[(dist * 2) + 1, (dist * 2) + 1];
            //int[] resVect = result.Cast<int>().ToArray();

            ArrGen <int> d = new ArrGen <int>();

            if (HelpMe(dist, dist))
            {
                result = d.ArrOfSingle(result.GetLength(0), result.GetLength(0), 1);

                for (int i = 0; i < result.GetLength(0); i++)
                {
                    for (int j = 0; j < result.GetLength(0); j++)
                    {
                        if (i < dist && j < dist - i || i < dist && j > i + dist)
                        {
                            result[i, j] = 0;
                        }
                        else if (i > dist && j < i - dist || i > dist && j > result.GetLength(0) - (i - dist + 1))
                        {
                            result[i, j] = 0;
                        }
                    }
                }
            }

            return(result);
        }
Example #5
0
        //create rectangle with entred height and width
        private static int[,] RectangleProcess(int height, int width)
        {
            ArrGen <int> d = new ArrGen <int>();

            if (HelpMe(height, width))
            {
                return(d.ArrOfSingle(height, width, 1));
            }
            return(new int[height, width]);
        }
Example #6
0
        //create square with entered square side size
        private static int[,] SquareProcess(int size)
        {
            ArrGen <int> d = new ArrGen <int>();

            if (HelpMe(size, size))
            {
                return(d.ArrOfSingle(size, size, 1));
            }

            return(new int[size, size]);
        }
Example #7
0
        //process histogram by applying lut
        private static int[,] HisteqHelper(int[,] cPlane)
        {
            //gen array of the same values
            ArrGen <double> d = new ArrGen <double>();

            double    eps    = 2.2204 * Math.Pow(10, -16);
            const int nDef   = 64;  //default
            const int nUint8 = 256; //for uint8 image. At this time operationg only with them

            int[,] Result;

            //hgram contain integer counts for equally spaced bins with intensity values
            //here count it based on input array

            //array on ones 1 x nDef mult by input array length dived by nDef
            //obtain vector 1 x nDef size
            var hgram = (d.ArrOfSingle(1, nDef, 1).Cast <double>().ToArray()).VectorMultByConst((cPlane.ArrayToDouble().Cast <double>().ToArray().Length) / (double)nDef);

            //Normalize hgram. hgram = hgram mult by input array dived by hgram elements sum
            hgram = hgram.VectorMultByConst((cPlane.ArrayToDouble().Cast <double>().ToArray().Length) / (hgram.Cast <double>().ToArray().Sum()));
            var m = hgram.Length;

            //compute Cumulative and Histogram
            var imhist = ImHist(cPlane); //imhist only for uint8 arrays realization ([0..255])

            double[] CumuSum = new double[nUint8];
            for (int i = 0; i < nUint8; i++)
            {
                if (i == 0)
                {
                    CumuSum[i] = imhist[i];
                }
                else
                {
                    CumuSum[i] = imhist[i] + CumuSum[i - 1];
                }
            }

            //cumulative distribution function
            //create Transformation To Intensity Image
            var cumdInput = hgram.VectorMultByConst((cPlane.ArrayToDouble().Cast <double>().ToArray().Length) / (hgram.Cast <double>().ToArray().Sum()));

            double[] cumd = new double[nDef];
            for (int i = 0; i < nDef; i++)
            {
                if (i == 0)
                {
                    cumd[i] = cumdInput[i];
                }
                else
                {
                    cumd[i] = cumdInput[i] + cumd[i - 1];
                }
            }

            //Create transformation to an intensity image by minimizing the error
            //between desired and actual cumulative histogram.
            //tol saturates equal fractions at low and high pixel values

            //sory for this wtf code
            var z       = new double[2 * imhist.Length];
            var partOne = imhist.ToList();

            partOne[nUint8 - 1] = 0;
            partOne.ToArray().CopyTo(z, 0);

            var partTwo = imhist.ToList();

            partTwo[0] = 0;
            partTwo.ToArray().CopyTo(z, imhist.Length);

            var tolPart = d.VecorToArrayRowByRow(1, nUint8, (d.VecorToArrayRowByRow(2, nUint8, z)).MinInColumns());

            var tol = (d.ArrOfSingle(m, 1, 1)).MultArrays(tolPart.ArrayDivByConst(2));

            //Error
            var cumdArr    = d.TransposeArray(d.VecorToArrayRowByRow(1, nDef, cumd));
            var CumuSumArr = d.VecorToArrayRowByRow(1, nUint8, CumuSum);

            var errPartOne = cumdArr.MultArrays(d.ArrOfSingle(1, nUint8, 1));

            var errPartTwo = (d.ArrOfSingle(m, 1, 1)).MultArrays(CumuSumArr);

            var err = errPartOne.SubArrays(errPartTwo).SumArrays(tol);

            //Find all places with error. Yep; wtf code continues!
            List <double> erroIndexes = new List <double>();

            //present array as vector col by col. Coz this is cool. Cast dont need!
            //Sorry; stupid copy step by step matlab logic
            //var errVector = d.ArrayToVectorColByCol(err);

            //with cast faster a little?
            var errVector = err.Cast <double>().ToArray();

            for (int i = 0; i < errVector.Length; i++)
            {
                if (errVector[i] < -(cPlane.Length * Math.Sqrt(eps)))
                {
                    erroIndexes.Add(i);
                }
            }

            //f**k the error values
            double[,] rest = new double[err.GetLength(0), err.GetLength(1)];
            if (erroIndexes.Any())
            {
                var newErrVector = errVector.ToList();
                var newValue     = (d.ArrOfSingle(erroIndexes.Count(), 1, 1).Cast <double>().ToArray()).VectorMultByConst(cPlane.Length); //coz erroIndexes - vector

                for (int i = 0; i < errVector.Length; i++)
                {
                    for (int j = 0; j < erroIndexes.Count(); j++)
                    {
                        if (i == erroIndexes[j])
                        {
                            newErrVector[i] = cPlane.Length; //newValue[j];
                        }
                    }
                }

                rest = d.VecorToArrayRowByRow(rest.GetLength(0), rest.GetLength(1), newErrVector.ToArray());
            }
            else
            {
                //err vector back to array
                rest = err;
            }

            //find row number of mins in each col rest array
            double[] lut = new double[rest.GetLength(1)];

            double min;
            int    index = 0;

            for (int i = 0; i < rest.GetLength(1); i++)
            {
                min   = rest[0, i];
                index = 0;
                for (int j = 0; j < rest.GetLength(0); j++)
                {
                    if (min > rest[j, i])
                    {
                        min = rest[j, i];

                        index = j;
                    }
                }
                lut[i] = index;
            }

            //count lut
            for (int i = 0; i < lut.Length; i++)
            {
                lut[i] = lut[i] / (m - 1);
            }

            Result = (InlutHisteq(cPlane, lut)).ArrayToUint8();

            return(Result);
        }
Example #8
0
        private static Bitmap SaltPepperFilterProcess(Bitmap img, int m, int n, double filterOrder, SaltPepperfilterType spfiltType, bool unsharp)
        {
            Bitmap image = new Bitmap(img.Width, img.Height, PixelFormat.Format24bppRgb);

            List <ArraysListInt> ColorList = Helpers.GetPixels(img);
            var Rc = ColorList[0].Color;
            var Gc = ColorList[1].Color;
            var Bc = ColorList[2].Color;

            double[,] filter;
            int[,] resultR = new int[img.Height, img.Width];
            int[,] resultG = new int[img.Height, img.Width];
            int[,] resultB = new int[img.Height, img.Width];

            ArrGen <double> arrGen = new ArrGen <double>();
            double          Depth  = System.Drawing.Image.GetPixelFormatSize(img.PixelFormat);

            if (m >= 1 && n >= 1)
            {
                switch (spfiltType)
                {
                //Arithmetic mean filtering.
                //help with salt noize
                case SaltPepperfilterType.amean:
                    filter = ImageFilter.FspecialSize(m, n, "average");

                    resultR = (ImageFilter.Filter_double(Rc, filter)).ArrayToUint8();
                    resultG = (ImageFilter.Filter_double(Gc, filter)).ArrayToUint8();
                    resultB = (ImageFilter.Filter_double(Bc, filter)).ArrayToUint8();
                    break;

                //Geometric mean filtering.
                //help with salt noize
                case SaltPepperfilterType.gmean:
                    filter = arrGen.ArrOfSingle(m, n, 1);

                    resultR = GmeanCount(Rc, filter, m, n);
                    resultG = GmeanCount(Gc, filter, m, n);
                    resultB = GmeanCount(Bc, filter, m, n);
                    break;

                //harmonic mean filter
                //help with salt noize
                case SaltPepperfilterType.hmean:
                    filter = arrGen.ArrOfSingle(m, n, 1);

                    resultR = HmeanCount(Rc, filter, m, n);
                    resultG = HmeanCount(Gc, filter, m, n);
                    resultB = HmeanCount(Bc, filter, m, n);
                    break;

                //contraharmonic mean filter Q>0 for pepper & <0 for salt
                case SaltPepperfilterType.chmean:
                    filter = arrGen.ArrOfSingle(m, n, 1);

                    resultR = CharmeanCount(Rc, filter, filterOrder);
                    resultG = CharmeanCount(Gc, filter, filterOrder);
                    resultB = CharmeanCount(Bc, filter, filterOrder);
                    break;

                default:
                    resultR = Rc; resultG = Gc; resultB = Bc;
                    break;
                }

                image = Helpers.SetPixels(image, resultR, resultG, resultB);

                if (unsharp)  //spfiltType == SaltPepperfilterType.chmean & unsharp
                {
                    image = Helpers.FastSharpImage(image);
                }

                if (Depth == 8)
                {
                    image = PixelFormatWorks.Bpp24Gray2Gray8bppBitMap(image);
                }
                if (Depth == 1)
                {
                    image = PixelFormatWorks.ImageTo1BppBitmap(image, 0.5);
                }
            }
            else
            {
                Console.WriteLine("m and n parameters must be positive geater or equal 1. Recommended 2 & 2 and higher. Method >SaltandPapperFilter<");
            }

            return(image);
        }