예제 #1
0
        private void BrCalc_Advanced()
        {
            #region Variables

            BitmapEx  bmp1, bmp2, bmp3;
            const int min = 5;
            const int max = 250;

            bmp1 = GetThumb(0, true);

            int        isdark, xS, yS;
            const uint ThumbWidth = 300;
            const uint ThumbHeight = 200;
            uint       x, y, rowstride, n = bmp1.ChannelCount;
            long       index, count;
            double     br1, br2, br3, newBr, maxiBrDiff;

            double[,] BrightChangeMask = new double[ThumbWidth, ThumbHeight];
            bool[,] NonUseMask         = new bool[ThumbWidth, ThumbHeight];
            double[][] PixelBrightness = new double[ThumbWidth * ThumbHeight][];

            ColorRGB c;

            #endregion

            //TODO: make calculation parallel

            for (int f = 0; f < Frames.Count; f += 2)
            {
                if (MainWorker.CancellationPending)
                {
                    return;
                }

                #region Variables

                if (f == 0)
                {
                    f++;
                }
                if (f + 2 >= Frames.Count)
                {
                    f = Frames.Count - 2;
                }

                bmp1      = GetThumb(f - 1, false).Scale(ThumbWidth, ThumbHeight);
                bmp2      = GetThumb(f, false).Scale(ThumbWidth, ThumbHeight);
                bmp3      = GetThumb(f + 1, false).Scale(ThumbWidth, ThumbHeight);
                rowstride = bmp1.Stride;

                n     = bmp1.ChannelCount;
                index = count = isdark = 0;
                br1   = br2 = br3 = newBr = maxiBrDiff = 0;
                RGBSpace space = new RGBColorspacesRGB();

                #endregion

                unsafe
                {
                    bmp1.LockBits();
                    bmp2.LockBits();
                    bmp3.LockBits();

                    byte *pix1 = (byte *)bmp1.Scan0;
                    byte *pix2 = (byte *)bmp2.Scan0;
                    byte *pix3 = (byte *)bmp3.Scan0;

                    #region Mask

                    for (y = 0; y < ThumbHeight; y++)
                    {
                        for (x = 0; x < rowstride; x += n)
                        {
                            index = y * rowstride + x;

                            c = new ColorRGB(pix1[index], pix1[index + 1], pix1[index + 2], space);
                            fixed(double *pt = c.ValueArray)
                            {
                                ((RGBSpace)c.Space).ToLinear(pt, pt);
                            }

                            br1 = (c.R + c.G + c.B) * 255d / 3d;
                            c   = new ColorRGB(pix2[index], pix2[index + 1], pix2[index + 2], space);
                            fixed(double *pt = c.ValueArray)
                            {
                                ((RGBSpace)c.Space).ToLinear(pt, pt);
                            }

                            br2 = (c.R + c.G + c.B) * 255d / 3d;
                            c   = new ColorRGB(pix3[index], pix3[index + 1], pix3[index + 2], space);
                            fixed(double *pt = c.ValueArray)
                            {
                                ((RGBSpace)c.Space).ToLinear(pt, pt);
                            }

                            br3 = (c.R + c.G + c.B) * 255d / 3d;

                            if (br1 > min && br2 > min && br3 > min && br1 < max && br2 < max && br3 < max)
                            {
                                NonUseMask[x / n, y] = false;
                            }
                            else
                            {
                                NonUseMask[x / n, y] = true;
                            }
                        }
                    }

                    List <double> brightnessDiff1;
                    List <double> brightnessDiff2;

                    for (y = 0; y < ThumbHeight; y++)
                    {
                        for (x = 0; x < bmp1.Stride; x += n)
                        {
                            if (NonUseMask[x / n, y] == false)
                            {
                                count           = 0;
                                brightnessDiff1 = new List <double>();
                                brightnessDiff2 = new List <double>();

                                for (yS = -1; yS <= 1; yS++)
                                {
                                    if (y + yS < ThumbHeight && y + yS >= 0)
                                    {
                                        for (xS = -1; xS <= 1; xS++)
                                        {
                                            if (x + xS < rowstride && x + xS >= 0)
                                            {
                                                if (NonUseMask[(x + xS) / n, y + yS] == false)
                                                {
                                                    index = (y + yS) * rowstride + x + xS;

                                                    c = new ColorRGB(pix1[index], pix1[index + 1], pix1[index + 2], space);
                                                    fixed(double *pt = c.ValueArray)
                                                    {
                                                        ((RGBSpace)c.Space).ToLinear(pt, pt);
                                                    }

                                                    br1 = (c.R + c.G + c.B) * 255d / 3d;
                                                    c   = new ColorRGB(pix2[index], pix2[index + 1], pix2[index + 2], space);
                                                    fixed(double *pt = c.ValueArray)
                                                    {
                                                        ((RGBSpace)c.Space).ToLinear(pt, pt);
                                                    }

                                                    br2 = (c.R + c.G + c.B) * 255d / 3d;
                                                    c   = new ColorRGB(pix3[index], pix3[index + 1], pix3[index + 2], space);
                                                    fixed(double *pt = c.ValueArray)
                                                    {
                                                        ((RGBSpace)c.Space).ToLinear(pt, pt);
                                                    }

                                                    br3 = (c.R + c.G + c.B) * 255d / 3d;

                                                    brightnessDiff1.Add(Math.Abs(br1 - br2));
                                                    brightnessDiff2.Add(Math.Abs(br2 - br3));

                                                    count++;
                                                }
                                            }
                                        }
                                    }
                                }

                                if (count > 0)
                                {
                                    BrightChangeMask[x / n, y] = Math.Max(brightnessDiff1.Average(), brightnessDiff2.Average());
                                }
                                else
                                {
                                    BrightChangeMask[x / n, y] = 0;
                                }

                                if (maxiBrDiff < BrightChangeMask[x / n, y])
                                {
                                    maxiBrDiff = BrightChangeMask[x / n, y];
                                }
                            }
                            else
                            {
                                BrightChangeMask[x / n, y] = 0;
                            }
                        }
                    }
                    bmp1.UnlockBits();
                    bmp2.UnlockBits();
                    bmp3.UnlockBits();

                    for (y = 0; y < ThumbHeight; y++)
                    {
                        for (x = 0; x < ThumbWidth; x++)
                        {
                            if (NonUseMask[x, y] == false)
                            {
                                if (maxiBrDiff > 0)
                                {
                                    newBr = (BrightChangeMask[x, y] * 100) / maxiBrDiff;
                                    if (newBr > 100)
                                    {
                                        newBr = 100;
                                    }
                                    BrightChangeMask[x, y] = Math.Abs(newBr - 100);
                                }
                                else
                                {
                                    BrightChangeMask[x, y] = 100;
                                }
                            }
                            else
                            {
                                BrightChangeMask[x, y] = 0;
                            }

                            if (BrightChangeMask[x, y] < 0.5)
                            {
                                isdark++;
                            }
                        }
                    }

                    if ((isdark * 100) / (ThumbHeight * ThumbWidth) > 97)
                    {
                        throw new ImageTooDarkException();
                    }
                    if (this.GetType() == typeof(ProjectLS))
                    {
                        ((FrameLS)Frames[f]).UsageMask = BrightChangeMask;
                    }

                    #endregion

                    MainWorker.ReportProgress(0, new ProgressChangeEventArgs((f + 1) * 100 / (Frames.Count - 1), ProgressType.CalculateBrightness));

                    #region Brightness

                    count = 0;

                    for (y = 0; y < ThumbHeight; y++)
                    {
                        for (x = 0; x < rowstride; x += n)
                        {
                            index = y * rowstride + x;
                            c     = new ColorRGB(pix1[index], pix1[index + 1], pix1[index + 2], space);
                            fixed(double *pt = c.ValueArray)
                            {
                                ((RGBSpace)c.Space).ToLinear(pt, pt);
                            }

                            br1 = (c.R + c.G + c.B) * 255d / 3d;
                            c   = new ColorRGB(pix2[index], pix2[index + 1], pix2[index + 2], space);
                            fixed(double *pt = c.ValueArray)
                            {
                                ((RGBSpace)c.Space).ToLinear(pt, pt);
                            }

                            br2 = (c.R + c.G + c.B) * 255d / 3d;
                            c   = new ColorRGB(pix3[index], pix3[index + 1], pix3[index + 2], space);
                            fixed(double *pt = c.ValueArray)
                            {
                                ((RGBSpace)c.Space).ToLinear(pt, pt);
                            }

                            br3 = (c.R + c.G + c.B) * 255d / 3d;

                            double factor = BrightChangeMask[x / n, y] / 100;
                            PixelBrightness[count] = new double[3] {
                                br1 *factor, br2 *factor, br3 *factor
                            };
                            count++;
                        }
                    }

                    double val0 = (PixelBrightness.Average(p => p[0]));
                    double val1 = (PixelBrightness.Average(p => p[1]));
                    double val2 = (PixelBrightness.Average(p => p[2]));

                    if (f == 1)
                    {
                        Frames[0].OriginalBrightness = val0;
                    }
                    double val1P = (val1 * 100) / val0;
                    Frames[f].OriginalBrightness = (Frames[f - 1].OriginalBrightness * val1P) / 100;
                    double val2P = (val2 * 100) / val0;
                    Frames[f + 1].OriginalBrightness = (Frames[f - 1].OriginalBrightness * val2P) / 100;

                    Frames[f - 1].AlternativeBrightness = Frames[f - 1].OriginalBrightness;
                    Frames[f].AlternativeBrightness     = Frames[f].OriginalBrightness;
                    Frames[f + 1].AlternativeBrightness = Frames[f + 1].OriginalBrightness;

                    Frames[f - 1].NewBrightness = Frames[f - 1].OriginalBrightness;
                    Frames[f].NewBrightness     = Frames[f].OriginalBrightness;
                    Frames[f + 1].NewBrightness = Frames[f + 1].OriginalBrightness;

                    #endregion
                }
            }

            //LTODO: write statistic/BV-value check
            #region Statistics/BV-Values Check

            /*Status = CalcState.Statistics;
             *
             *  for (int f = 1; f < filecount; f++)
             *  {
             *      if (AllFiles[f].HasExif)
             *      {
             *          double EvP = (Math.Min(AllFiles[f].Brightness, AllFiles[f - 1].Brightness) * 100) / Math.Max(AllFiles[f].Brightness, AllFiles[f - 1].Brightness);
             *          double bv1 = Math.Abs(AllFiles[f - 1].Bv);
             *          double bv2 = Math.Abs(AllFiles[f].Bv);
             *          double BvP = (Math.Min(bv1, bv2) * 100) / Math.Max(bv1, bv2);
             *          if (bv1 < bv2) { BvP *= -1; }
             *          double res = BvP - EvP;
             *          if (AllFiles[f].Brightness < AllFiles[f - 1].Brightness) { res *= -1; }
             *          AllFiles[f].StatisticalError = res;
             *      }
             *      else
             *      {
             *          //do statistical check
             *      }
             *
             *      CalcWorker[0].ReportProgress((int)((((double)f / (double)filecount)) * 100f), Status);
             *  }*/

            #endregion Statistics/BV-Values Check
        }
