private bool ProcessImage(Color[,] image, CIELAB[,] imageLAB) { double thresh = 5; UnionFind <CIELAB> uf = new UnionFind <CIELAB>((a, b) => (a.SqDist(b) <= thresh)); int[,] assignments = uf.ConnectedComponents(imageLAB);//Util.Map<Color, CIELAB>(image, Util.RGBtoLAB)); int numC = -1; for (int i = 0; i < image.GetLength(0); i++) { for (int j = 0; j < image.GetLength(1); j++) { numC = Math.Max(numC, assignments[i, j] + 1); } } if (numC >= 2) { RemoveBackground(image, imageLAB); } //if it is a black and white image (with num connected components >= 2), it's not a valid color image return(!(isBlackWhite(image, imageLAB) && numC >= 2)); }
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); } } } } }