Invert image.

The filter inverts colored and grayscale images.

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

Sample usage:

// create filter Invert filter = new Invert( ); // apply the filter filter.ApplyInPlace( image );

Initial image:

Result image:

상속: BaseInPlacePartialFilter
예제 #1
0
        /// <summary>
        /// Process the filter on the specified image.
        /// </summary>
        ///
        /// <param name="image">Source image data.</param>
        ///
        protected override unsafe void ProcessFilter(UnmanagedImage image)
        {
            int width  = image.Width;
            int height = image.Height;

            BlobCounter blobCounter = new BlobCounter();

            // 1 - invert the source image
            Invert invertFilter = new Invert();

            using (UnmanagedImage invertedImage = invertFilter.Apply(image))
            {
                // 2 - use blob counter to find holes (they are white objects now on the inverted image)
                blobCounter.ProcessImage(invertedImage);
            }

            Blob[] blobs = blobCounter.GetObjectsInformation();

            // 3 - check all blobs and determine which should be filtered
            byte[] newObjectColors = new byte[blobs.Length + 1];
            newObjectColors[0] = 255; // don't touch the objects, which have 0 ID

            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                Blob blob = blobs[i];

                if ((blob.Rectangle.Left == 0) || (blob.Rectangle.Top == 0) ||
                    (blob.Rectangle.Right == width) || (blob.Rectangle.Bottom == height))
                {
                    newObjectColors[blob.ID] = 0;
                }
                else
                {
                    if (((coupledSizeFiltering) && (blob.Rectangle.Width <= maxHoleWidth) && (blob.Rectangle.Height <= maxHoleHeight)) |
                        ((!coupledSizeFiltering) && ((blob.Rectangle.Width <= maxHoleWidth) || (blob.Rectangle.Height <= maxHoleHeight))))
                    {
                        newObjectColors[blob.ID] = 255;
                    }
                    else
                    {
                        newObjectColors[blob.ID] = 0;
                    }
                }
            }

            // 4 - process the source image image and fill holes
            byte *ptr    = (byte *)image.ImageData.ToPointer();
            int   offset = image.Stride - width;

            int[] objectLabels = blobCounter.ObjectLabels;

            for (int y = 0, i = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++, i++, ptr++)
                {
                    *ptr = newObjectColors[objectLabels[i]];
                }
                ptr += offset;
            }
        }
예제 #2
0
        /// <summary>
        /// Process the filter on the specified image.
        /// </summary>
        /// 
        /// <param name="image">Source image data.</param>
        ///
        protected override unsafe void ProcessFilter( UnmanagedImage image )
        {
            int width  = image.Width;
            int height = image.Height;

            // 1 - invert the source image
            Invert invertFilter = new Invert( );
            UnmanagedImage invertedImage = invertFilter.Apply( image );

            // 2 - use blob counter to find holes (they are white objects now on the inverted image)
            BlobCounter blobCounter = new BlobCounter( );
            blobCounter.ProcessImage( invertedImage );
            Blob[] blobs = blobCounter.GetObjectsInformation( );

            // 3 - check all blobs and determine which should be filtered
            byte[] newObjectColors = new byte[blobs.Length + 1];
            newObjectColors[0] = 255; // don't touch the objects, which have 0 ID

            for ( int i = 0, n = blobs.Length; i < n; i++ )
            {
                Blob blob = blobs[i];

                if ( ( blob.Rectangle.Left == 0 ) || ( blob.Rectangle.Top == 0 ) ||
                     ( blob.Rectangle.Right == width ) || ( blob.Rectangle.Bottom == height ) )
                {
                    newObjectColors[blob.ID] = 0;
                }
                else
                {
                    if ( ( ( coupledSizeFiltering ) && ( blob.Rectangle.Width <= maxHoleWidth ) && ( blob.Rectangle.Height <= maxHoleHeight ) ) |
                         ( ( !coupledSizeFiltering ) && ( ( blob.Rectangle.Width <= maxHoleWidth ) || ( blob.Rectangle.Height <= maxHoleHeight ) ) ) )
                    {
                        newObjectColors[blob.ID] = 255;
                    }
                    else
                    {
                        newObjectColors[blob.ID] = 0;
                    }
                }
            }

            // 4 - process the source image image and fill holes
            byte* ptr = (byte*) image.ImageData.ToPointer( );
            int offset = image.Stride - width;

            int[] objectLabels = blobCounter.ObjectLabels;

            for ( int y = 0, i = 0; y < height; y++ )
            {
                for ( int x = 0; x < width; x++, i++, ptr++ )
                {
                    *ptr = newObjectColors[objectLabels[i]];
                }
                ptr += offset;
            }
        }
