//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); }
//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); }
//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); }
//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); }
//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]); }
//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]); }
//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); }
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); }