Resize image using nearest neighbor algorithm.

The class implements image resizing filter using nearest neighbor algorithm, which does not assume any interpolation.

The filter accepts 8 and 16 bpp grayscale images and 24, 32, 48 and 64 bpp color images for processing.

Sample usage:

// create filter ResizeNearestNeighbor filter = new ResizeNearestNeighbor( 400, 300 ); // apply the filter Bitmap newImage = filter.Apply( image );

Initial image:

Result image:

Inheritance: BaseResizeFilter
Example #1
0
        private void SetFilter()
        {
            ImageType = ImageTypes.Rgb24bpp;

            switch (mode)
            {
            case Modes.Bicubic:
                Af.ResizeBicubic newFilterA = new Af.ResizeBicubic(width, height);
                imageFilter = newFilterA;
                break;

            case Modes.Bilinear:
                Af.ResizeBilinear newFilterB = new Af.ResizeBilinear(width, height);
                imageFilter = newFilterB;
                break;

            case Modes.Nearest:
                Af.ResizeNearestNeighbor newFilterC = new Af.ResizeNearestNeighbor(width, height);
                imageFilter = newFilterC;
                break;
            }
        }
Example #2
0
        public void ConvertTest4()
        {
            // Create an array representation 
            // of a 4x4 image with a inner 2x2
            // square drawn in the middle

            Color[] pixels = 
            {
                 Color.Black, Color.Black,       Color.Black, Color.Black, 
                 Color.Black, Color.Transparent, Color.Red,   Color.Black, 
                 Color.Black, Color.Green,       Color.Blue,  Color.Black, 
                 Color.Black, Color.Black,       Color.Black,  Color.Black, 
            };

            // Create the converter to create a Bitmap from the array
            ArrayToImage conv = new ArrayToImage(width: 4, height: 4);

            // Declare an image and store the pixels on it
            Bitmap image; conv.Convert(pixels, out image);

            // Show the image on screen
            image = new ResizeNearestNeighbor(320, 320).Apply(image);
            // Accord.Controls.ImageBox.Show(image, PictureBoxSizeMode.Zoom);

            Assert.AreEqual(0, conv.Min);
            Assert.AreEqual(1, conv.Max);
            Assert.AreEqual(320, image.Height);
            Assert.AreEqual(320, image.Width);
        }
        public void ConvertTest3()
        {
            double[] pixels = 
            {
                 0, 0, 0, 0,
                 0, 1, 1, 0,
                 0, 1, 1, 0,
                 0, 0, 0, 0,
            };


            ArrayToImage conv1 = new ArrayToImage(width: 4, height: 4);
            Bitmap image;
            conv1.Convert(pixels, out image);
            image = new ResizeNearestNeighbor(16, 16).Apply(image);


            // Obtain an image
            // Bitmap image = ...

            // Show on screen
            //ImageBox.Show(image, PictureBoxSizeMode.Zoom);

            // Create the converter to convert the image to a
            //  matrix containing only values between 0 and 1 
            ImageToMatrix conv = new ImageToMatrix(min: 0, max: 1);

            // Convert the image and store it in the matrix
            double[,] matrix; conv.Convert(image, out matrix);

            /*
                        // Show the matrix on screen as an image
                        ImageBox.Show(matrix, PictureBoxSizeMode.Zoom);


                        // Show the matrix on screen as a .NET multidimensional array
                        MessageBox.Show(matrix.ToString(CSharpMatrixFormatProvider.InvariantCulture));

                        // Show the matrix on screen as a table
                        DataGridBox.Show(matrix, nonBlocking: true)
                            .SetAutoSizeColumns(DataGridViewAutoSizeColumnsMode.Fill)
                            .SetAutoSizeRows(DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders)
                            .SetDefaultFontSize(5)
                            .WaitForClose();
            */

            Assert.AreEqual(0, matrix.Min());
            Assert.AreEqual(1, matrix.Max());
            Assert.AreEqual(16 * 16, matrix.Length);
        }
        public void ConvertTest2()
        {
            // Create a matrix representation 
            // of a 4x4 image with a inner 2x2
            // square drawn in the middle

            double[,] pixels = 
            {
                { 0, 0, 0, 0 },
                { 0, 1, 1, 0 },
                { 0, 1, 1, 0 },
                { 0, 0, 0, 0 },
            };

            // Create the converter to convert the matrix to a image
            MatrixToImage conv = new MatrixToImage(min: 0, max: 1);

            // Declare an image and store the pixels on it
            Bitmap image; conv.Convert(pixels, out image);

            // Show the image on screen
            image = new ResizeNearestNeighbor(320, 320).Apply(image);
            // ImageBox.Show(image, PictureBoxSizeMode.Zoom);

            Assert.AreEqual(0, conv.Min);
            Assert.AreEqual(1, conv.Max);
            Assert.AreEqual(320, image.Height);
            Assert.AreEqual(320, image.Width);
        }
