Пример #1
0
        /// <summary>
        /// Transform this image to a greyscale version out-of-place
        /// </summary>
        /// <param name="source">The source image</param>
        /// <param name="output">The image to write to</param>
        /// <returns>The output writable lockbit image</returns>
        public static WritableLockBitImage Transform(WritableLockBitImage source, WritableLockBitImage output)
        {
            if (source.Locked || output.Locked)
            {
                throw new ArgumentException("Lockbit image is locked.");
            }

            for (int y = 0; y < source.Height; y++)
            {
                for (int x = 0; x < source.Width; x++)
                {
                    Color sourcePixel = source.GetPixel(x, y);

                    int greyColor =
                        (int)Math.Floor(sourcePixel.R * 0.299) +
                        (int)Math.Floor(sourcePixel.G * 0.587) +
                        (int)Math.Floor(sourcePixel.B * 0.114);

                    Color greyScale = Color.FromArgb(
                        greyColor,
                        greyColor,
                        greyColor
                        );
                    output.SetPixel(x, y, greyScale);
                }
            }

            return(output);
        }
Пример #2
0
        public static WritableLockBitImage Transform(
            WritableLockBitImage sourceImage,
            int radius = 3
            )
        {
            using (var copyOfSourceImage = new WritableLockBitImage(sourceImage))
            {
                WritableLockBitImage outputImage = new WritableLockBitImage(sourceImage.Width, sourceImage.Height);
                int index = 0;
                foreach (int boxWidth in EnumerateBoxesForGauss(radius, 3))
                {
                    if (index % 2 == 0)
                    {
                        PerformSplitBoxBlurAcc(copyOfSourceImage, outputImage, (boxWidth - 1) / 2);
                    }
                    else
                    {
                        // Switching of outputImage and copyOfSourceImage is INTENTIONAL!
                        PerformSplitBoxBlurAcc(outputImage, copyOfSourceImage, (boxWidth - 1) / 2);
                    }
                    index++;
                }

                return(outputImage);
            }
        }
Пример #3
0
 /// <summary>
 /// Resize the image to the destination width and height
 /// </summary>
 public static WritableLockBitImage Transform(WritableLockBitImage sourceImage, int width, int height)
 {
     using (WritableLockBitImage copyOfSourceImage = new WritableLockBitImage(sourceImage))
     {
         copyOfSourceImage.Lock();
         return(new WritableLockBitImage(Transform(copyOfSourceImage.GetImage(), width, height)));
     }
 }
Пример #4
0
 private static WritableLockBitImage ApplySobelFilter(WritableLockBitImage sourceImage)
 {
     return(CalculateContour(
                CalculateHorizontalSobelMatrix(sourceImage),
                CalculateVerticalSobelMatrix(sourceImage),
                sourceImage.Width,
                sourceImage.Height
                ));
 }
Пример #5
0
 private static void CopyPixels(WritableLockBitImage sourceImage, WritableLockBitImage destImage)
 {
     for (int row = 0; row < sourceImage.Height; row++)
     {
         for (int col = 0; col < sourceImage.Width; col++)
         {
             destImage.SetPixel(col, row, sourceImage.GetPixel(col, row));
         }
     }
 }
