Ejemplo n.º 1
0
        private CIELAB[,] ModeRecolor(CIELAB[,] image, PaletteData palette)
        {
            int width = image.GetLength(0);
            int height = image.GetLength(1);
            CIELAB[,] result = new CIELAB[width, height];

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    double[] scores = new double[palette.colors.Count()];

                    //check if the color is in the palette
                    CIELAB color = image[i, j];
                    if (palette.lab.Contains(color))
                    {
                        result[i, j] = color;
                        continue;
                    }

                    //otherwise, find the best color by mode
                    for (int dx = -1; dx <= 1; dx++)
                    {
                        for (int dy = -1; dy <= 1; dy++)
                        {
                            int x = i + dx;
                            int y = j + dy;
                            double weight = (dx == 0 && dy == 0) ? 4 : 1;
                            if (Util.InBounds(x, y, width, height))
                            {
                                int bestc = ClosestColorIndex(image[x, y], palette.lab);
                                scores[bestc] -= weight;
                            }
                        }
                    }

                    //pick the color with the min score
                    double minScore = Double.PositiveInfinity;
                    int bestIdx = 0;
                    for (int c = 0; c < palette.colors.Count(); c++)
                    {
                        if (scores[c] < minScore)
                        {
                            minScore = scores[c];
                            bestIdx = c;
                        }
                    }

                    result[i, j] = palette.lab[bestIdx];

                }
            }

            return result;
        }
Ejemplo n.º 2
0
        private CIELAB[,] EdgeUnmixRecolor(CIELAB[,] image, PaletteData palette)
        {
            int width = image.GetLength(0);
            int height = image.GetLength(1);
            CIELAB[,] result = new CIELAB[width, height];

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    double[] scores = new double[palette.colors.Count()];

                    //check if the color is in the palette
                    CIELAB color = image[i, j];
                    if (palette.lab.Contains(color))
                    {
                        result[i, j] = color;
                        continue;
                    }

                    //otherwise, find the best color
                    //see if this is an edge
                    //if it is, assign the color to be one of the edge color candidates
                    HashSet<CIELAB> tbCandidates = new HashSet<CIELAB>();
                    HashSet<CIELAB> lrCandidates = new HashSet<CIELAB>();
                    List<HashSet<CIELAB>> unmixCandidates = new List<HashSet<CIELAB>> { tbCandidates, lrCandidates };

                    //check edge types
                    //horizontal and vertical
                    HashSet<CIELAB> oneSide = new HashSet<CIELAB>();
                    HashSet<CIELAB> otherSide = new HashSet<CIELAB>();
                    Point[] top = new Point[] { new Point(i - 1, j - 1), new Point(i, j - 1), new Point(i + 1, j - 1) };
                    Point[] bottom = new Point[] { new Point(i - 1, j + 1), new Point(i - 1, j), new Point(i - 1, j + 1) };
                    Point[] left = new Point[] { new Point(i - 1, j - 1), new Point(i - 1, j), new Point(i - 1, j + 1) };
                    Point[] right = new Point[] { new Point(i + 1, j - 1), new Point(i + 1, j), new Point(i + 1, j + 1) };

                    List<Point[]> oneCompare = new List<Point[]> { top, left };
                    List<Point[]> otherCompare = new List<Point[]> { bottom, right };

                    bool edge = false;
                    for (int c = 0; c < oneCompare.Count(); c++)
                    {
                        oneSide.Clear();
                        otherSide.Clear();

                        foreach (Point p in oneCompare[c])
                        {
                            if (Util.InBounds(p.X, p.Y, width, height))
                            {
                                CIELAB rc = ClosestColor(image[p.X, p.Y], palette.lab);
                                //check if in the set
                                if (oneSide.Contains(rc))
                                {
                                    //yes, we found a majority
                                    unmixCandidates[c].Add(image[p.X, p.Y]);
                                    break;
                                }
                                else
                                {
                                    oneSide.Add(rc);
                                }
                            }
                        }

                        foreach (Point p in otherCompare[c])
                        {

                            if (Util.InBounds(p.X, p.Y, width, height))
                            {
                                CIELAB rc = ClosestColor(image[p.X, p.Y], palette.lab);
                                //check if in the set
                                if (otherSide.Contains(rc))
                                {
                                    //yes, we found a majority
                                    unmixCandidates[c].Add(rc);
                                    break;
                                }
                                else
                                {
                                    otherSide.Add(rc);
                                }
                            }
                        }

                        //is it an edge?
                        if (unmixCandidates[c].Count() >= 2)
                        {
                            result[i, j] = ClosestColor(image[i, j], unmixCandidates[c].ToList<CIELAB>());
                            edge = true;
                            break;
                        }
                    }

                    //TODO:
                    //45 degrees

                    //45 degrees-flipped

                    if (!edge)
                    {
                        for (int dx = -1; dx <= 1; dx++)
                        {
                            for (int dy = -1; dy <= 1; dy++)
                            {
                                int x = i + dx;
                                int y = j + dy;
                                double weight = (dx == 0 && dy == 0) ? 4 : 1;
                                if (Util.InBounds(x, y, width, height))
                                {
                                    int bestc = ClosestColorIndex(image[x, y], palette.lab);
                                    scores[bestc] -= weight;
                                }
                            }
                        }

                        //pick the color with the min score
                        double minScore = Double.PositiveInfinity;
                        int bestIdx = 0;
                        for (int c = 0; c < palette.colors.Count(); c++)
                        {
                            if (scores[c] < minScore)
                            {
                                minScore = scores[c];
                                bestIdx = c;
                            }
                        }

                        result[i, j] = palette.lab[bestIdx];
                    }

                }
            }

            return result;
        }