private bool isBlackWhite(Color[,] image, CIELAB[,] imageLAB) { double nonGray = 0; double thresh = 0.001; CIELAB white = new CIELAB(100, 0, 0); CIELAB black = new CIELAB(0, 0, 0); int width = image.GetLength(0); int height = image.GetLength(1); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { Color color = image[i, j]; CIELAB lab = imageLAB[i, j];//Util.RGBtoLAB(color); bool gray = color.GetSaturation() <= 0.2 || lab.SqDist(white) <= 5 || lab.SqDist(black) <= 5; if (!gray) { nonGray++; } } } return(nonGray / (width * height) < thresh); }
private CIELAB ClosestColor(CIELAB color, List <CIELAB> palette) { int bestc = 0; Double bestDist = Double.PositiveInfinity; for (int c = 0; c < palette.Count(); c++) { double dist = color.SqDist(palette[c]); if (dist < bestDist) { bestDist = dist; bestc = c; } } return(palette[bestc]); }
private void RemoveBackground(Color[,] image, CIELAB[,] imageLAB) { //check perimeter to see if it's mostly black or white //RGB to LAB CIELAB black = new CIELAB(0, 0, 0); CIELAB white = new CIELAB(100, 0, 0); int width = image.GetLength(0); int height = image.GetLength(1); CIELAB[,] labs = imageLAB;//Util.Map<Color, CIELAB>(image, (c) => Util.RGBtoLAB(c)); int numBlack = 0; int numWhite = 0; int thresh = 3 * 3; List <Point> perimeterIdx = new List <Point>(); double totalPerimeter = 4 * width + 4 * height; double bgThresh = totalPerimeter * 0.75; for (int i = 0; i < width; i++) { //top for (int j = 0; j < 2; j++) { if (black.SqDist(labs[i, j]) < thresh) { numBlack++; } if (white.SqDist(labs[i, j]) < thresh) { numWhite++; } perimeterIdx.Add(new Point(i, j)); } //bottom for (int j = height - 2; j < height; j++) { perimeterIdx.Add(new Point(i, j)); if (black.SqDist(labs[i, j]) < thresh) { numBlack++; } if (white.SqDist(labs[i, j]) < thresh) { numWhite++; } } } for (int j = 0; j < height; j++) { //left for (int i = 0; i < 2; i++) { perimeterIdx.Add(new Point(i, j)); if (black.SqDist(labs[i, j]) < thresh) { numBlack++; } if (white.SqDist(labs[i, j]) < thresh) { numWhite++; } } //right for (int i = width - 2; i < width; i++) { perimeterIdx.Add(new Point(i, j)); if (black.SqDist(labs[i, j]) < thresh) { numBlack++; } if (white.SqDist(labs[i, j]) < thresh) { numWhite++; } } } if (numBlack >= bgThresh || numWhite >= bgThresh) { //connected components UnionFind <CIELAB> uf = new UnionFind <CIELAB>((a, b) => a.SqDist(b) < thresh); int[,] cc = uf.ConnectedComponents(labs); SortedSet <int> ids = new SortedSet <int>(); //go around the perimeter to collect the right ids foreach (Point p in perimeterIdx) { if (numWhite > numBlack) { if (labs[p.X, p.Y].SqDist(white) < thresh) { ids.Add(cc[p.X, p.Y]); } } else { if (labs[p.X, p.Y].SqDist(black) < thresh) { ids.Add(cc[p.X, p.Y]); } } } //fill the bitmap with transparency for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (ids.Contains(cc[i, j])) { image[i, j] = Color.FromArgb(0, 0, 0, 0); } } } } }
private double[] GetProbabilities(String query, Func <CIELAB, CIELAB, double> distFunc, Kernel kernel, double whiteThresh = 20) { CIELAB white = new CIELAB(100, 0, 0); //load the histogram double[, ,] hist = new double[Lbins, Abins, Bbins]; String histFile = Path.Combine(cacheDir, query) + ".txt"; String[] hlines = File.ReadAllLines(histFile); for (int i = 0; i < hlines.Count(); i++) { int L = i / (Abins * Bbins); int plane = (i % (Abins * Bbins)); int A = plane / Bbins; int B = plane % Bbins; hist[L, A, B] = Double.Parse(hlines[i]); } int ncolors = paletteLAB.Count(); double[] freq = new double[20]; Parallel.For(0, ncolors, l => { double count = 0; for (int i = 0; i < Lbins; i++) { for (int j = 0; j < Abins; j++) { for (int k = 0; k < Bbins; k++) { double val = hist[i, j, k]; System.Diagnostics.Debug.Assert(!double.IsNaN(val)); CIELAB lab = new CIELAB(i * binSize, j * binSize - 100, k * binSize - 100); if (white.SqDist(lab) < whiteThresh * whiteThresh) { continue; } if (val <= 0) { continue; } count += val; freq[l] += val * kernel.Eval(distFunc(paletteLAB[l], lab)); } } } if (count > 0) { freq[l] /= count; } }); //now renormalize double totalFreq = 0; for (int i = 0; i < freq.Count(); i++) { totalFreq += freq[i]; } //this should only happen if the histogram is empty or has no valid bins if (totalFreq == 0) { totalFreq = 1; } for (int i = 0; i < freq.Count(); i++) { freq[i] /= totalFreq; } return(freq); }