private static int[,] GammaCorrectionFunc(this int[,] x, double multCoeff, double gamma) { return(x.ArrayToDouble().PowArrayElements(gamma).ArrayMultByConst(multCoeff).ArrayToUint8()); }
//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 int[,] StretchContrastFunc(this int[,] x, double m, double e) { return(x.ArrayToDouble().ArraySumWithConst((2.2204 * Math.Pow(10, -16))).ConstDivByArrayElements(m). PowArrayElements(e).ArraySumWithConst(1).ConstDivByArrayElements(1).ImageDoubleToUint8()); }
private static int[,] LogTransformationFunc(this int[,] x, double multCoeff) { return(x.ArrayToDouble().ArraySumWithConst(1).LogArrayElements().ArrayMultByConst(multCoeff).ArrayToUint8()); }
//Overloads Need or not? public static int[,] Conv2(int[,] inArray, int[,] convArray, Convback convback) { return(Conv2Process(inArray.ArrayToDouble(), convArray.ArrayToDouble(), convback).DoubleArrayToInt()); }
public static double[,] Conv2(double[,] inArray, int[,] convArray, Convback convback) { return(Conv2Process(inArray, convArray.ArrayToDouble(), convback)); }
//Overloads Need or not? public static int[,] Conv2(int[,] inArray, int[] hrow, int[] hcol, Convback convback) { return(Conv2Process(inArray.ArrayToDouble(), hrow.VectorToDouble(), hcol.VectorToDouble(), convback).DoubleArrayToInt()); }
public static double[,] Conv2(int[,] inArray, int[] hrow, double[] hcol, Convback convback) { return(Conv2Process(inArray.ArrayToDouble(), hrow.VectorToDouble(), hcol, convback)); }
//negative value - rotate in another way public static int[,] RotateArray90(int[,] arr, int howmanytimes) { return(RotateArray90(arr.ArrayToDouble(), howmanytimes).DoubleArrayToInt()); }
public static double[,] Filter_double(int[,] arr, double[,] filter) { return(Filter_double(arr.ArrayToDouble(), filter, PadType.replicate)); }
public static double[,] Filter_double(int[,] arr, double[,] filter, double fdiv) { return(Filter_double(arr.ArrayToDouble(), filter.ArrayDivByConst(fdiv), PadType.replicate)); }
//Shorter some operation with using filter //shorter double public static double[,] Filter_double(int[,] arr, string filterType) { return(Filter_double(arr.ArrayToDouble(), ImageFilter.Dx3FWindow(filterType), PadType.replicate)); }
public static double[,] EuclidBinary(int[,] arr) { return(EuclidBinaryProcess(arr.ArrayToDouble())); }