예제 #1
0
        /// <summary>
        /// Computes the pixel variances and their average
        /// </summary>
        public override void OnEndIteration(int curIteration)
        {
            // Update the mean and moment based on the buffered image of the current iteration
            Parallel.For(0, momentImage.Height, row => {
                for (int col = 0; col < momentImage.Width; ++col)
                {
                    float val = bufferImage.GetPixel(col, row);
                    momentImage.AtomicAdd(col, row, val * val / curIteration);
                    meanImage.AtomicAdd(col, row, val / curIteration);
                }
            });

            // Blur both buffers to get a more stable estimate.
            // TODO this could be done in-place by directly splatting in multiple pixels above
            BoxFilter       filter        = new(1);
            MonochromeImage blurredMean   = new(meanImage.Width, meanImage.Height);
            MonochromeImage blurredMoment = new(meanImage.Width, meanImage.Height);

            filter.Apply(meanImage, blurredMean);
            filter.Apply(momentImage, blurredMoment);

            // Compute the final variance and update the main image
            Average = 0;
            Parallel.For(0, momentImage.Height, row => {
                for (int col = 0; col < momentImage.Width; ++col)
                {
                    float mean     = blurredMean.GetPixel(col, row);
                    float variance = blurredMoment.GetPixel(col, row) - mean * mean;
                    variance      /= (mean * mean + 0.001f);
                    Image.SetPixelChannel(col, row, 0, variance);
                    Atomic.AddFloat(ref Average, variance);
                }
            });
            Average /= momentImage.Height * momentImage.Width;
        }