Copy() public method

Copy unmanaged image.

The method copies current unmanaged image to the specified image. Size and pixel format of the destination image must be exactly the same.

Destination image has different size or pixel format.
public Copy ( UnmanagedImage destImage ) : void
destImage UnmanagedImage Destination image to copy this image to.
return void
Beispiel #1
0
 public static void ConvertToGrayscale(UnmanagedImage source, UnmanagedImage destination)
 {
     if (source.PixelFormat != PixelFormat.Format8bppIndexed)
     {
         Grayscale.CommonAlgorithms.BT709.Apply(source, destination);
     }
     else
     {
         source.Copy(destination);
     }
 }
Beispiel #2
0
        public void Correct(UnmanagedImage img, double aFocalLinPixels, int limit, double scale, int offx, int offy)
        {
            if (Math.Abs(_aFocalLinPixels - aFocalLinPixels) > Double.Epsilon || limit != _mFeLimit ||
                Math.Abs(scale - _mScaleFeSize) > Double.Epsilon || img.Width != _w || img.Height != _h ||
                _offsetx != offx || _offsety != offy)
            {
                Init(aFocalLinPixels, limit, scale, img.Width, img.Height, offx, offy);
            }
            var correctImage = UnmanagedImage.Create(img.Width, img.Height, img.PixelFormat);
            img.Copy(correctImage);
            int c = 0;
            for (int x = 0; x < _w; x++)
            {
                for (int y = 0; y < _h; y++)
                {
                    img.SetPixel(x, y, correctImage.GetPixel(_map[c, 0], _map[c, 1]));
                    c++;
                }

            }
            correctImage.Dispose();
        }
        /// <summary>
        /// Process new video frame.
        /// </summary>
        /// 
        /// <param name="videoFrame">Video frame to process (detect motion in).</param>
        /// 
        /// <remarks><para>Processes new frame from video source and detects motion in it.</para>
        /// 
        /// <para>Check <see cref="MotionLevel"/> property to get information about amount of motion
        /// (changes) in the processed frame.</para>
        /// </remarks>
        ///
        public unsafe void ProcessFrame( UnmanagedImage videoFrame )
        {
            lock ( _sync )
            {
                // check background frame
                if ( _backgroundFrame == null )
                {
                    _lastTimeMeasurment = DateTime.UtcNow;

                    // save image dimension
                    _width  = videoFrame.Width;
                    _height = videoFrame.Height;

                    // alocate memory for previous and current frames
                    _backgroundFrame = UnmanagedImage.Create( _width, _height, videoFrame.PixelFormat );
                    _motionFrame = UnmanagedImage.Create( _width, _height, PixelFormat.Format8bppIndexed );

                    _frameSize = videoFrame.Stride * _height;
					_motionSize = _motionFrame.Stride * _motionFrame.Height;

                    // temporary buffer
                    if ( _suppressNoise )
                    {
                        _tempFrame = UnmanagedImage.Create( _width, _height, PixelFormat.Format8bppIndexed );
                    }

                    // set the backgroundframe
					videoFrame.Copy (_backgroundFrame);

                    return;
                }

                // check image dimension
                if ( ( videoFrame.Width != _width ) || ( videoFrame.Height != _height ) )
                    return;


                // pointers to background and current frames
                byte* backFrame;
                byte* currFrame;
                int diff;

                // update background frame
                if ( _millisecondsPerBackgroundUpdate == 0 )
                {
                    // update background frame using frame counter as a base
                    if ( ++_framesCounter == _framesPerBackgroundUpdate )
                    {
                        _framesCounter = 0;

                        backFrame = (byte*) _backgroundFrame.ImageData.ToPointer( );
                        currFrame = (byte*) videoFrame.ImageData.ToPointer( );
						
                        for ( int i = 0; i < _frameSize; i++, backFrame++, currFrame++ )
                        {
                            diff = *currFrame - *backFrame;
                            if ( diff > 0 )
                            {
                                ( *backFrame )++;
                            }
                            else if ( diff < 0 )
                            {
                                ( *backFrame )--;
                            }
                        }
                    }
                }
                else
                {
                    // update background frame using timer as a base

                    // get current time and calculate difference
                    DateTime currentTime = DateTime.UtcNow;
                    TimeSpan timeDff = currentTime - _lastTimeMeasurment;
                    // save current time as the last measurment
                    _lastTimeMeasurment = currentTime;

                    int millisonds = (int) timeDff.TotalMilliseconds + _millisecondsLeftUnprocessed;

                    // save remainder so it could be taken into account in the future
                    _millisecondsLeftUnprocessed = millisonds % _millisecondsPerBackgroundUpdate;
                    // get amount for background update 
                    int updateAmount = ( millisonds / _millisecondsPerBackgroundUpdate );

                    backFrame = (byte*) _backgroundFrame.ImageData.ToPointer( );
                    currFrame = (byte*) videoFrame.ImageData.ToPointer( );

                    for ( int i = 0; i < _frameSize; i++, backFrame++, currFrame++ )
                    {
                        diff = *currFrame - *backFrame;
                        if ( diff > 0 )
                        {
                            ( *backFrame ) += (byte) ( (  diff < updateAmount ) ? diff :  updateAmount );
                        }
                        else if ( diff < 0 )
                        {
                            ( *backFrame ) += (byte) ( ( -diff < updateAmount ) ? diff : -updateAmount );
                        }
                    }
                }

                backFrame = (byte*) _backgroundFrame.ImageData.ToPointer( );
                currFrame = (byte*) videoFrame.ImageData.ToPointer( );
				byte* motion = (byte*) _motionFrame.ImageData.ToPointer( );
                int bytesPerPixel = Tools.BytesPerPixel( videoFrame.PixelFormat );
					
                // 1 - get difference between frames (accumulated on every channel)
                // 2 - threshold the difference
				for ( int i = 0; i < _height; i++ ) {
					var currFrameLocal = currFrame;
					var backFrameLocal = backFrame;
					var motionLocal = motion;
					for ( int j = 0; j < _width; j++ ) {
						diff = 0;
						for ( int nbBytes = 0; nbBytes < bytesPerPixel; nbBytes++ ) {
					    	// difference
                    		diff += Math.Abs ( *currFrameLocal -  *backFrameLocal);
							currFrameLocal++;
							backFrameLocal++;
						}
						diff /= bytesPerPixel;
						*motionLocal = ( diff >= _differenceThreshold ) ? (byte) 255 : (byte) 0;
						motionLocal++;
					}
					currFrame += videoFrame.Stride;
					backFrame += _backgroundFrame.Stride;
					motion += _motionFrame.Stride;
				}
				
                if ( _suppressNoise )
                {
                    // suppress noise and calculate motion amount
                    AForge.SystemTools.CopyUnmanagedMemory( _tempFrame.ImageData, _motionFrame.ImageData, _motionSize );
                    _erosionFilter.Apply( _tempFrame, _motionFrame );

                    if ( _keepObjectEdges )
                    {
                        AForge.SystemTools.CopyUnmanagedMemory( _tempFrame.ImageData, _motionFrame.ImageData, _motionSize );
                        _dilatationFilter.Apply( _tempFrame, _motionFrame );
                    }
                }

                // calculate amount of motion pixels
                _pixelsChanged = 0;
                motion = (byte*) _motionFrame.ImageData.ToPointer( );

                for ( int i = 0; i < _motionSize; i++, motion++ )
                {
                    _pixelsChanged += ( *motion & 1 );
                }
            }
        }
        /// <summary>
        ///   Process the filter on the specified image.
        /// </summary>
        /// 
        /// <param name="sourceData">Source image data.</param>
        /// <param name="destinationData">Destination image data.</param>
        ///
        protected override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
        {
            if (sourceData.PixelFormat == PixelFormat.Format8bppIndexed)
                sourceData = toRGB.Apply(sourceData);

            // Copy image contents
            sourceData.Copy(destinationData);

            Bitmap managedImage = destinationData.ToManagedImage(makeCopy: false);

            using (Graphics g = Graphics.FromImage(managedImage))
            using (Pen positive = new Pen(Color.Red))
            using (Pen negative = new Pen(Color.Blue))
            using (Pen line = new Pen(Color.FromArgb(0, 255, 0)))
            {
                // mark all points
                foreach (SpeededUpRobustFeaturePoint p in points)
                {
                    int S = (int)(scale * p.Scale);
                    int R = (int)(S / 2f);

                    Point pt = new Point((int)p.X, (int)p.Y);
                    Point ptR = new Point((int)(R * System.Math.Cos(p.Orientation)),
                                          (int)(R * System.Math.Sin(p.Orientation)));

                    Pen myPen = (p.Laplacian > 0 ? negative : positive);

                    g.DrawEllipse(myPen, pt.X - R, pt.Y - R, S, S);
                    g.DrawLine(line, new Point(pt.X, pt.Y), new Point(pt.X + ptR.X, pt.Y + ptR.Y));
                }
            }

        }
        /// <summary>
        /// Process new video frame.
        /// </summary>
        /// 
        /// <param name="videoFrame">Video frame to process (detect motion in).</param>
        /// 
        /// <remarks><para>Processes new frame from video source and detects motion in it.</para>
        /// 
        /// <para>Check <see cref="MotionLevel"/> property to get information about amount of motion
        /// (changes) in the processed frame.</para>
        /// </remarks>
        /// 
        public unsafe void ProcessFrame( UnmanagedImage videoFrame )
        {
            lock ( sync )
            {
                // check previous frame
                if ( previousFrame == null )
                {
                    // save image dimension
                    width = videoFrame.Width;
                    height = videoFrame.Height;

                    // alocate memory for previous and current frames
                    previousFrame = UnmanagedImage.Create( width, height, videoFrame.PixelFormat );
                    motionFrame = UnmanagedImage.Create( width, height, PixelFormat.Format8bppIndexed );

                    frameSize = videoFrame.Stride * height;
                    motionSize = motionFrame.Stride * height;

                    // temporary buffer
                    if ( suppressNoise )
                    {
                        tempFrame = UnmanagedImage.Create( width, height, PixelFormat.Format8bppIndexed );
                    }

                    // conpy source frame
                    videoFrame.Copy(previousFrame);

                    return;
                }

                // check image dimension
                if ( ( videoFrame.Width != width ) || ( videoFrame.Height != height ) )
                    return;

                // pointers to previous and current frames
                byte* prevFrame = (byte*) previousFrame.ImageData.ToPointer( );
                byte* currFrame = (byte*) videoFrame.ImageData.ToPointer( );
                byte* motion = (byte*) motionFrame.ImageData.ToPointer( );
                byte* currFrameLocal;
                byte* prevFrameLocal;
                byte* motionLocal;
                int bytesPerPixel = Tools.BytesPerPixel( videoFrame.PixelFormat );

                // difference value
                int diff;

                // 1 - get difference between frames
                // 2 - threshold the difference (accumulated over every channels)
                // 3 - copy current frame to previous frame
                for ( int i = 0; i < height; i++ ) {
                    currFrameLocal = currFrame;
                    prevFrameLocal = prevFrame;
                    motionLocal = motion;
                    for ( int j = 0; j < width; j++ ) {
                        diff = 0;
                        for ( int nbBytes = 0; nbBytes < bytesPerPixel; nbBytes++ ) {
                            // difference
                            diff += Math.Abs ((int) *currFrameLocal - (int) *prevFrameLocal);
                            // copy current frame to previous
                            *prevFrameLocal = *currFrameLocal;
                            currFrameLocal++;
                            prevFrameLocal++;
                        }
                        diff /= bytesPerPixel;
                        // threshold
                        *motionLocal = ( diff >= differenceThreshold ) ? (byte) 255 : (byte) 0;
                        motionLocal++;
                    }
                    currFrame += videoFrame.Stride;
                    prevFrame += previousFrame.Stride;
                    motion += motionFrame.Stride;
                }

                if ( suppressNoise )
                {
                    // suppress noise and calculate motion amount
                    AForge.SystemTools.CopyUnmanagedMemory( tempFrame.ImageData, motionFrame.ImageData, motionSize );
                    erosionFilter.Apply( tempFrame, motionFrame );
                }

                // calculate amount of motion pixels
                pixelsChanged = 0;
                motion = (byte*) motionFrame.ImageData.ToPointer( );

                for ( int i = 0; i < motionSize; i++, motion++ )
                {
                    pixelsChanged += ( *motion & 1 );
                }
            }
        }
        /// <summary>
        /// Set background frame.
        /// </summary>
        /// 
        /// <param name="backgroundFrame">Background frame to set.</param>
        /// 
        /// <remarks><para>The method sets background frame, which will be used to calculate
        /// difference with.</para></remarks>
        /// 
        public void SetBackgroundFrame( UnmanagedImage backgroundFrame )
        {
            // reset motion detection algorithm
            Reset( true );

            lock ( sync )
            {
                // save image dimension
                width  = backgroundFrame.Width;
                height = backgroundFrame.Height;

                // alocate memory for previous and current frames
                this.backgroundFrame = UnmanagedImage.Create( width, height, backgroundFrame.PixelFormat );
                frameSize = this.backgroundFrame.Stride * height;

                // convert source frame to grayscale
                backgroundFrame.Copy( this.backgroundFrame );

                manuallySetBackgroundFrame = true;
            }
        }
        /// <summary>
        /// Set background frame.
        /// </summary>
        /// 
        /// <param name="backgroundFrame">Background frame to set.</param>
        /// 
        /// <remarks><para>The method sets background frame, which will be used to calculate
        /// difference with.</para></remarks>
        /// 
        public void SetBackgroundFrame( UnmanagedImage backgroundFrame )
        {
            // reset motion detection algorithm
            Reset( true );

            lock ( _sync )
            {
                // save image dimension
                _width  = backgroundFrame.Width;
                _height = backgroundFrame.Height;

                // alocate memory for previous and current frames
                _backgroundFrame = UnmanagedImage.Create( _width, _height, backgroundFrame.PixelFormat );

                // convert source frame to grayscale
				backgroundFrame.Copy(_backgroundFrame );

                _manuallySetBackgroundFrame = true;
            }
        }
        /// <summary>
        /// Process new video frame.
        /// </summary>
        /// 
        /// <param name="videoFrame">Video frame to process (detect motion in).</param>
        /// 
        /// <remarks><para>Processes new frame from video source and detects motion in it.</para>
        /// 
        /// <para>Check <see cref="MotionLevel"/> property to get information about amount of motion
        /// (changes) in the processed frame.</para>
        /// </remarks>
        /// 
        public unsafe void ProcessFrame( UnmanagedImage videoFrame )
        {
            lock ( _sync )
            {
                // check background frame
                if ( _backgroundFrame == null )
                {
                    // save image dimension
                    _width  = videoFrame.Width;
                    _height = videoFrame.Height;

                    // alocate memory for background frame
                    _backgroundFrame = UnmanagedImage.Create( _width, _height, videoFrame.PixelFormat );

                    // convert source frame to grayscale
					videoFrame.Copy(_backgroundFrame);

                    return;
                }

                // check image dimension
                if ( ( videoFrame.Width != _width ) || ( videoFrame.Height != _height ) )
                    return;

                // check motion frame
                if ( _motionFrame == null )
                {
                    _motionFrame = UnmanagedImage.Create( _width, _height, PixelFormat.Format8bppIndexed );
					_motionSize = _motionFrame.Stride * _height;

                    // temporary buffer
                    if ( _suppressNoise )
                    {
                        _tempFrame = UnmanagedImage.Create( _width, _height, PixelFormat.Format8bppIndexed );
                    }
                }


                // pointers to background and current frames

                var backFrame = (byte*) _backgroundFrame.ImageData.ToPointer( );
                var currFrame = (byte*) videoFrame.ImageData.ToPointer( );
                byte* motion = (byte*) _motionFrame.ImageData.ToPointer( );
                int bytesPerPixel = Tools.BytesPerPixel( videoFrame.PixelFormat );

                // 1 - get difference between frames
                // 2 - threshold the difference (accumulated over every channels)
				for ( int i = 0; i < _height; i++ ) {
					var currFrameLocal = currFrame;
					var backFrameLocal = backFrame;
					var motionLocal = motion;
					for ( int j = 0; j < _width; j++ ) {
						var diff = 0;
						for ( int nbBytes = 0; nbBytes < bytesPerPixel; nbBytes++ ) {
					    	// difference
                    		diff += Math.Abs ( *currFrameLocal -  *backFrameLocal);
							currFrameLocal++;
							backFrameLocal++;
						}
						diff /= bytesPerPixel;
						// threshold
						*motionLocal = ( diff >= _differenceThreshold ) ? (byte) 255 : (byte) 0;
						motionLocal++;
					}
					currFrame += videoFrame.Stride;
					backFrame += _backgroundFrame.Stride;
					motion += _motionFrame.Stride;
				}

                if ( _suppressNoise )
                {
                    // suppress noise and calculate motion amount
                    AForge.SystemTools.CopyUnmanagedMemory( _tempFrame.ImageData, _motionFrame.ImageData, _motionSize );
                    _erosionFilter.Apply( _tempFrame, _motionFrame );

                    if ( _keepObjectEdges )
                    {
                        AForge.SystemTools.CopyUnmanagedMemory( _tempFrame.ImageData, _motionFrame.ImageData, _motionSize );
                        _dilatationFilter.Apply( _tempFrame, _motionFrame );
                    }
                }

                // calculate amount of motion pixels
                _pixelsChanged = 0;
                motion = (byte*) _motionFrame.ImageData.ToPointer( );

                for ( int i = 0; i < _motionSize; i++, motion++ )
                {
                    _pixelsChanged += ( *motion & 1 );
                }
            }
        }