예제 #3
0
        public void GetBlobs2(string inputFile, string outputPath)
        {
            UnmanagedImage skewedImg = null;
            UnmanagedImage bwInvImg  = null;

            {
                var    bmp          = new Bitmap(inputFile);
                var    img          = UnmanagedImage.FromManagedImage(bmp);
                var    grayImg      = Accord.Imaging.Filters.Grayscale.CommonAlgorithms.BT709.Apply(img);
                var    bwImg        = new Accord.Imaging.Filters.OtsuThreshold().Apply(grayImg);
                var    skewChecker  = new DocumentSkewChecker();
                double angle        = skewChecker.GetSkewAngle(bwImg);
                var    rotateFilter = new Accord.Imaging.Filters.RotateBilinear(-angle);
                skewedImg = rotateFilter.Apply(img);
                bwImg.Dispose();
                grayImg.Dispose();
                img.Dispose();
                bmp.Dispose();
            }

            {
                var grayImg       = Accord.Imaging.Filters.Grayscale.CommonAlgorithms.BT709.Apply(skewedImg);
                var bwImg         = new Accord.Imaging.Filters.OtsuThreshold().Apply(grayImg);
                var openingFilter = new Accord.Imaging.Filters.Opening();
                openingFilter.ApplyInPlace(bwImg);
                bwInvImg = new Accord.Imaging.Filters.Invert().Apply(bwImg);
                bwImg.Dispose();
                grayImg.Dispose();
            }


            var blobProc = new Accord.Imaging.BlobCounter();

            blobProc.ProcessImage(bwInvImg);
            var blobs = blobProc.GetObjectsInformation().ToList();

            foreach (Accord.Imaging.Blob blob in blobs.OrderBy(b => b.Rectangle.Left).ThenBy(b => b.Rectangle.Top))
            {
                Console.WriteLine("{0} {1}", blob.Rectangle.ToString(), blob.Area.ToString());
            }

            //Layout parameters
            var expectedLineMarkerSize = new System.Drawing.Size(25, 10); //new System.Drawing.Size(35, 15);
            var expectedCellSize       = new System.Drawing.Size(15, 10); //new System.Drawing.Size(20, 13);
            int expectedNumlineMarkers = 19;                              // 23;
            int tolerance = 3;
            //Limits to determine in a cell is marked
            double fullnessOk     = .75;
            double fullnessUnsure = .65;
            var    questions      = new List <Tuple <int, Accord.Imaging.Blob, List <Accord.Imaging.Blob> > >();

            {
                var lineMarkers = blobs.Where(b =>
                {
                    if (b.Rectangle.Width < expectedLineMarkerSize.Width - tolerance)
                    {
                        return(false);
                    }
                    if (b.Rectangle.Width > expectedLineMarkerSize.Width + tolerance)
                    {
                        return(false);
                    }
                    if (b.Rectangle.Height < expectedLineMarkerSize.Height - tolerance)
                    {
                        return(false);
                    }
                    if (b.Rectangle.Height > expectedLineMarkerSize.Height + tolerance)
                    {
                        return(false);
                    }
                    return(true);
                })
                                  .OrderBy(b => b.Rectangle.Left)
                                  .ThenBy(b => b.Rectangle.Top)
                                  .ToList();
                if (lineMarkers.Count() != expectedNumlineMarkers)
                {
                    throw new Exception(string.Format("Can't locate all line markers. Expected {0}, found {1}", expectedNumlineMarkers, lineMarkers.Count));
                }
                var cells = blobs.Where(b =>
                {
                    if (b.Rectangle.Width < expectedCellSize.Width - tolerance)
                    {
                        return(false);
                    }
                    if (b.Rectangle.Width > expectedCellSize.Width + tolerance)
                    {
                        return(false);
                    }
                    if (b.Rectangle.Height < expectedCellSize.Height - tolerance)
                    {
                        return(false);
                    }
                    if (b.Rectangle.Height > expectedCellSize.Height + tolerance)
                    {
                        return(false);
                    }
                    return(true);
                }).ToList();

                int idxLine = 1;
                foreach (var lineMarker in lineMarkers.OrderBy(b => b.CenterOfGravity.Y))
                {
                    var cellsOfLine = cells.Where(b => Math.Abs(b.CenterOfGravity.Y - lineMarker.CenterOfGravity.Y) <= tolerance)
                                      .Take(5)
                                      .ToList()
                                      .OrderBy(b => b.CenterOfGravity.X)
                                      .ToList();
                    questions.Add(new Tuple <int, Accord.Imaging.Blob, List <Accord.Imaging.Blob> >(idxLine, lineMarker, cellsOfLine));
                    idxLine++;
                }
            }

            {
                var bmp = skewedImg.ToManagedImage();
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    foreach (var question in questions)
                    {
                        g.FillRectangle(new SolidBrush(Color.Blue), question.Item2.Rectangle);
                        g.DrawString(question.Item1.ToString(), new System.Drawing.Font("Arial", 8), new SolidBrush(Color.White), question.Item2.Rectangle);
                        int column = 1;
                        foreach (Accord.Imaging.Blob blob in question.Item3.OrderBy(b => b.Rectangle.Left).ThenBy(b => b.Rectangle.Top))
                        {
                            if (System.Diagnostics.Debugger.IsAttached)
                            {
                                Console.WriteLine("Line {0}, Column {1}, Fullness {2}", question.Item1, column, Math.Round(blob.Fullness, 2));
                            }
                            if (blob.Fullness >= fullnessOk)
                            {
                                g.DrawRectangle(new Pen(Color.Green, 2), blob.Rectangle);
                            }
                            else if (blob.Fullness >= fullnessUnsure)
                            {
                                g.DrawRectangle(new Pen(Color.Yellow, 2), blob.Rectangle);
                            }
                            else
                            {
                                g.DrawRectangle(new Pen(Color.Red, 2), blob.Rectangle);
                            }
                            column++;
                        }
                    }
                }
                // bmp.Save(outp);
            }
        }