Пример #6
0
        private void RunQueue()
        {
            int currentFrame = 0;
            int frameSize    = 3 * _width * _height;

            byte[] frameBuffer  = new byte[frameSize];
            int    currentIndex = 0;

            try
            {
                foreach (byte[] rawBytes in _rawByteQueue.GetConsumingEnumerable())
                {
                    // Raw bytes don't overflow frame
                    if (rawBytes.Length < frameSize - currentIndex)
                    {
                        Buffer.BlockCopy(rawBytes, 0, frameBuffer, currentIndex, rawBytes.Length);
                        currentIndex += rawBytes.Length;
                    }
                    // Raw bytes overflow frame
                    else
                    {
                        int numBytesToCopy = frameSize - currentIndex;
                        Buffer.BlockCopy(rawBytes, 0, frameBuffer, currentIndex, numBytesToCopy);

                        // Frame is now full. Create image and ship it off
                        WritableLockBitImage frame = new WritableLockBitImage(_width, _height, frameBuffer);
                        frame.Lock();

                        _videoIndexer.SubmitVideoFrame(frame, currentFrame);
                        currentFrame++;

                        // Write overflow stuff now
                        Buffer.BlockCopy(rawBytes, numBytesToCopy, frameBuffer, 0, rawBytes.Length - numBytesToCopy);
                        currentIndex = rawBytes.Length - numBytesToCopy;
                    }

                    // Reduce the amount of bytes
                    long currentMemoryLevels = Interlocked.Add(ref _currentMemoryLevel, -rawBytes.Length);

                    // Check capacity and set or reset the barrier
                    if (currentMemoryLevels < _maxCapacity)
                    {
                        _capacityBarrier.Set();
                    }
                    else
                    {
                        _capacityBarrier.Reset();
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Shutdown();
            }
        }
Пример #7
0
        private static WritableLockBitImage PerformSplitBoxBlurAcc(
            WritableLockBitImage sourceImage,
            int radius
            )
        {
            var outputImage = new WritableLockBitImage(sourceImage);

            // The switching of outputImage and souceImage is INTENTIONAL!
            PerformHorizontalBoxBlurAcc(outputImage, sourceImage, radius);
            PerformTotalBoxBlurAcc(sourceImage, outputImage, radius);

            return(outputImage);
        }
Пример #8
0
        private static byte[] CalculateGrayScaleThumbnail(WritableLockBitImage image)
        {
            byte[] buffer = new byte[image.Width * image.Height];
            for (int row = 0; row < image.Height; row++)
            {
                for (int col = 0; col < image.Width; col++)
                {
                    buffer[row * image.Width + col] = image.GetPixel(col, row).R;
                }
            }

            return(ByteCompressor.Compress(buffer));
        }
Пример #9
0
        private static WritableLockBitImage PerformSplitBoxBlurAcc(
            WritableLockBitImage sourceImage,
            WritableLockBitImage outputImage,
            int radius
            )
        {
            // Must copy pixels from source to output
            CopyPixels(sourceImage, outputImage);

            // The switching of outputImage and souceImage is INTENTIONAL!
            PerformHorizontalBoxBlurAcc(outputImage, sourceImage, radius);
            PerformTotalBoxBlurAcc(sourceImage, outputImage, radius);

            return(outputImage);
        }
Пример #10
0
        private static WritableLockBitImage GetFrameFromVideo(VideoFingerPrintWrapper video, int frameNumber)
        {
            using (MediaInfoProcess mediaInfoProcess = new MediaInfoProcess(video.FilePath))
            {
                MediaInfo mediaInfo = mediaInfoProcess.Execute();
                if (mediaInfo.GetFramerate().Numerator == 0)
                {
                    throw new Exception("Did not get valid frame rate");
                }

                int width  = mediaInfo.GetWidth();
                int height = mediaInfo.GetHeight();
                var ffmpegProcessSettings = new FFMPEGProcessVideoSettings(
                    video.FilePath,
                    mediaInfo.GetFramerate().Numerator,
                    mediaInfo.GetFramerate().Denominator * 4,
                    FFMPEGMode.SeekFrame
                    );

                ffmpegProcessSettings.TargetFrame = frameNumber;
                byte[] frameBytes = new byte[width * height * 3];
                int    offset     = 0;
                using (
                    var ffmpegProcess = new FFMPEGProcess(
                        ffmpegProcessSettings,
                        (stdoutBytes, numBytes) =>
                {
                    Buffer.BlockCopy(stdoutBytes, 0, frameBytes, offset, numBytes);
                    offset += numBytes;
                },
                        false
                        )
                    )
                {
                    ffmpegProcess.Execute();
                    if (offset != 3 * width * height)
                    {
                        throw new Exception("Did not get all bytes to produce valid frame");
                    }

                    WritableLockBitImage videoFrame = new WritableLockBitImage(width, height, frameBytes);
                    videoFrame.Lock();
                    return(videoFrame);
                }
            }
        }
        public void SubmitVideoFrame(WritableLockBitImage frame, int frameNumber)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException("this");
            }

            // Wait until capacity is available
            _capacityBarrier.Wait();

            Interlocked.Add(ref _currentMemoryLevel, frame.MemorySize);

            _buffer.Add(new WorkItem
            {
                FrameNumber = frameNumber,
                Frame       = frame,
            });
        }