Example #5
0
        /// <summary>
        /// Process the filter on the specified image.
        /// </summary>
        /// 
        /// <param name="image">Source image data.</param>
        /// <param name="overlay">Overlay image data.</param>
        ///
        protected override void ProcessFilter(UnmanagedImage image, UnmanagedImage overlay)
        {
            BaseResizeFilter resizer = new ResizeNearestNeighbor(
                (int)(image.Width * _subSamplingRatio),
                (int)(image.Height * _subSamplingRatio));

            UnmanagedImage imageSub = resizer.Apply(image);
            UnmanagedImage overlaySub = resizer.Apply(overlay);
            byte kernelSizeSub = (byte)(_kernelSize * _subSamplingRatio);

            UnmanagedImage imageBorder = new FastBoxBlur(kernelSizeSub, kernelSizeSub).Apply(
                GetFilledImage(imageSub.Width, imageSub.Height, imageSub.PixelFormat, Color.White));

            UnmanagedImage imageMean = new FastBoxBlur(kernelSizeSub, kernelSizeSub).Apply(imageSub);
            new Divide(imageBorder).ApplyInPlace(imageMean);

            UnmanagedImage overlayMean = new FastBoxBlur(kernelSizeSub, kernelSizeSub).Apply(overlaySub);
            new Divide(imageBorder).ApplyInPlace(overlayMean);

            UnmanagedImage mulMean = new Multiply(overlaySub).Apply(imageSub);
            overlaySub.Dispose();
            new FastBoxBlur(kernelSizeSub, kernelSizeSub).ApplyInPlace(mulMean);
            new Divide(imageBorder).ApplyInPlace(mulMean);

            //This is the covariance of (image, overlay) in each local patch.
            UnmanagedImage mulCov = new Subtract(new Multiply(overlayMean).Apply(imageMean)).Apply(mulMean);
            mulMean.Dispose();

            UnmanagedImage imageMean2 = new Multiply(imageSub).Apply(imageSub);
            imageSub.Dispose();
            new FastBoxBlur(kernelSizeSub, kernelSizeSub).ApplyInPlace(imageMean2);
            new Divide(imageBorder).ApplyInPlace(imageMean2);

            UnmanagedImage imageVar = new Subtract(new Multiply(imageMean).Apply(imageMean)).Apply(imageMean2);
            imageMean2.Dispose();

            byte cc = (byte)(255 * _epsilon);
            var imageEpsilon = GetFilledImage(
                imageVar.Width, imageVar.Height, imageVar.PixelFormat, Color.FromArgb(cc, cc, cc));

            new Add(imageEpsilon).ApplyInPlace(imageVar);
            imageEpsilon.Dispose();

            UnmanagedImage a = new Divide(imageVar).Apply(mulCov);
            imageVar.Dispose();
            mulCov.Dispose();

            UnmanagedImage b = new Subtract(new Multiply(imageMean).Apply(a)).Apply(overlayMean);
            imageMean.Dispose();
            overlayMean.Dispose();

            UnmanagedImage aMean = new Divide(imageBorder).Apply(new FastBoxBlur(kernelSizeSub, kernelSizeSub).Apply(a));
            UnmanagedImage bMean = new Divide(imageBorder).Apply(new FastBoxBlur(kernelSizeSub, kernelSizeSub).Apply(b));
            imageBorder.Dispose();
            a.Dispose();
            b.Dispose();

            resizer = new ResizeBilinear(image.Width, image.Height);

            aMean = resizer.Apply(aMean);
            bMean = resizer.Apply(bMean);

            new Multiply(aMean).ApplyInPlace(image);
            aMean.Dispose();
            new Add(bMean).ApplyInPlace(image);
            bMean.Dispose();
        }
        /// <summary>
        /// Process the filter on the specified image.
        /// </summary>
        ///
        /// <param name="image">Source image data.</param>
        /// <param name="overlay">Overlay image data.</param>
        ///
        protected override void ProcessFilter(UnmanagedImage image, UnmanagedImage overlay)
        {
            // TODO: Refactor, add "using" clauses, manipulate pixel/pointers directly
            BaseResizeFilter resizer = new ResizeNearestNeighbor(
                (int)(image.Width * _subSamplingRatio),
                (int)(image.Height * _subSamplingRatio));

            UnmanagedImage imageSub   = resizer.Apply(image);
            UnmanagedImage overlaySub = resizer.Apply(overlay);

            byte        kernelSizeSub = (byte)(_kernelSize * _subSamplingRatio);
            FastBoxBlur blur          = new FastBoxBlur(kernelSizeSub, kernelSizeSub);

            UnmanagedImage imageBorder = blur.Apply(GetFilledImage(imageSub.Width, imageSub.Height, imageSub.PixelFormat, Color.White));

            UnmanagedImage imageMean = blur.Apply(imageSub);

            new Divide(imageBorder).ApplyInPlace(imageMean);

            UnmanagedImage overlayMean = blur.Apply(overlaySub);

            new Divide(imageBorder).ApplyInPlace(overlayMean);

            UnmanagedImage mulMean = new Multiply(overlaySub).Apply(imageSub);

            overlaySub.Dispose();
            blur.ApplyInPlace(mulMean);
            new Divide(imageBorder).ApplyInPlace(mulMean);

            // This is the covariance of (image, overlay) in each local patch.
            UnmanagedImage mulCov = new Subtract(new Multiply(overlayMean).Apply(imageMean)).Apply(mulMean);

            mulMean.Dispose();

            UnmanagedImage imageMean2 = new Multiply(imageSub).Apply(imageSub);

            imageSub.Dispose();
            blur.ApplyInPlace(imageMean2);
            new Divide(imageBorder).ApplyInPlace(imageMean2);

            UnmanagedImage imageVar = new Subtract(new Multiply(imageMean).Apply(imageMean)).Apply(imageMean2);

            imageMean2.Dispose();

            byte cc           = (byte)(255 * _epsilon);
            var  imageEpsilon = GetFilledImage(
                imageVar.Width, imageVar.Height, imageVar.PixelFormat, Color.FromArgb(cc, cc, cc));

            new Add(imageEpsilon).ApplyInPlace(imageVar);
            imageEpsilon.Dispose();

            UnmanagedImage a = new Divide(imageVar).Apply(mulCov);

            imageVar.Dispose();
            mulCov.Dispose();

            UnmanagedImage b = new Subtract(new Multiply(imageMean).Apply(a)).Apply(overlayMean);

            imageMean.Dispose();
            overlayMean.Dispose();

            UnmanagedImage aMean = new Divide(imageBorder).Apply(blur.Apply(a));
            UnmanagedImage bMean = new Divide(imageBorder).Apply(blur.Apply(b));

            imageBorder.Dispose();
            a.Dispose();
            b.Dispose();

            resizer = new ResizeBilinear(image.Width, image.Height);

            aMean = resizer.Apply(aMean);
            bMean = resizer.Apply(bMean);

            new Multiply(aMean).ApplyInPlace(image);
            aMean.Dispose();
            new Add(bMean).ApplyInPlace(image);
            bMean.Dispose();
        }
