예제 #1
0
        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));
        }
예제 #2
0
        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);
                        }
                    }
                }
            }
        }