Example #1
0
        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]);
        }
Example #3
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);
                        }
                    }
                }
            }
        }
Example #4
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);
        }