예제 #1
1
        public ColorTemplate(Bitmap image, Segmentation seg, PaletteData palette)
        {
            slots = seg; //TODO: need to copy the segmentation?
            originalPalette = new PaletteData(palette);

            int width = image.Width;
            int height = image.Height;

            template = new CIELAB[width, height];

            //initialize the template
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    template[i, j] = Util.RGBtoLAB(image.GetPixel(i, j));
                }
            }

            segToColor = new int[seg.numSegments];

            //map each segment to the closest palette color, based on its mean color
            //TODO: if two adjacent segments have the same mean color, we could merge them...
            for (int i = 0; i < seg.numSegments; i++)
            {
                CIELAB lab = seg.segToMeanColor[i];
                int bestColor = -1;
                double bestDist = Double.PositiveInfinity;
                for (int j = 0; j < palette.lab.Count(); j++)
                {
                    double dist = palette.lab[j].SqDist(lab);

                    if (dist < bestDist)
                    {
                        bestDist = dist;
                        bestColor = j;
                    }
                }
                segToColor[i] = bestColor;
            }

            //subtract the mean color from the template
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    int coloridx = segToColor[slots.assignments[i, j]];
                    template[i, j] -= palette.lab[coloridx];
                    //template[i, j] /= palette.lab[coloridx];
                }
            }
        }
예제 #2
0
        CIELAB[,] template; //relative LAB difference (or change to RGB difference?)

        #endregion Fields

        #region Constructors

        public ColorTemplate(Bitmap image, PaletteData palette)
        {
            //create the segmentation based on the palette
            //TODO: There's a problem that sometimes a palette color won't appear in the image (perhaps due to color blending), and so the slot will have no pixels associated with it
            int width = image.Width;
            int height = image.Height;
            slots = new Segmentation(palette.colors.Count(), width, height);
            segToColor = new int[slots.numSegments];

            template = new CIELAB[width, height];

            CIELAB[,] recolored = ModeRecolor(Util.Map<Color, CIELAB>(Util.BitmapToArray(image), c => Util.RGBtoLAB(c)), palette);

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    template[i, j] = new CIELAB();
                    int bestIdx = -1;
                    CIELAB lab = recolored[i, j];
                    double bestDist = Double.PositiveInfinity;

                    for (int c = 0; c < palette.lab.Count(); c++)
                    {
                        double dist = palette.lab[c].SqDist(lab);
                        if (dist < bestDist)
                        {
                            bestDist = dist;
                            bestIdx = c;

                            if (dist < 0.00001)
                                break;

                        }
                    }

                    slots.assignments[i, j] = bestIdx;
                    slots.counts[bestIdx]++;
                    segToColor[bestIdx] = bestIdx;
                }
            }

            originalPalette = new PaletteData(palette);
        }
예제 #3
0
        private void ExtractTemplate_Click(object sender, EventArgs e)
        {
            //extract templates from images in a directory
            String[] files = Directory.GetFiles(dir, "*.png");
            String infile = dir + "\\palettes.tsv";
            Dictionary<String, List<PaletteData>> palettes = LoadFilePalettes(infile);

             Directory.CreateDirectory(dir + "\\templates\\");
             Directory.CreateDirectory(dir + "\\recolor\\");

            Random random = new Random();

            foreach (String f in files)
            {
                Bitmap image = new Bitmap(Image.FromFile(f));
                Segmentation seg = new Segmentation();
                String basename = f.Replace(dir+"\\", "");
                String segFile = dir + "/segments/" + basename;
                seg.LoadFromFile(f, segFile);

                ColorTemplate template = new ColorTemplate(image, seg, palettes[basename].First());
                Bitmap render = template.Render();
                render.Save(dir + "\\templates\\" + basename);

                //testing random color assignments
                int numSeg = template.NumSlots();

                int[] segToColor = new int[numSeg];
                for (int t = 0; t < 3; t++)
                {
                    for (int i = 0; i < numSeg; i++)
                        segToColor[i] = random.Next(palettes[basename].First().colors.Count());

                    Bitmap recolor = template.ColorWith(palettes[basename].First(), segToColor);
                    recolor.Save(dir + "\\recolor\\" + Util.ConvertFileName(basename,"_"+t));

                    Bitmap solidcolor = template.SolidColor(palettes[basename].First(), segToColor);
                    solidcolor.Save(dir + "\\recolor\\" + Util.ConvertFileName(basename, "_" + t + "_solid"));
                }

            }
        }
        //Load the segmentation file for a particular image
        private Segmentation LoadSegAssignments(String key, int width, int height, CIELAB[,] imageLAB)
        {
            Bitmap map = new Bitmap(dir + "/segments/" + key);
            Bitmap resized = Util.ResizeBitmapNearest(map, width, height);

            Segmentation s = new Segmentation();
            s.assignments = new int[width, height];

            List<Color> unique = new List<Color>();
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    Color c = resized.GetPixel(i, j);
                    if (!unique.Contains(c))
                        unique.Add(c);

                    int idx = unique.IndexOf(c);
                    s.assignments[i, j] = idx;

                }
            }

            s.numSegments = unique.Count();
            s.counts = new int[s.numSegments];
            s.segToMeanColor = new CIELAB[s.numSegments];
            for (int i = 0; i < s.numSegments; i++)
            {
                s.segToMeanColor[i] = new CIELAB();
            }
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {

                    int idx = s.assignments[i, j];
                    s.counts[idx]++;
                    s.segToMeanColor[idx] += imageLAB[i, j];
                }
            }

            for (int i = 0; i < s.numSegments; i++)
            {
                s.segToMeanColor[i] /= s.counts[i];
            }

            return s;
        }
예제 #5
0
        private void RenderWheels_Click(object sender, EventArgs e)
        {
            String[] files = Directory.GetFiles(dir, "*.png");
            String infile = dir + "\\palettes.tsv";
            Dictionary<String, List<PaletteData>> palettes = LoadFilePalettes(infile);

            String oinfile = dir + "\\oracle.csv";
            Dictionary<String, List<PaletteData>> oracle = LoadFilePalettes(oinfile);

            Directory.CreateDirectory(dir + "\\wheels\\");

            Random random = new Random();

            ColorWheel wheel = new ColorWheel(400, 10);

            foreach (String f in files)
            {
                Bitmap image = new Bitmap(Image.FromFile(f));
                Segmentation seg = new Segmentation();
                String basename = f.Replace(dir + "\\", "");

                List<HSV> phsv = new List<HSV>();
                List<HSV> ihsv = new List<HSV>();
                List<HSV> ohsv = new List<HSV>();

                for (int i = 0; i < image.Width; i++)
                {
                    for (int j = 0; j < image.Height; j++)
                    {
                        ihsv.Add(Util.RGBtoHSV(image.GetPixel(i,j)));
                    }
                }
                foreach (Color c in palettes[basename].First().colors)
                {
                    phsv.Add(Util.RGBtoHSV(c));
                }
                foreach (Color c in oracle[basename].First().colors)
                {
                    ohsv.Add(Util.RGBtoHSV(c));
                }

                Bitmap iw = wheel.RenderHueHistogram(ihsv);
                Bitmap pd = wheel.RenderDisk(phsv);
                Bitmap od = wheel.RenderDisk(ohsv);

                iw.Save(dir + "\\wheels\\" + Util.ConvertFileName(basename, "_hist"));
                pd.Save(dir + "\\wheels\\" + Util.ConvertFileName(basename, "_disk"));
                od.Save(dir + "\\wheels\\" + Util.ConvertFileName(basename, "_disko"));

            }
        }