Пример #12
0
        /// <summary>
        /// Quantisize a photo by ceiling or flooring each value depending one whether it's above or below the median value
        /// </summary>
        /// <param name="sourceImage">The source image</param>
        /// <param name="outputImage">The image to write to</param>
        /// <param name="maxValue">The value to quantize the maximum value to</param>
        /// <returns>The output image, but returned for convenience</returns>
        public static WritableLockBitImage Transform(WritableLockBitImage sourceImage, WritableLockBitImage outputImage, byte maxValue = byte.MaxValue)
        {
            Color medianColor = GetMedianColorValue(sourceImage);

            for (int row = 0; row < sourceImage.Height; row++)
            {
                for (int col = 0; col < sourceImage.Width; col++)
                {
                    // Quantisize the individual channels
                    Color currentColor = sourceImage.GetPixel(col, row);
                    byte  outputRed, outputGreen, outputBlue;
                    if (currentColor.R < medianColor.R)
                    {
                        outputRed = 0;
                    }
                    else
                    {
                        outputRed = maxValue;
                    }

                    if (currentColor.G < medianColor.G)
                    {
                        outputGreen = 0;
                    }
                    else
                    {
                        outputGreen = maxValue;
                    }

                    if (currentColor.B < medianColor.B)
                    {
                        outputBlue = 0;
                    }
                    else
                    {
                        outputBlue = maxValue;
                    }

                    outputImage.SetPixel(col, row, Color.FromArgb(outputRed, outputGreen, outputBlue));
                }
            }

            return(outputImage);
        }
Пример #13
0
        private static VideoFingerPrintWrapper FindMostLikelyVideo(
            PhotoFingerPrintWrapper photo,
            IDictionary <string, ISet <FrameMetricWrapper> > treeResults,
            IDictionary <string, VideoFingerPrintWrapper> nameToVideoMap
            )
        {
            if (treeResults.Count() == 1)
            {
                return(treeResults.First().Value.First().Video);
            }

            using (WritableLockBitImage photoAsLockBitImage = new WritableLockBitImage(Image.FromFile(photo.FilePath)))
            {
                // Filter on grayscale results first
                List <FrameMetricWrapper> filteredOnGrayScaleResults = (from videoFrameResults in treeResults
                                                                        from frameMetricWrapper in videoFrameResults.Value
                                                                        where DistanceCalculator.CalculateHammingDistance(photo.EdgeGrayScaleThumb, frameMetricWrapper.Frame.EdgeGrayScaleThumb) < 2
                                                                        select frameMetricWrapper).ToList();

                if (filteredOnGrayScaleResults.Count == 1)
                {
                    return(filteredOnGrayScaleResults.First().Video);
                }

                double currentBestSSIM = 0.0;
                VideoFingerPrintWrapper currentBestVideo = null;
                foreach (FrameMetricWrapper FrameMetricWrapper in filteredOnGrayScaleResults)
                {
                    // Calculate SSIM
                    using (WritableLockBitImage videoFrame = GetFrameFromVideo(FrameMetricWrapper.Video, FrameMetricWrapper.Frame.FrameNumber))
                    {
                        double possibleBestSSIM = SSIMCalculator.Compute(photoAsLockBitImage, videoFrame);
                        // SSIM must be at least good enough for us to consider
                        if (possibleBestSSIM > currentBestSSIM)
                        {
                            currentBestSSIM  = possibleBestSSIM;
                            currentBestVideo = FrameMetricWrapper.Video;
                        }
                    }
                }

                return(currentBestVideo);
            }
        }
