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"));
                }

            }
        }
        private void Vis(bool figureQuality = false)
        {
            Directory.CreateDirectory(outdir + "\\viscolor\\");

            Directory.CreateDirectory(outdir + "\\vis\\");

            //read in the patterns and save out their layers
            List<PatternItem> patterns = PatternIO.GetPatterns(imagedir);

            foreach (PatternItem p in patterns)
            {
                String basename = p.Name;

                //Read the vis permutation description if available
                String specs = Path.Combine(outdir, "vis", p.Directory, Util.ConvertFileName(basename, "", ".txt"));
                if (!File.Exists(specs))
                    continue;

                Bitmap image = new Bitmap(p.FullPath);

                if (!palettes.ContainsKey(basename))
                    continue;

                PaletteData palette = palettes[basename];

                ColorTemplate template = new ColorTemplate(image, palette);

                int[] slotToColor = new int[template.NumSlots()];
                for (int i = 0; i < slotToColor.Count(); i++)
                    slotToColor[i] = i;

                Dictionary<int, int> groupToSlot = new Dictionary<int, int>();
                PaletteData data = new PaletteData();

                int ngroups = 0;
                for (int i = 0; i < slotToColor.Count(); i++)
                {
                    slotToColor[i] = i;
                    data.colors.Add(new Color());
                    data.lab.Add(new CIELAB());

                    if (template.PixelsInSlot(i) > 0)
                        groupToSlot.Add(ngroups++, i);
                }

                Bitmap vis = null;
                Graphics g = null;

                String[] lines = File.ReadAllLines(specs);

                //read the score and if it's the original or not
                double score = 0;
                bool orig = false;

                int nresult = 0;
                int y = 0;
                int x = 0;
                int ncol = 8;
                int iwidth = 200;
                int iheight = 200;
                int padding = (figureQuality) ? 8 : 15 ;
                Font font = new Font("Arial", 8);
                int colorIdx = 0;

                foreach (String line in lines)
                {
                    if (line.StartsWith("Count"))
                    {
                        int count = Int32.Parse(line.Split(' ').Last());

                        //initialize the result image
                        int nrow = count / ncol + 1;
                        vis = new Bitmap(ncol*iwidth, nrow*iheight);
                        g = Graphics.FromImage(vis);

                    } else if (line.StartsWith("Score"))
                    {
                        //add the result to the visualization
                        x = (nresult % ncol)*iwidth;
                        y = (nresult / ncol)*iheight;

                        if (colorIdx > 0)
                        {
                            Bitmap result = (renderFinal) ? GetFinalRendering(Util.ConvertFileName(basename, "",""), data): template.SolidColor(data, slotToColor);
                            //sometimes we can't get the nice image, so render the quantized image in this case
                            if (result == null)
                                result = template.SolidColor(data, slotToColor);
                            g.DrawImage(result, x, y, iwidth-padding, iheight-padding);

                            String label = String.Format("{0:0.00}", score);
                            Color color = Color.Black;
                            if (orig)
                            {
                                label += ", ***";
                                color = Color.Red;
                            }
                            if(!figureQuality) g.DrawString(label, font, new SolidBrush(color), x, y + iheight-padding);

                            result.Dispose();

                            colorIdx = 0;
                            //data.colors.Clear();
                            //data.lab.Clear();

                            nresult++;
                        }
                        score = Double.Parse(line.Split(' ')[1]);
                        orig = Boolean.Parse(line.Split(' ')[2]);
                    }
                    else
                    {
                        //rgb floats
                        int[] fields = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).Select<String, int>(s => ((int)(Math.Round(double.Parse(s) * 255)))).ToArray<int>();
                        Color color = Color.FromArgb(fields[0], fields[1], fields[2]);
                        data.colors[groupToSlot[colorIdx]] = color;
                        data.lab[groupToSlot[colorIdx]] = Util.RGBtoLAB(color);
                        colorIdx++;
                    }
                }

                //save the last image
                if (data.colors.Count() > 0)
                {
                    x = (nresult % ncol) * iwidth;
                    y = (nresult / ncol) * iheight;

                    Bitmap result = (renderFinal)? GetFinalRendering(Util.ConvertFileName(basename, "",""), data): template.SolidColor(data, slotToColor);
                    //sometimes we can't get the nice image, so render the quantized image in this case
                    if (result == null)
                        result = template.SolidColor(data, slotToColor);
                    g.DrawImage(result, x, y, iwidth - padding, iheight - padding);
                    Color color = Color.Black;

                    String label = String.Format("{0:0.00}", score);
                    if (orig)
                    {
                        label += ", ***";
                        color = Color.Red;
                    }

                    if (!figureQuality) g.DrawString(label, font, new SolidBrush(color), x, y + iheight - padding);

                    result.Dispose();

                    //data.colors.Clear();
                    //data.lab.Clear();
                    colorIdx = 0;

                    nresult++;
                }

                PatternIO.SavePattern(vis, p, Path.Combine(outdir, "viscolor"));
                vis.Dispose();

            }
        }
        //render an image of the original pattern, plus columns of patterns generated by different models (trained on diff styles)
        private void VisAllStyles()
        {
            Directory.CreateDirectory(outdir + "\\stylecolor\\");

            Directory.CreateDirectory(outdir + "\\styles\\");

            //read in the patterns and save out their layers
            List<PatternItem> patterns = PatternIO.GetPatterns(Path.Combine(imagedir,"../styles"));

            foreach (PatternItem p in patterns)
            {
                String basename = p.Name;

                //Read the style description if available
                String specs = Path.Combine(outdir, "styles", p.Directory, Util.ConvertFileName(basename, "", ".txt"));
                if (!File.Exists(specs))
                    continue;

                Bitmap image = new Bitmap(p.FullPath);

                if (!palettes.ContainsKey(basename))
                    continue;

                PaletteData palette = palettes[basename];

                ColorTemplate template = new ColorTemplate(image, palette);

                int[] slotToColor = new int[template.NumSlots()];
                for (int i = 0; i < slotToColor.Count(); i++)
                    slotToColor[i] = i;

                List<List<String>> lines = File.ReadAllLines(specs).Select(line => line.Split(',').ToList<String>()).ToList<List<String>>();
                if (lines.Count() == 0)
                    continue;

                Dictionary<String, int> styleToRowIdx = new Dictionary<String, int>();
                String origStyle = "";

                foreach (List<String> line in lines)
                {
                    origStyle = line[0];
                    if (!styleToRowIdx.ContainsKey(line[1]))
                        styleToRowIdx.Add(line[1], 0);
                }

                //read the score and if it's the original or not
                double score = 0;
                int iwidth = 100;
                int iheight = 100;
                int padding = 15;
                int headerSpace = 30;
                int width = (styleToRowIdx.Keys.Count() + 1) * iwidth;
                int height = (lines.Count() / styleToRowIdx.Keys.Count()) * iheight + headerSpace;

                Font font = new Font("Arial", 10);

                Bitmap vis = new Bitmap(width, height);
                Graphics g = Graphics.FromImage(vis);

                //write out the headings, highlight the original style heading
                var headers = styleToRowIdx.Keys.ToList<String>();
                int ncol = headers.Count()+1;
                Color headerColor = Color.Black;
                g.DrawString("original", font, new SolidBrush(headerColor), 0, 0);
                for (int i=0; i<headers.Count(); i++)
                {
                    if (headers[i] == origStyle)
                        g.DrawString(headers[i], font, new SolidBrush(headerColor), (i+1)*iwidth, 0);
                    else
                        g.DrawString(headers[i], font, new SolidBrush(headerColor), (i+1)*iwidth, 0);
                }

                //draw the original
                Bitmap original = (renderFinal)? image: template.DebugQuantization();
                g.DrawImage(original, 0, headerSpace, iwidth-padding, iheight-padding);
                original.Dispose();

                PaletteData data = new PaletteData();
                Dictionary<int, int> groupToSlot = new Dictionary<int, int>();
                int ngroups = 0;
                for (int i = 0; i < slotToColor.Count(); i++)
                {
                    slotToColor[i] = i;
                    data.colors.Add(new Color());
                    data.lab.Add(new CIELAB());

                    if (template.PixelsInSlot(i) > 0)
                        groupToSlot.Add(ngroups++, i);
                }

                foreach (List<String> line in lines)
                {
                    //draw the colorized thumbnail in the right location
                    String style = line[1];

                    String[] colors = line[2].Split('^');

                    int colorIdx = 0;
                    foreach (String color in colors)
                    {
                        //rgb floats
                        int[] fields = color.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).Select<String, int>(s => ((int)(Math.Round(double.Parse(s) * 255)))).ToArray<int>();
                        Color c = Color.FromArgb(fields[0], fields[1], fields[2]);
                        data.colors[groupToSlot[colorIdx]] = c;
                        data.lab[groupToSlot[colorIdx]] = Util.RGBtoLAB(c);
                        colorIdx++;
                    }

                    int x = (headers.IndexOf(style)+1)*iwidth;
                    int y = styleToRowIdx[style]*iheight+headerSpace;
                    styleToRowIdx[style]++;

                    Bitmap result = (renderFinal)?GetFinalRendering(Util.ConvertFileName(basename, "",""), data):template.SolidColor(data, slotToColor);
                    //sometimes we can't get the nice image, so render the quantized image in this case
                    if (result == null)
                        result = template.SolidColor(data, slotToColor);
                    g.DrawImage(result, x, y, iwidth-padding, iheight-padding);
                    result.Dispose();

                }

                PatternIO.SavePattern(vis, p, Path.Combine(outdir, "stylecolor"));
                vis.Dispose();

            }
        }
        private void Recolor()
        {
            String suboutdir = Path.Combine(outdir, "recolored");
            Directory.CreateDirectory(suboutdir);

            //read in the patterns and save out their layers
            List<PatternItem> patterns = PatternIO.GetPatterns(imagedir);

            foreach (PatternItem p in patterns)
            {
                String basename = p.Name;

                if (!palettes.ContainsKey(basename))
                    continue;

                PaletteData palette = palettes[basename];

                //Read the recoloring description if available
                String specs = Path.Combine(outdir, "specs", p.Directory, Util.ConvertFileName(basename, "", ".txt"));

                if (!File.Exists(specs))
                    continue;

                Bitmap image = new Bitmap(p.FullPath);

                //TODO: save and reload color templates functionality
                ColorTemplate template = new ColorTemplate(image, palette);

                PaletteData data = new PaletteData();

                String[] lines = File.ReadAllLines(specs);
                int[] slotToColor = new int[template.NumSlots()];
                Dictionary<int, int> groupToSlot = new Dictionary<int, int>();

                int ngroups = 0;
                for (int i = 0; i < slotToColor.Count(); i++)
                {
                    slotToColor[i] = i;
                    if (template.PixelsInSlot(i) > 0)
                        groupToSlot.Add(ngroups++, i);
                }

                //TODO: handle recoloring when # groups is less than number of original slots, because of quantization issues.
                //Right now, this is rather ugly..

                data.colors = new List<Color>();
                data.lab = new List<CIELAB>();
                for (int i = 0; i < slotToColor.Count(); i++)
                {
                    data.colors.Add(new Color());
                    data.lab.Add(new CIELAB());
                }

                int groupid = 0;
                foreach (String line in lines)
                {
                    //rgb floats
                    int[] fields = line.Split(new string[]{" "},StringSplitOptions.RemoveEmptyEntries).Select<String, int>(s=>((int)(Math.Round(double.Parse(s)*255)))).ToArray<int>();
                    Color color = Color.FromArgb(fields[0], fields[1], fields[2]);
                    data.colors[groupToSlot[groupid]] = color;
                    data.lab[groupToSlot[groupid]] = Util.RGBtoLAB(color);
                    groupid++;
                }

                Bitmap orig = (renderFinal)? image : template.DebugQuantization();
                PatternIO.SavePattern(orig, p, suboutdir, "_original");
                orig.Dispose();

                Bitmap result = (renderFinal)? GetFinalRendering(Util.ConvertFileName(basename, "",""), data): template.SolidColor(data, slotToColor);
                //sometimes we can't get the nice image, so render the quantized image in this case. TODO: or maybe skip rendering this visualization at all
                if (result == null)
                    result = template.SolidColor(data, slotToColor);
                PatternIO.SavePattern(result, p, suboutdir, "_recolored");
                result.Dispose();

            }
        }