예제 #2
0
        private void BrCalc_Advanced()
        {
            #region Variables

            BitmapEx bmp1, bmp2, bmp3;
            const int min = 5;
            const int max = 250;

            bmp1 = GetThumb(0, true);

            int isdark, xS, yS;
            const uint ThumbWidth = 300;
            const uint ThumbHeight = 200;
            uint x, y, rowstride, n = bmp1.ChannelCount;
            long index, count;
            double br1, br2, br3, newBr, maxiBrDiff;

            double[,] BrightChangeMask = new double[ThumbWidth, ThumbHeight];
            bool[,] NonUseMask = new bool[ThumbWidth, ThumbHeight];
            double[][] PixelBrightness = new double[ThumbWidth * ThumbHeight][];

            ColorRGB c;

            #endregion

            //TODO: make calculation parallel

            for (int f = 0; f < Frames.Count; f += 2)
            {
                if (MainWorker.CancellationPending) { return; }

                #region Variables

                if (f == 0) { f++; }
                if (f + 2 >= Frames.Count) { f = Frames.Count - 2; }

                bmp1 = GetThumb(f - 1, false).Scale(ThumbWidth, ThumbHeight);
                bmp2 = GetThumb(f, false).Scale(ThumbWidth, ThumbHeight);
                bmp3 = GetThumb(f + 1, false).Scale(ThumbWidth, ThumbHeight);
                rowstride = bmp1.Stride;

                n = bmp1.ChannelCount;
                index = count = isdark = 0;
                br1 = br2 = br3 = newBr = maxiBrDiff = 0;
                RGBSpace space = new RGBColorspacesRGB();

                #endregion

                unsafe
                {
                    bmp1.LockBits();
                    bmp2.LockBits();
                    bmp3.LockBits();

                    byte* pix1 = (byte*)bmp1.Scan0;
                    byte* pix2 = (byte*)bmp2.Scan0;
                    byte* pix3 = (byte*)bmp3.Scan0;

                    #region Mask

                    for (y = 0; y < ThumbHeight; y++)
                    {
                        for (x = 0; x < rowstride; x += n)
                        {
                            index = y * rowstride + x;

                            c = new ColorRGB(pix1[index], pix1[index + 1], pix1[index + 2], space);
                            fixed (double* pt = c.ValueArray) { ((RGBSpace)c.Space).ToLinear(pt, pt); }
                            br1 = (c.R + c.G + c.B) * 255d / 3d;
                            c = new ColorRGB(pix2[index], pix2[index + 1], pix2[index + 2], space);
                            fixed (double* pt = c.ValueArray) { ((RGBSpace)c.Space).ToLinear(pt, pt); }
                            br2 = (c.R + c.G + c.B) * 255d / 3d;
                            c = new ColorRGB(pix3[index], pix3[index + 1], pix3[index + 2], space);
                            fixed (double* pt = c.ValueArray) { ((RGBSpace)c.Space).ToLinear(pt, pt); }
                            br3 = (c.R + c.G + c.B) * 255d / 3d;

                            if (br1 > min && br2 > min && br3 > min && br1 < max && br2 < max && br3 < max) { NonUseMask[x / n, y] = false; }
                            else { NonUseMask[x / n, y] = true; }
                        }
                    }

                    List<double> brightnessDiff1;
                    List<double> brightnessDiff2;

                    for (y = 0; y < ThumbHeight; y++)
                    {
                        for (x = 0; x < bmp1.Stride; x += n)
                        {
                            if (NonUseMask[x / n, y] == false)
                            {
                                count = 0;
                                brightnessDiff1 = new List<double>();
                                brightnessDiff2 = new List<double>();

                                for (yS = -1; yS <= 1; yS++)
                                {
                                    if (y + yS < ThumbHeight && y + yS >= 0)
                                    {
                                        for (xS = -1; xS <= 1; xS++)
                                        {
                                            if (x + xS < rowstride && x + xS >= 0)
                                            {
                                                if (NonUseMask[(x + xS) / n, y + yS] == false)
                                                {
                                                    index = (y + yS) * rowstride + x + xS;

                                                    c = new ColorRGB(pix1[index], pix1[index + 1], pix1[index + 2], space);
                                                    fixed (double* pt = c.ValueArray) { ((RGBSpace)c.Space).ToLinear(pt, pt); }
                                                    br1 = (c.R + c.G + c.B) * 255d / 3d;
                                                    c = new ColorRGB(pix2[index], pix2[index + 1], pix2[index + 2], space);
                                                    fixed (double* pt = c.ValueArray) { ((RGBSpace)c.Space).ToLinear(pt, pt); }
                                                    br2 = (c.R + c.G + c.B) * 255d / 3d;
                                                    c = new ColorRGB(pix3[index], pix3[index + 1], pix3[index + 2], space);
                                                    fixed (double* pt = c.ValueArray) { ((RGBSpace)c.Space).ToLinear(pt, pt); }
                                                    br3 = (c.R + c.G + c.B) * 255d / 3d;

                                                    brightnessDiff1.Add(Math.Abs(br1 - br2));
                                                    brightnessDiff2.Add(Math.Abs(br2 - br3));

                                                    count++;
                                                }
                                            }
                                        }
                                    }
                                }

                                if (count > 0) { BrightChangeMask[x / n, y] = Math.Max(brightnessDiff1.Average(), brightnessDiff2.Average()); }
                                else { BrightChangeMask[x / n, y] = 0; }

                                if (maxiBrDiff < BrightChangeMask[x / n, y]) { maxiBrDiff = BrightChangeMask[x / n, y]; }
                            }
                            else { BrightChangeMask[x / n, y] = 0; }
                        }
                    }
                    bmp1.UnlockBits();
                    bmp2.UnlockBits();
                    bmp3.UnlockBits();

                    for (y = 0; y < ThumbHeight; y++)
                    {
                        for (x = 0; x < ThumbWidth; x++)
                        {
                            if (NonUseMask[x, y] == false)
                            {
                                if (maxiBrDiff > 0)
                                {
                                    newBr = (BrightChangeMask[x, y] * 100) / maxiBrDiff;
                                    if (newBr > 100) { newBr = 100; }
                                    BrightChangeMask[x, y] = Math.Abs(newBr - 100);
                                }
                                else { BrightChangeMask[x, y] = 100; }
                            }
                            else { BrightChangeMask[x, y] = 0; }

                            if (BrightChangeMask[x, y] < 0.5) { isdark++; }
                        }
                    }

                    if ((isdark * 100) / (ThumbHeight * ThumbWidth) > 97) { throw new ImageTooDarkException(); }
                    if (this.GetType() == typeof(ProjectLS)) { ((FrameLS)Frames[f]).UsageMask = BrightChangeMask; }

                    #endregion

                    MainWorker.ReportProgress(0, new ProgressChangeEventArgs((f + 1) * 100 / (Frames.Count - 1), ProgressType.CalculateBrightness));

                    #region Brightness

                    count = 0;

                    for (y = 0; y < ThumbHeight; y++)
                    {
                        for (x = 0; x < rowstride; x += n)
                        {
                            index = y * rowstride + x;
                            c = new ColorRGB(pix1[index], pix1[index + 1], pix1[index + 2], space);
                            fixed (double* pt = c.ValueArray) { ((RGBSpace)c.Space).ToLinear(pt, pt); }
                            br1 = (c.R + c.G + c.B) * 255d / 3d;
                            c = new ColorRGB(pix2[index], pix2[index + 1], pix2[index + 2], space);
                            fixed (double* pt = c.ValueArray) { ((RGBSpace)c.Space).ToLinear(pt, pt); }
                            br2 = (c.R + c.G + c.B) * 255d / 3d;
                            c = new ColorRGB(pix3[index], pix3[index + 1], pix3[index + 2], space);
                            fixed (double* pt = c.ValueArray) { ((RGBSpace)c.Space).ToLinear(pt, pt); }
                            br3 = (c.R + c.G + c.B) * 255d / 3d;

                            double factor = BrightChangeMask[x / n, y] / 100;
                            PixelBrightness[count] = new double[3] { br1 * factor, br2 * factor, br3 * factor };
                            count++;
                        }
                    }

                    double val0 = (PixelBrightness.Average(p => p[0]));
                    double val1 = (PixelBrightness.Average(p => p[1]));
                    double val2 = (PixelBrightness.Average(p => p[2]));

                    if (f == 1) { Frames[0].OriginalBrightness = val0; }
                    double val1P = (val1 * 100) / val0;
                    Frames[f].OriginalBrightness = (Frames[f - 1].OriginalBrightness * val1P) / 100;
                    double val2P = (val2 * 100) / val0;
                    Frames[f + 1].OriginalBrightness = (Frames[f - 1].OriginalBrightness * val2P) / 100;

                    Frames[f - 1].AlternativeBrightness = Frames[f - 1].OriginalBrightness;
                    Frames[f].AlternativeBrightness = Frames[f].OriginalBrightness;
                    Frames[f + 1].AlternativeBrightness = Frames[f + 1].OriginalBrightness;

                    Frames[f - 1].NewBrightness = Frames[f - 1].OriginalBrightness;
                    Frames[f].NewBrightness = Frames[f].OriginalBrightness;
                    Frames[f + 1].NewBrightness = Frames[f + 1].OriginalBrightness;

                    #endregion
                }
            }

            //LTODO: write statistic/BV-value check
            #region Statistics/BV-Values Check

            /*Status = CalcState.Statistics;

                for (int f = 1; f < filecount; f++)
                {
                    if (AllFiles[f].HasExif)
                    {
                        double EvP = (Math.Min(AllFiles[f].Brightness, AllFiles[f - 1].Brightness) * 100) / Math.Max(AllFiles[f].Brightness, AllFiles[f - 1].Brightness);
                        double bv1 = Math.Abs(AllFiles[f - 1].Bv);
                        double bv2 = Math.Abs(AllFiles[f].Bv);
                        double BvP = (Math.Min(bv1, bv2) * 100) / Math.Max(bv1, bv2);
                        if (bv1 < bv2) { BvP *= -1; }
                        double res = BvP - EvP;
                        if (AllFiles[f].Brightness < AllFiles[f - 1].Brightness) { res *= -1; }
                        AllFiles[f].StatisticalError = res;
                    }
                    else
                    {
                        //do statistical check
                    }

                    CalcWorker[0].ReportProgress((int)((((double)f / (double)filecount)) * 100f), Status);
                }*/

            #endregion Statistics/BV-Values Check
        }