Пример #14
0
        /// <summary>
        /// Calculate the DCT
        /// </summary>
        /// <param name="sourceImage">The source image to find the DCT of</param>
        /// <returns>The DCT coefficients</returns>
        public static double[,] Transform(WritableLockBitImage sourceImage)
        {
            if (sourceImage.Width != sourceImage.Height)
            {
                throw new ArgumentException("DCTs can only be calculated on square matrices");
            }

            byte[,] sourceMatrix = new byte[sourceImage.Height, sourceImage.Width];
            for (int y = 0; y < sourceImage.Height; y++)
            {
                for (int x = 0; x < sourceImage.Width; x++)
                {
                    // We only need the greyscale (luminance)
                    sourceMatrix[y, x] = sourceImage.GetPixel(x, y).R;
                }
            }

            return(Calculate(sourceMatrix));
        }
Пример #15
0
        private static Color GetMedianColorValue(WritableLockBitImage sourceImage)
        {
            var setOfRedColorValues   = new HashSet <int>();
            var setOfGreenColorValues = new HashSet <int>();
            var setOfBlueColorValues  = new HashSet <int>();

            for (int row = 0; row < sourceImage.Height; row++)
            {
                for (int col = 0; col < sourceImage.Width; col++)
                {
                    Color color = sourceImage.GetPixel(col, row);
                    setOfRedColorValues.Add(color.R);
                    setOfGreenColorValues.Add(color.G);
                    setOfBlueColorValues.Add(color.B);
                }
            }

            List <int> listOfRedColorValues   = setOfRedColorValues.ToList();
            List <int> listOfGreenColorValues = setOfRedColorValues.ToList();
            List <int> listOfBlueColorValues  = setOfRedColorValues.ToList();

            listOfRedColorValues.Sort();
            listOfGreenColorValues.Sort();
            listOfBlueColorValues.Sort();

            int count = listOfRedColorValues.Count;
            int medianRed, medianGreen, medianBlue;

            if (count % 2 == 0)
            {
                medianRed   = (int)Math.Round((listOfRedColorValues[count / 2] + listOfRedColorValues[count / 2 - 1]) / 2.0);
                medianGreen = (int)Math.Round((listOfGreenColorValues[count / 2] + listOfGreenColorValues[count / 2 - 1]) / 2.0);
                medianBlue  = (int)Math.Round((listOfBlueColorValues[count / 2] + listOfBlueColorValues[count / 2 - 1]) / 2.0);
            }
            else
            {
                medianRed   = listOfRedColorValues[count / 2];
                medianGreen = listOfGreenColorValues[count / 2];
                medianBlue  = listOfBlueColorValues[count / 2];
            }

            return(Color.FromArgb(medianRed, medianGreen, medianBlue));
        }
Пример #16
0
        private static WritableLockBitImage CalculateContour(int[] horizontalMatrix, int[] verticalMatrix, int width, int height)
        {
            WritableLockBitImage outputImage = new WritableLockBitImage(width, height);

            for (int row = 0; row < height; row++)
            {
                for (int col = 0; col < width; col++)
                {
                    int  horizontalValue = horizontalMatrix[row * width + col];
                    int  verticalValue   = verticalMatrix[row * width + col];
                    byte pixelValue      = (byte)Math.Round(Math.Sqrt(
                                                                (horizontalValue * horizontalValue) +
                                                                (verticalValue * verticalValue)
                                                                ));

                    outputImage.SetPixel(col, row, Color.FromArgb(pixelValue, pixelValue, pixelValue));
                }
            }
            return(outputImage);
        }
Пример #17
0
        private static Tuple <ulong, byte[]> CalcluateFramePerceptionHash(Image frame, bool shouldDoEdgeDetection)
        {
            using (WritableLockBitImage resizedImage = new WritableLockBitImage(ResizeTransformation.Transform(frame, FingerPrintWidth, FingerPrintWidth)))
                using (WritableLockBitImage grayscaleImage = GreyScaleTransformation.TransformInPlace(resizedImage))
                    using (WritableLockBitImage blurredImage = FastGaussianBlur.Transform(grayscaleImage))
                    {
                        double[,] dctMatrix = FastDCTCalculator.Transform(blurredImage);
                        double medianOfDCTValue = CalculateMedianDCTValue(dctMatrix);
                        ulong  hashCode         = ConstructHashCode(dctMatrix, medianOfDCTValue);
                        if (shouldDoEdgeDetection)
                        {
                            using (WritableLockBitImage sobelImage = SobelFilter.TransformWithGrayScaleImage(grayscaleImage))
                                using (WritableLockBitImage quantisizedImage = QuantisizingFilter.TransformInPlace(sobelImage, 1))
                                    using (WritableLockBitImage resizedQuantisizedImage = ResizeTransformation.Transform(quantisizedImage, 16, 16))
                                    {
                                        return(Tuple.Create(hashCode, CalculateGrayScaleThumbnail(resizedQuantisizedImage)));
                                    }
                        }

                        return(Tuple.Create <ulong, byte[]>(hashCode, null));
                    }
        }
        private void RunConsumer()
        {
            try
            {
                foreach (WorkItem item in _buffer.GetConsumingEnumerable())
                {
                    using (WritableLockBitImage frame = item.Frame)
                    {
                        frame.Lock();
                        Tuple <ulong, byte[]> fingerPrintHashTuple = FrameIndexer.IndexFrame(item.Frame.GetImage());
                        _fingerPrints.Add(new FrameFingerPrintWrapper
                        {
                            PHashCode          = fingerPrintHashTuple.Item1,
                            FrameNumber        = item.FrameNumber,
                            EdgeGrayScaleThumb = fingerPrintHashTuple.Item2,
                        });

                        // Reduce the current memory level
                        long currentMemoryLevels = Interlocked.Add(ref _currentMemoryLevel, -frame.MemorySize);

                        // Check capacity
                        if (currentMemoryLevels < _maxCapacity)
                        {
                            // If we have space, set event
                            _capacityBarrier.Set();
                        }
                        else
                        {
                            // Otherwise, reset the event
                            _capacityBarrier.Reset();
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Shutdown();
            }
        }
Пример #19
0
        private static int[] CoreCalculateSobelMatrix(WritableLockBitImage sourceImage, int[] firstKernel, int[] secondKernel)
        {
            // Go through each pixel in the source image
            int[] intermediateResult = new int[sourceImage.Height * sourceImage.Width];
            int[] inputBuffer        = new int[3];
            int   width = sourceImage.Width;

            for (int row = 0; row < sourceImage.Height; row++)
            {
                for (int col = 0; col < sourceImage.Width; col++)
                {
                    // Set the input buffer
                    inputBuffer[0] = col > 0 ? sourceImage.GetPixel(col - 1, row).R : 0;
                    inputBuffer[1] = sourceImage.GetPixel(col, row).R;
                    inputBuffer[2] = col < sourceImage.Width - 1 ? sourceImage.GetPixel(col + 1, row).R : 0;

                    // Convolute it with the vector
                    intermediateResult[row * width + col] = ConvoluteOneDimensionalVector(inputBuffer, firstKernel);
                }
            }

            // Go through each result in the intermediate result
            int[] finalMatrix = new int[sourceImage.Height * sourceImage.Width];
            for (int row = 0; row < sourceImage.Height; row++)
            {
                for (int col = 0; col < sourceImage.Width; col++)
                {
                    // Set input buffer
                    inputBuffer[0] = row > 0 ? intermediateResult[((row - 1) * width) + col] : 0;
                    inputBuffer[1] = intermediateResult[row * width + col];
                    inputBuffer[2] = row < sourceImage.Height - 1 ? intermediateResult[((row + 1) * width) + col] : 0;

                    // Convolute it with the second vector
                    finalMatrix[row * width + col] = ConvoluteOneDimensionalVector(inputBuffer, secondKernel);
                }
            }

            return(finalMatrix);
        }
Пример #20
0
        private static void PerformHorizontalBoxBlurAcc(WritableLockBitImage sourceImage, WritableLockBitImage outputImage, int radius)
        {
            double iarr = 1 / ((double)radius + radius + 1);

            for (int row = 0; row < sourceImage.Height; row++)
            {
                Color firstPixel    = sourceImage.GetPixel(0, row);
                Color lastPixel     = sourceImage.GetPixel(sourceImage.Width - 1, row);
                int   cumRedValue   = (radius + 1) * firstPixel.R;
                int   cumGreenValue = (radius + 1) * firstPixel.G;
                int   cumBlueValue  = (radius + 1) * firstPixel.B;

                int currentLastColIndex   = 0;      // li
                int currentRadiusColIndex = radius; // ri

                for (int col = 0; col < radius; col++)
                {
                    Color chosenPixel = sourceImage.GetPixel(col, row);
                    cumRedValue   += chosenPixel.R;
                    cumGreenValue += chosenPixel.G;
                    cumBlueValue  += chosenPixel.B;
                }

                for (int col = 0; col <= radius; col++)
                {
                    Color chosenPixel = sourceImage.GetPixel(currentRadiusColIndex, row);
                    cumRedValue   += chosenPixel.R - firstPixel.R;
                    cumGreenValue += chosenPixel.G - firstPixel.G;
                    cumBlueValue  += chosenPixel.B - firstPixel.B;
                    currentRadiusColIndex++;

                    outputImage.SetPixel(
                        col,
                        row,
                        Color.FromArgb(
                            (int)Math.Round(cumRedValue * iarr),
                            (int)Math.Round(cumGreenValue * iarr),
                            (int)Math.Round(cumBlueValue * iarr)
                            )
                        );
                }

                for (int col = radius + 1; col < sourceImage.Width - radius; col++)
                {
                    Color chosenRadiusPixel = sourceImage.GetPixel(currentRadiusColIndex, row);
                    Color chosenLastPixel   = sourceImage.GetPixel(currentLastColIndex, row);
                    cumRedValue   += chosenRadiusPixel.R - chosenLastPixel.R;
                    cumGreenValue += chosenRadiusPixel.G - chosenLastPixel.G;
                    cumBlueValue  += chosenRadiusPixel.B - chosenLastPixel.B;
                    currentRadiusColIndex++;
                    currentLastColIndex++;

                    outputImage.SetPixel(
                        col,
                        row,
                        Color.FromArgb(
                            (int)Math.Round(cumRedValue * iarr),
                            (int)Math.Round(cumGreenValue * iarr),
                            (int)Math.Round(cumBlueValue * iarr)
                            )
                        );
                }

                for (int col = sourceImage.Width - radius; col < sourceImage.Width; col++)
                {
                    Color chosenLastPixel = sourceImage.GetPixel(currentLastColIndex, row);
                    cumRedValue   += lastPixel.R - chosenLastPixel.R;
                    cumGreenValue += lastPixel.G - chosenLastPixel.G;
                    cumBlueValue  += lastPixel.B - chosenLastPixel.B;
                    currentLastColIndex++;

                    outputImage.SetPixel(
                        col,
                        row,
                        Color.FromArgb(
                            (int)Math.Round(cumRedValue * iarr),
                            (int)Math.Round(cumGreenValue * iarr),
                            (int)Math.Round(cumBlueValue * iarr)
                            )
                        );
                }
            }
        }
Пример #21
0
 /// <summary>
 /// Transform this image to a greyscale version in-place
 /// </summary>
 /// <remarks>This will transform the image INPLACE</remarks>
 /// <returns>A black and white image. This reference is equal to the input</returns>
 public static WritableLockBitImage TransformInPlace(WritableLockBitImage image)
 {
     Transform(image, image);
     return(image);
 }
Пример #22
0
 public static WritableLockBitImage TransformInPlace(WritableLockBitImage sourceImage, byte maxValue = byte.MaxValue)
 {
     return(Transform(sourceImage, sourceImage, maxValue));
 }
Пример #23
0
        private static void PerformTotalBoxBlurAcc(WritableLockBitImage sourceImage, WritableLockBitImage outputImage, int radius)
        {
            double iarr = 1 / ((double)radius + radius + 1);

            for (int col = 0; col < sourceImage.Width; col++)
            {
                Color topPixel    = sourceImage.GetPixel(col, 0);
                Color bottomPixel = sourceImage.GetPixel(col, sourceImage.Height - 1);

                int cumRedValue   = (radius + 1) * topPixel.R;
                int cumGreenValue = (radius + 1) * topPixel.G;
                int cumBlueValue  = (radius + 1) * topPixel.B;

                for (int row = 0; row < radius; row++)
                {
                    Color chosenPixel = sourceImage.GetPixel(col, row);
                    cumRedValue   += chosenPixel.R;
                    cumGreenValue += chosenPixel.G;
                    cumBlueValue  += chosenPixel.B;
                }

                for (int row = 0; row <= radius; row++)
                {
                    Color chosenPixel = sourceImage.GetPixel(col, row + radius);
                    cumRedValue   += chosenPixel.R - topPixel.R;
                    cumGreenValue += chosenPixel.G - topPixel.G;
                    cumBlueValue  += chosenPixel.B - topPixel.B;

                    outputImage.SetPixel(
                        col,
                        row,
                        Color.FromArgb(
                            (int)Math.Round(cumRedValue * iarr),
                            (int)Math.Round(cumGreenValue * iarr),
                            (int)Math.Round(cumBlueValue * iarr)
                            )
                        );
                }

                for (int row = radius + 1; row < sourceImage.Height - radius; row++)
                {
                    Color radiusPixel  = sourceImage.GetPixel(col, radius + row);
                    Color laggingPixel = sourceImage.GetPixel(col, row - radius - 1);
                    cumRedValue   += radiusPixel.R - laggingPixel.R;
                    cumGreenValue += radiusPixel.G - laggingPixel.G;
                    cumBlueValue  += radiusPixel.B - laggingPixel.B;

                    outputImage.SetPixel(
                        col,
                        row,
                        Color.FromArgb(
                            (int)Math.Round(cumRedValue * iarr),
                            (int)Math.Round(cumGreenValue * iarr),
                            (int)Math.Round(cumBlueValue * iarr)
                            )
                        );
                }

                for (int row = sourceImage.Height - radius; row < sourceImage.Height; row++)
                {
                    Color laggingPixel = sourceImage.GetPixel(col, row - radius);
                    cumRedValue   += bottomPixel.R - laggingPixel.R;
                    cumGreenValue += bottomPixel.G - laggingPixel.G;
                    cumBlueValue  += bottomPixel.B - laggingPixel.B;

                    outputImage.SetPixel(
                        col,
                        row,
                        Color.FromArgb(
                            (int)Math.Round(cumRedValue * iarr),
                            (int)Math.Round(cumGreenValue * iarr),
                            (int)Math.Round(cumBlueValue * iarr)
                            )
                        );
                }
            }
        }
Пример #24
0
 private static int[] CalculateVerticalSobelMatrix(WritableLockBitImage sourceImage)
 {
     return(CoreCalculateSobelMatrix(sourceImage, VerticalMatrixStep1, VerticalMatrixStep2));
 }
Пример #25
0
 /// <summary>
 /// Performs the Sobel Filter on the given gray scale image
 /// </summary>
 /// <param name="grayScaleImage"></param>
 /// <returns></returns>
 public static WritableLockBitImage TransformWithGrayScaleImage(WritableLockBitImage grayScaleImage)
 {
     return(ApplySobelFilter(grayScaleImage));
 }