Shrink an image by removing specified color from its boundaries.

Removes pixels with specified color from image boundaries making the image smaller in size.

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

Sample usage:

// create filter Shrink filter = new Shrink( Color.Black ); // apply the filter Bitmap newImage = filter.Apply( image );

Initial image:

Result image:

Inheritance: BaseTransformationFilter
        /// <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;
        }