Horizontal intensity statistics.

The class provides information about horizontal distribution of pixel intensities, which may be used to locate objects, their centers, etc.

The class accepts grayscale (8 bpp indexed and 16 bpp) and color (24, 32, 48 and 64 bpp) images. In the case of 32 and 64 bpp color images, the alpha channel is not processed - statistics is not gathered for this channel.

Sample usage:

// collect statistics HorizontalIntensityStatistics his = new HorizontalIntensityStatistics( sourceImage ); // get gray histogram (for grayscale image) Histogram histogram = his.Gray; // output some histogram's information System.Diagnostics.Debug.WriteLine( "Mean = " + histogram.Mean ); System.Diagnostics.Debug.WriteLine( "Min = " + histogram.Min ); System.Diagnostics.Debug.WriteLine( "Max = " + histogram.Max );

Sample grayscale image with its horizontal intensity histogram:

        //1. bright pixel / dark pixel
        //2.lowest gray level
        //3.highest gray level
        //4.number of peaks in the x direction.
        //5.number of peaks in the y direction.
        public static double[] ExtractFeatures(Bitmap bmp,int i)
        {
            //Apply GrayScale
            GrayscaleBT709 greyScaleFilter = new GrayscaleBT709();
            Bitmap newBmp = greyScaleFilter.Apply((Bitmap)bmp.Clone());

            //Count Blobs
            BlobCounter blobCounter = new BlobCounter();
            blobCounter.BackgroundThreshold = Color.FromArgb(255, 150, 150, 150);
            blobCounter.ProcessImage(newBmp);
            int blobs = (blobCounter.ObjectsCount - 1) * 30;

            //Count Corner
            SusanCornersDetector scd = new SusanCornersDetector();
            scd.DifferenceThreshold = 70;
            scd.GeometricalThreshold = 8;
            int corners = scd.ProcessImage((Bitmap)newBmp.Clone()).Count();

            //Apply Edge Filter
            CannyEdgeDetector filter = new CannyEdgeDetector();
            //newBmp = filter.Apply(newBmp);
            Histogram his = new HorizontalIntensityStatistics(newBmp).Gray;
            Histogram vis = new VerticalIntensityStatistics(newBmp).Gray;

            HoughLineTransformation lineTransform = new HoughLineTransformation();
            // apply Hough line transofrm
            lineTransform.ProcessImage(filter.Apply(newBmp));
            Bitmap houghLineImage = lineTransform.ToBitmap();
            // get lines using relative intensity
            HoughLine[] lines = lineTransform.GetLinesByRelativeIntensity(1);
            int linesCount = lines.Count() * 30;

            double[] features = new double[13] { blobs, corners, his.Max, his.Min, his.Mean, his.Median, his.StdDev,
                vis.Max, vis.Min, vis.Mean, vis.Median, vis.StdDev,linesCount};

            //double[] features = new double[3] { blobs, corners,lines};

            newBmp.Save(String.Format("test{0}.bmp",i));
            return features;
        }
        /// <summary>
        /// Determines if the cells are white over a black background, for a black and white image
        /// </summary>
        /// <param name="page">The bitmap that is the manga page</param>
        /// <returns>Returns true if the background of the manga page is black</returns>
        public static bool IsInvertedColor(Bitmap page)
        {
            // The colors are inverted if the color of the borders are inverted.
            HorizontalIntensityStatistics his = new HorizontalIntensityStatistics(page);
            VerticalIntensityStatistics vis = new VerticalIntensityStatistics(page);

            int vband = (int)(page.Height * 0.05);
            int hband = (int)(page.Width * 0.05);

            decimal totalValue = 0;

            for (int i = 0; i < vband; i++)
            {
                totalValue += vis.Gray.Values[i] + vis.Gray.Values[page.Height - i - 1];
            }

            for (int i = 0; i < hband; i++)
            {
                totalValue += his.Gray.Values[i] + his.Gray.Values[page.Width - i - 1];
            }

            return totalValue < (decimal)(((page.Height * hband * 2) + (page.Width * vband * 2)) * 255 * 0.50);
        }
        /// <summary>
        /// Recognize hands gesture.
        /// </summary>
        /// 
        /// <param name="imageData">Source image data to recognize hands gesture on.</param>
        /// <param name="bodyImageOnly">Specifies if the passed image data contain only human's body or not.</param>
        /// 
        /// <returns>Returns gesture structure, which specifies position of both hands.</returns>
        /// 
        /// <remarks><para>The <b>bodyImageOnly</b>> parameter specifies if human's body occupies the
        /// passes image from top to down and from left to rigth. If the value is set to <b>false</b>,
        /// then humans' body may occupy only part of the image, what will require image shrinking.</para></remarks>
        /// 
        public Gesture Recognize( BitmapData imageData, bool bodyImageOnly )
        {
            // check source image format
            if ( imageData.PixelFormat != PixelFormat.Format8bppIndexed )
            {
                throw new ArgumentException( "Source image can be binary (8 bpp indexed) only" );
            }

            // recognized gesture
            Gesture gesture = new Gesture( HandPosition.NotRaised, HandPosition.NotRaised );

            Bitmap bodyImage = null;
            BitmapData bodyImageData = null;

            if ( bodyImageOnly == false )
            {
                // use shrink filter to extract only body image
                Shrink shrinkFilter = new Shrink( );
                bodyImage = shrinkFilter.Apply( imageData );

                // lock body image for further processing
                bodyImageData = bodyImage.LockBits(
                    new Rectangle( 0, 0, bodyImage.Width, bodyImage.Height ),
                    ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed );
            }
            else
            {
                // use passed image as body image
                bodyImageData = imageData;
            }

            int bodyWidth = bodyImageData.Width;
            int bodyHeight = bodyImageData.Height;

            // get statistics about horizontal pixels distribution
            HorizontalIntensityStatistics his = new HorizontalIntensityStatistics( bodyImageData );
            int[] hisValues = (int[]) his.Gray.Values.Clone( );

            // build map of hands (0) and torso (1)
            double torsoLimit = torsoCoefficient * bodyHeight;

            for ( int i = 0; i < bodyWidth; i++ )
            {
                hisValues[i] = ( (double) hisValues[i] / 255 > torsoLimit ) ? 1 : 0;
            }

            // get hands' length
            int leftHand = 0;
            while ( ( hisValues[leftHand] == 0 ) && ( leftHand < bodyWidth ) )
                leftHand++;

            int rightHand = bodyWidth - 1;
            while ( ( hisValues[rightHand] == 0 ) && ( rightHand > 0 ) )
                rightHand--;
            rightHand = bodyWidth - ( rightHand + 1 );

            // get torso's width
            int torsoWidth = bodyWidth - leftHand - rightHand;

            // process left hand
            if ( ( (double) leftHand / torsoWidth ) >= handsMinProportion )
            {
                // extract left hand's image
                Crop cropFilter = new Crop( new Rectangle( 0, 0, leftHand, bodyHeight ) );
                Bitmap leftHandImage = cropFilter.Apply( bodyImageData );

                // get left hand's position
                gesture.LeftHand = GetHandPosition( leftHandImage );
            }

            // process right hand
            if ( ( (double) rightHand / torsoWidth ) >= handsMinProportion )
            {
                // extract right hand's image
                Crop cropFilter = new Crop( new Rectangle( bodyWidth - rightHand, 0, rightHand, bodyHeight ) );
                Bitmap rightHandImage = cropFilter.Apply( bodyImageData );

                // get right hand's position
                gesture.RightHand = GetHandPosition( rightHandImage );
            }

            if ( !bodyImageOnly )
            {
                // unlock body image and dispose it
                bodyImage.UnlockBits( bodyImageData );
                bodyImage.Dispose( );
            }

            return gesture;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets the content.
        /// </summary>
        /// <param name="mincross">Минимальная разница яркости ячейки с кретсиком</param>
        /// <param name="maxcross">Максимальная разница яркости ячейки с кретсиком</param>
        public void GetContent(double mincross, double maxcross)
        {
            _content = false;
            _neurocontent = CellContent.Free;

            List<double> _lrange = new List<double>();
            BitmapData data = _parentimage.LockBits(_rect, ImageLockMode.ReadWrite, _parentimage.PixelFormat);
            VerticalIntensityStatistics vis = new VerticalIntensityStatistics(data);
            histogram = vis.Gray;

            HorizontalIntensityStatistics his = new HorizontalIntensityStatistics(data);
            Histogram hhistogram = his.Gray;
            List<double> _hrange = new List<double>();

            _parentimage.UnlockBits(data);

            for (int i = 8; i <= 15; i++)
            {
                _lrange.Add((histogram.Values[i]+hhistogram.Values[i])/2);
               // _hrange.Add(hhistogram.Values[i]);
            }
              // _britnessdispertion = (1 - RecogCore.Statistics.Mean(_lrange) / histogram.Values.Max()) + (1 - RecogCore.Statistics.Mean(_hrange) / hhistogram.Values.Max());
            _britnessdispertion = 1 - RecogCore.Statistics.Mean(_lrange) / histogram.Values.Max();
            if (_britnessdispertion <= mincross) { _neurocontent = CellContent.Free; _content = false; }
            if (_britnessdispertion > mincross & _britnessdispertion <= maxcross) { _neurocontent = CellContent.Cross; _content = true; }
            if (_britnessdispertion > maxcross) { _neurocontent = CellContent.Miss; _content = false; }
        }
Ejemplo n.º 5
0
        public override void Execute(Bitmap Image)
        {
            BlobCounter blobCounter = new BlobCounter();
            blobCounter.MinHeight = 75;
            blobCounter.MinWidth = 75;
            blobCounter.CoupledSizeFiltering = true;
            blobCounter.ProcessImage(Image);
            Blob[] blobs = blobCounter.GetObjects(Image);
            int maxSize = 0;
            int TmpX = -100, TmpY = -100;
            Blob maxObject = new Blob(0, new Rectangle(0, 0, 0, 0));
            // find biggest blob
            if (blobs != null)
            {
                foreach (Blob blob in blobs)
                {
                    int blobSize = blob.Rectangle.Width * blob.Rectangle.Height;

                    if (blobSize > maxSize)
                    {
                        maxSize = blobSize;
                        maxObject = blob;
                    }
                }
                if (maxSize > 70)
                {
                    TmpX = (maxObject.Rectangle.Left + maxObject.Rectangle.Right) / 2;
                    TmpY = maxObject.Rectangle.Top;
                }
            }
            AForge.Imaging.VerticalIntensityStatistics VIS = new VerticalIntensityStatistics(Image);
            int[] HistVer = VIS.Gray.Values;
            AForge.Imaging.HorizontalIntensityStatistics HIS = new HorizontalIntensityStatistics(Image);
            int[] HistHor = HIS.Gray.Values;

            bool Found = false;
            for (int i = System.Math.Max(CurrY - GateLengthY / 2, 0); i <= System.Math.Min(CurrY + GateLengthY / 2, HistVer.Length - 2); i++)
            {
                if (((double)HistVer[i]) / 255 > 0)
                {
                    Found = true;
                    CurrY = i;
                    break;
                }
            }
            if (!Found)
            {
                Validity = ValidLocation.FALSE;
                return;
            }
            Found = false;
            for (int i = System.Math.Max(0, CurrX - GateLengthX / 2); i <= System.Math.Min(HistHor.Length - 1, CurrX + GateLengthX / 2); i++)
            {
                if (Image.GetPixel(i, CurrY).Name != "ff000000")
                {
                    Found = true;
                    CurrX = i;
                    break;
                }
            }
            if (!Found)
            {
                Validity = ValidLocation.FALSE;
                return;
            }
            /*if (System.Math.Sqrt((CurrX - TmpX) * (CurrX - TmpX) + (CurrY - TmpY) * (CurrY - TmpY)) > 80)
            {
                Validity = ValidLocation.FALSE;
                return;
            }
            else
                Validity = ValidLocation.TRUE;
            CurrX = TmpX;
            CurrY = TmpY;*/
            Validity = ValidLocation.TRUE;
        }
Ejemplo n.º 6
0
        void webcam_ImageCaptured_Back2(object source, WebcamEventArgs e)
        {
            _FrameImage.Image = e.WebCamImage;
            Bitmap MaskImage = new Bitmap(640, 480);
            if (backgroundFrame == null)
            {
                Frames2Ignore--;
                if (Frames2Ignore == 0)
                {
                    backgroundFrame = (Bitmap)e.WebCamImage;
                    backgroundFrameGray = grayscaleFilter.Apply(backgroundFrame);
                }
                return;
            }

            //Save curent image
            CurrentFrame = (Bitmap)e.WebCamImage;
            CurrentFrameGray = grayscaleFilter.Apply(CurrentFrame);

            /*
            // create filter
            IFilter pixellateFilter = new Pixellate();
            // apply the filter
            backgroundFrame = pixellateFilter.Apply(backgroundFrame);
            backgroundFrameGray = grayscaleFilter.Apply(backgroundFrame);
            CurrentFrame = pixellateFilter.Apply(CurrentFrame);
            CurrentFrameGray = grayscaleFilter.Apply(CurrentFrame);*/

            MoveTowards moveTowardsFilter = new MoveTowards();
            moveTowardsFilter.OverlayImage = CurrentFrameGray;
            // move background towards current frame
            Bitmap tmp = moveTowardsFilter.Apply(backgroundFrameGray);
            // dispose old background
            backgroundFrame.Dispose();
            backgroundFrame = tmp;

            // create processing filters sequence

            FiltersSequence processingFilter = new FiltersSequence();
            processingFilter.Add(new Difference(backgroundFrameGray));
            processingFilter.Add(new Threshold(15));
            processingFilter.Add(new Opening());
            processingFilter.Add(new Edges());
            processingFilter.Add(new DifferenceEdgeDetector());

            // apply the filter

            Bitmap tmp1 = processingFilter.Apply(CurrentFrameGray);
            // extract red channel from the original image

            /*IFilter extrachChannel = new ExtractChannel(RGB.R);
            Bitmap redChannel = extrachChannel.Apply(backgroundFrame);

            //  merge red channel with moving object borders

            Merge mergeFilter = new Merge();
            mergeFilter.OverlayImage = tmp1;
            Bitmap tmp2 = mergeFilter.Apply(redChannel);
            // replace red channel in the original image

            ReplaceChannel replaceChannel = new ReplaceChannel(RGB.R, tmp2);
            replaceChannel.ChannelImage = tmp2;
            Bitmap tmp3 = replaceChannel.Apply(backgroundFrame);

            ConnectedComponentsLabeling CCL = new ConnectedComponentsLabeling();
            CCL.MinWidth = 75;
            CCL.MinHeight = 75;
            CCL.CoupledSizeFiltering = true;
            Bitmap tmp4 = CCL.Apply(tmp1);

            blobCounter.MinHeight = 75;
            blobCounter.MinWidth = 75;
            blobCounter.CoupledSizeFiltering = true;
            blobCounter.ProcessImage(tmp1);
            Blob[] blobs = blobCounter.GetObjects(tmp1);
            int maxSize = 0;
            Blob maxObject = new Blob(0, new Rectangle(0, 0, 0, 0));
            // find biggest blob
            if (blobs != null)
            {
                foreach (Blob blob in blobs)
                {
                    int blobSize = blob.Rectangle.Width * blob.Rectangle.Height;

                    if (blobSize > maxSize)
                    {
                        maxSize = blobSize;
                        maxObject = blob;
                    }
                }
            }*/
            Bitmap Hor = new Bitmap(320, 240);
            Bitmap Ver = new Bitmap(320, 240);
            /*if (maxSize > 150)
            {
                AForge.Imaging.VerticalIntensityStatistics VIS = new VerticalIntensityStatistics(tmp1);
                int[] HistVer = VIS.Gray.Values;
                AForge.Imaging.HorizontalIntensityStatistics HIS = new HorizontalIntensityStatistics(tmp1);
                int[] HistHor = HIS.Gray.Values;
            }
             */
            AForge.Imaging.VerticalIntensityStatistics VIS = new VerticalIntensityStatistics(tmp1);
            int[] HistVer = VIS.Gray.Values;
            AForge.Imaging.HorizontalIntensityStatistics HIS = new HorizontalIntensityStatistics(tmp1);
            int[] HistHor = HIS.Gray.Values;
            //StateMgr.Execute(HistHor,HistVer);
            if (eChangedCursorEvent != null && StateMgr.Val == Webcam.ValidLocation.TRUE)
            {
                //Console.WriteLine("X={0} , Y={1}", StateMgr.CurrState.CurrX, StateMgr.CurrState.CurrY);
                eChangedCursorEvent(StateMgr.CurrState.CurrX, StateMgr.CurrState.CurrY);
                //eChangedCursorEvent(StateMgr.CurrState.CurrX, 100);
                //eChangedCursorEvent(100, StateMgr.CurrState.CurrY);
            }

            #region Paint Hist
            /*for (int x = 0; x < 320; x++)
                for (int y = 0; y < 240; y++)
                {
                    Hor.SetPixel(x, y, Color.White);
                    Ver.SetPixel(x, y, Color.White);
                }
            int Imax = -1, Max = -1;
            for (int i = 0; i < HistHor.Length; i++)
            {
                for (int y = 0; y < ((double)(HistHor[i]) / 255); y++)
                    Hor.SetPixel(i, y, Color.Black);
                if (HistHor[i] > 0)
                {
                    Imax = i;
                    Max = HistHor[i];
                }
            }
            int ImaxY = -1, MaxY = -1;
            for (int i = 0; i < HistVer.Length; i++)
            {
                for (int x = 0; x < ((double)(HistVer[i]) / 255); x++)
                    Ver.SetPixel(x, i, Color.Black);
                if (HistVer[i] > MaxY)
                {
                    ImaxY = i;
                    MaxY = HistVer[i];
                }
            }*/
            #endregion

            _CaptureImage.Image = Hor;
            _CaptureImage2.Image = Ver;
            backgroundFrame = (Bitmap)e.WebCamImage;
            backgroundFrameGray = grayscaleFilter.Apply(backgroundFrame);
        }