Exemple #1
0
        void WorkerOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                currentTask.OriginalImage.Dispose();
                if (currentTaskImage != null)
                {
                    currentTaskImage.Dispose();
                }
            }
            else if (!runAfterCancel)
            {
                Image oldImage = pictureBox.Image;
                pictureBox.Image = currentTaskImage;

                // Free resources used by the previous rendering
                if (oldImage != null && oldImage != originalImage)
                {
                    oldImage.Dispose();
                }

                // We're done! Unlock the interface.
                SetProgressVisible(false);
            }
            currentTaskImage = null;
            currentTask      = null;
            if (runAfterCancel)
            {
                runAfterCancel = false;
                bProcess.PerformClick();
            }
        }
Exemple #2
0
        void bProcess_Click(object sender, EventArgs e)
        {
            // cancel whatever task is in progress
            if (currentTask != null)
            {
                runAfterCancel = true;
                worker.CancelAsync();
                currentTask.CancelAsync();
                return;
            }

            SortAlgorithm algo          = (SortAlgorithm)cAlgorithm.SelectedIndex;
            SortOrder     order         = (SortOrder)cOrder.SelectedIndex;
            SortMetric    metric        = (SortMetric)cMetric.SelectedIndex;
            SamplingMode  sampling      = (SamplingMode)cSampling.SelectedIndex;
            int           segmentWidth  = (int)nSegmentWidth.Value;
            int           segmentHeight = (int)nSegmentHeight.Value;
            double        threshold     = tbThreshold.Value / 100d;

            pbProgress.Value = 0;
            SetProgressVisible(true);

            currentTask = new SortingTask(algo,
                                          order,
                                          metric,
                                          sampling,
                                          segmentWidth,
                                          segmentHeight,
                                          (Bitmap)originalImage.Clone(),
                                          threshold);
            currentTask.ProgressChanged += (o, args) => worker.ReportProgress(args.ProgressPercentage);

            worker.RunWorkerAsync();
        }
Exemple #3
0
 public Segment(SortingTask task, int x, int y)
 {
     OffsetX = x;
     OffsetY = y;
     Value   = 0;
     Value   = GetValue(task);
 }