예제 #4
0
 private void SetFilter()
 {
     ImageType = ImageTypes.Rgb24bpp;
     Af.Invert newFilter = new Af.Invert();
     imageFilter = newFilter;
 }
예제 #5
0
        private void videoSourcePlayer1_NewFrame(object sender, ref Bitmap image)
        {
            Invert inv = new Invert();
            inv.ApplyInPlace(image);

            UnmanagedImage ui = UnmanagedImage.FromManagedImage(image);

            pictureBox1.Image = image;


            if (controller.Tracker.TrackingObject == null)
                return;

            if (controller.Tracker.TrackingObject.IsEmpty)
                return;

            var rect = controller.Tracker.TrackingObject.Rectangle;
            Crop crop = new Crop(rect);

            UnmanagedImage head = crop.Apply(ui);

            var points = new List<IntPoint>() { new IntPoint(head.Width / 2, head.Height / 2) };
            var pps = head.Collect16bppPixelValues(points);

            double mean = pps.Mean();

            double cutoff = mean + 15;
            Threshold t = new Threshold((int)cutoff);
            var mask = t.Apply(ui);



            LevelsLinear16bpp levels = new LevelsLinear16bpp();
            levels.InGray = new IntRange((int)cutoff, 65535);
            levels.OutGray = new IntRange(0, 65535);
            levels.ApplyInPlace(ui);


            var mask8bit = Accord.Imaging.Image.Convert16bppTo8bpp(mask.ToManagedImage());



            BlobCounter bc = new BlobCounter();
            bc.ObjectsOrder = ObjectsOrder.Area;
            bc.ProcessImage(mask8bit);
            var blobs = bc.GetObjectsInformation();

            inv.ApplyInPlace(image);
            Intersect intersect = new Intersect();
            intersect.UnmanagedOverlayImage = mask;
            mask = intersect.Apply(ui);

            List<Rectangle> rects = new List<Rectangle>();

            // Extract the uppermost largest blobs.
            for (int i = 0; i < blobs.Length; i++)
            {
                double dx = (blobs[i].Rectangle.Top - controller.Tracker.TrackingObject.Center.Y);
                double d = (dx * dx) / controller.Tracker.TrackingObject.Area;
                if (d < 2 && blobs[i].Area > 1000)
                    rects.Add(blobs[i].Rectangle);
            }

            rects.Sort(compare);

            if (rects.Count > 0)
            {
                captureHand(mask, rects[0], pbLeftArm, pbLeftHand);
            }
            if (rects.Count > 1)
            {
                captureHand(mask, rects[1], pbRightArm, pbRightHand);

            }

            RectanglesMarker marker = new RectanglesMarker(rects);
            marker.MarkerColor = Color.White;
            marker.ApplyInPlace(mask8bit);

            image = mask.ToManagedImage();
        }