Example #7
0
        public void ConvertTest3()
        {
            double[] pixels = 
            {
                 0, 0, 0, 0,
                 0, 1, 1, 0,
                 0, 1, 1, 0,
                 0, 0, 0, 0,
            };

            ArrayToImage conv1 = new ArrayToImage(width: 4, height: 4);
            Bitmap image;
            conv1.Convert(pixels, out image);
            image = new ResizeNearestNeighbor(16, 16).Apply(image);


            // Obtain a 16x16 bitmap image
            // Bitmap image = ...

            // Show on screen
            // ImageBox.Show(image, PictureBoxSizeMode.Zoom);

            // Create the converter to convert the image to an
            //   array containing only values between 0 and 1 
            ImageToArray conv = new ImageToArray(min: 0, max: 1);

            // Convert the image and store it in the array
            double[] array; conv.Convert(image, out array);

            // Show the array on screen
            // ImageBox.Show(array, 16, 16, PictureBoxSizeMode.Zoom);

            Assert.AreEqual(0, array.Min());
            Assert.AreEqual(1, array.Max());
            Assert.AreEqual(16 * 16, array.Length);
        }
Example #8
0
        // New frame received by the player
        private void videoSourcePlayer_NewFrame(object sender, ref Bitmap image)
        {
            if (!detecting && !tracking)
                return;

            lock (this)
            {
                if (detecting)
                {
                    detecting = false;
                    tracking = false;

                    UnmanagedImage im = UnmanagedImage.FromManagedImage(image);

                    float xscale = image.Width / 160f;
                    float yscale = image.Height / 120f;

                    ResizeNearestNeighbor resize = new ResizeNearestNeighbor(160, 120);
                    UnmanagedImage downsample = resize.Apply(im);

                    Rectangle[] regions = detector.ProcessFrame(downsample);

                    if (regions.Length > 0)
                    {
                        tracker.Reset();

                        // Will track the first face found
                        Rectangle face = regions[0];

                        // Reduce the face size to avoid tracking background
                        Rectangle window = new Rectangle(
                            (int)((regions[0].X + regions[0].Width / 2f) * xscale),
                            (int)((regions[0].Y + regions[0].Height / 2f) * yscale),
                            1, 1);

                        window.Inflate(
                            (int)(0.2f * regions[0].Width * xscale),
                            (int)(0.4f * regions[0].Height * yscale));

                        // Initialize tracker
                        tracker.SearchWindow = window;
                        tracker.ProcessFrame(im);

                        marker = new RectanglesMarker(window);
                        marker.ApplyInPlace(im);

                        image = im.ToManagedImage();

                        tracking = true;
                        //detecting = true;
                    }
                    else
                    {
                        detecting = true;
                    }
                }
                else if (tracking)
                {
                    UnmanagedImage im = UnmanagedImage.FromManagedImage(image);

                    // Track the object
                    tracker.ProcessFrame(im);

                    // Get the object position
                    var obj = tracker.TrackingObject;
                    var wnd = tracker.SearchWindow;

                    if (displayBackprojectionToolStripMenuItem.Checked)
                    {
                        var backprojection = tracker.GetBackprojection(PixelFormat.Format24bppRgb);
                        im = UnmanagedImage.FromManagedImage(backprojection);
                    }

                    if (drawObjectAxisToolStripMenuItem.Checked)
                    {
                        LineSegment axis = obj.GetAxis();

                        // Draw X axis
                        if (axis != null)
                            Drawing.Line(im, axis.Start.Round(), axis.End.Round(), Color.Red);
                        else detecting = true;
                    }


                    if (drawObjectBoxToolStripMenuItem.Checked && drawTrackingWindowToolStripMenuItem.Checked)
                    {
                        marker = new RectanglesMarker(new Rectangle[] { wnd, obj.Rectangle });
                    }
                    else if (drawObjectBoxToolStripMenuItem.Checked)
                    {
                        marker = new RectanglesMarker(obj.Rectangle);
                    }
                    else if (drawTrackingWindowToolStripMenuItem.Checked)
                    {
                        marker = new RectanglesMarker(wnd);
                    }
                    else
                    {
                        marker = null;
                    }


                    if (marker != null)
                        marker.ApplyInPlace(im);
                    image = im.ToManagedImage();
                }
                else
                {
                    if (marker != null)
                        image = marker.Apply(image);
                }

            }
        }
Example #9
0
        private void captureHand(UnmanagedImage mask, Rectangle rect, PictureBox pbArm, PictureBox pbHand)
        {
            Crop c = new Crop(rect);
            var handImage = c.Apply(mask);

            var ps = handImage.Collect16bppPixelValues(handImage.CollectActivePixels());

            if (ps.Length > 0)
            {
                ushort max = Matrix.Max(ps);

                LevelsLinear16bpp levels = new LevelsLinear16bpp();
                levels.InGray = new IntRange(0, max);
                levels.OutGray = new IntRange(0, 65535);
                levels.ApplyInPlace(handImage);


                // pbArm.Image = handImage.ToManagedImage();


                double cutoff = 30000;
                Threshold th = new Threshold((int)cutoff);
                var handMask = th.Apply(handImage);

                var handMask8bit = Accord.Imaging.Image.Convert16bppTo8bpp(handMask.ToManagedImage());

                BlobCounter bch = new BlobCounter();
                bch.ObjectsOrder = ObjectsOrder.Area;
                bch.ProcessImage(handMask8bit);
                var blob = bch.GetObjectsInformation();

                if (blob.Length > 0)
                {
                    Intersect inters = new Intersect();
                    inters.UnmanagedOverlayImage = handMask;
                    inters.ApplyInPlace(handImage);

                    Crop ch = new Crop(blob[0].Rectangle);
                    handImage = ch.Apply(handImage);

                    ResizeNearestNeighbor res = new ResizeNearestNeighbor(25, 25);
                    handImage = res.Apply(handImage);

                    var leftHand = Accord.Imaging.Image.Convert16bppTo8bpp(handImage.ToManagedImage());

                    pbHand.Image = leftHand;
                }
            }
        }