Exemple #4
0
        static double GetSingleValue(SortingTask task, int x, int y)
        {
            Color c = task.OriginalImage.GetPixel(x, y);

            switch (task.Metric)
            {
            case SortMetric.Intensity:
                return(c.GetIntensity());

            case SortMetric.Lightness:
                return(c.GetLightness());

            case SortMetric.Value:
                return(Math.Max(c.R, Math.Max(c.G, c.B)));

            case SortMetric.Luma:
                return(c.R * 0.2126 + c.G * 0.7152 + c.B * 0.0722);

            case SortMetric.HslHue:
                return(c.GetHue() / 360d);

            case SortMetric.LabHue: {
                LabColor labC = c.ToLab();
                if (labC.a == 0)
                {
                    return(Math.PI / 2);
                }
                else
                {
                    double lh = Math.Atan2(labC.b, labC.a);
                    if (lh <= 0)
                    {
                        lh = Math.PI * 2 - Math.Abs(lh);
                    }
                    return(lh);
                }
            }

            case SortMetric.Chroma:
                return(c.GetChroma());

            case SortMetric.LabChroma: {
                LabColor labColor = c.ToLab();
                return(Math.Sqrt(labColor.a * labColor.a + labColor.b * labColor.b));
            }


            case SortMetric.HsbSaturation: {
                double chroma = c.GetChroma();
                if (chroma == 0)
                {
                    return(0);
                }
                else
                {
                    return(chroma / c.GetMax());
                }
            }

            case SortMetric.HsiSaturation: {
                double chroma    = c.GetChroma();
                double intensity = c.GetIntensity();
                if (chroma == 0 || intensity == 0)
                {
                    return(0);
                }
                else
                {
                    double m = c.GetMin();
                    return(1 - m / intensity);
                }
            }

            case SortMetric.HslSaturation: {
                double max    = c.GetMax();
                double min    = c.GetMin();
                double chroma = c.GetChroma();
                double L      = c.GetLightness();
                if (chroma == 0 || L == 0 || L == 1)
                {
                    return(0);
                }
                if (L < 0.5)
                {
                    return(chroma / (max + min));
                }
                else
                {
                    return(chroma / (2 - max - min));
                }
            }

            case SortMetric.LabSaturation: {
                LabColor labColor = c.ToLab();
                if (labColor.L < ColorUtil.LinearThreshold)
                {
                    return(0);
                }
                else
                {
                    return(Math.Sqrt(labColor.a * labColor.a + labColor.b * labColor.b) / labColor.L);
                }
            }

            case SortMetric.RedChannel:
                return(c.R);

            case SortMetric.GreenChannel:
                return(c.G);

            case SortMetric.BlueChannel:
                return(c.B);

            case SortMetric.Red:
                return(c.R - Math.Max(c.G, c.B));

            case SortMetric.Green:
                return(c.G - Math.Max(c.R, c.B));

            case SortMetric.Blue:
                return(c.B - Math.Max(c.R, c.G));

            case SortMetric.Cyan:
                return((c.G + c.B) - Math.Max(c.R * 1.5, Math.Abs(c.G - c.B)));

            case SortMetric.Magenta:
                return((c.R + c.B) - Math.Max(c.G * 1.5, Math.Abs(c.R - c.B)));

            case SortMetric.Yellow:
                return((c.R + c.G) - Math.Max(c.B * 1.5, Math.Abs(c.R - c.G)));

            case SortMetric.LabA:
                return(c.ToLab().a);

            case SortMetric.LabB:
                return(c.ToLab().b);

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemple #5
0
        double GetValue(SortingTask task)
        {
            if (task.Algorithm == SortAlgorithm.Segment)
            {
                return(GetSingleValue(task, OffsetX, OffsetY));
            }
            switch (task.Sampling)
            {
            case SamplingMode.Center:
                return(GetSingleValue(task, OffsetX + task.SegmentWidth / 2, OffsetY + task.SegmentHeight / 2));

            case SamplingMode.Mean: {
                double result = 0;
                for (int x = 0; x < task.SegmentWidth; ++x)
                {
                    for (int y = 0; y < task.SegmentHeight; ++y)
                    {
                        result += GetSingleValue(task, OffsetX + x, OffsetY + y);
                    }
                }
                return(result / (task.SegmentWidth * task.SegmentHeight));
            }

            case SamplingMode.Median: {
                var all = new double[task.SegmentWidth * task.SegmentHeight];
                for (int x = 0; x < task.SegmentWidth; ++x)
                {
                    for (int y = 0; y < task.SegmentHeight; ++y)
                    {
                        all[x * task.SegmentHeight + y] = GetSingleValue(task, OffsetX + x, OffsetY + y);
                    }
                }
                Array.Sort(all);
                return(all[all.Length / 2]);
            }

            case SamplingMode.Maximum: {
                double result = double.MinValue;
                for (int x = 0; x < task.SegmentWidth; ++x)
                {
                    for (int y = 0; y < task.SegmentHeight; ++y)
                    {
                        result = Math.Max(result, GetSingleValue(task, OffsetX + x, OffsetY + y));
                    }
                }
                return(result);
            }

            case SamplingMode.Minimum: {
                double result = double.MaxValue;
                for (int x = 0; x < task.SegmentWidth; ++x)
                {
                    for (int y = 0; y < task.SegmentHeight; ++y)
                    {
                        result = Math.Min(result, GetSingleValue(task, OffsetX + x, OffsetY + y));
                    }
                }
                return(result);
            }

            case SamplingMode.Random:
                return(GetSingleValue(task, OffsetX + task.rand.Next(task.SegmentWidth),
                                      OffsetY + task.rand.Next(task.SegmentHeight)));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }