/// <summary>
        /// Calculates dominant color of the region
        /// </summary>
        private PixelData GetDominantColorOfTheRegion(FastBitmap fBitmap, int up, int down, int left, int right)
        {
            fBitmap.LockBitmap();
            List <ColorOccurance> listColors = new List <ColorOccurance>();

            for (int j = up; j < down; j++)
            {
                for (int i = left; i < right; i++)
                {
                    PixelData data = fBitmap.GetPixel(i, j);

                    bool colorFound = false;
                    for (int z = 0; z < listColors.Count; z++)
                    {
                        if ((listColors[z].Color.R + _differenceThreshold > data.R) && (listColors[z].Color.R - _differenceThreshold < data.R) &&
                            (listColors[z].Color.G + _differenceThreshold > data.G) && (listColors[z].Color.G - _differenceThreshold < data.G) &&
                            (listColors[z].Color.B + _differenceThreshold > data.B) && (listColors[z].Color.B - _differenceThreshold < data.B))
                        {
                            listColors[z].Occurance++;
                            colorFound = true;
                        }
                    }
                    if (!colorFound)
                    {
                        ColorOccurance oc = new ColorOccurance();
                        oc.Color = data;
                        listColors.Add(oc);
                    }
                }
            }
            fBitmap.UnlockBitmap();


            // Here we got the list of all colors
            // let's sort
            listColors.Sort();

            // At first position we should have our object color;
            return(listColors[0].Color);
        }
        /// <summary>
        /// Function for processing a separate captured frame
        /// </summary>
        public unsafe void ProcessFrame(Image videoFrame)
        {
            lock (this)
            {
                // check if we started searching
                if (!_initialized)
                {
                    return;
                }

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

                // Easier way to extract pixels
                FastBitmap fBitmap = new FastBitmap(videoFrame);



                // mask for easier processing
                bool[,] newMask = new bool[_width, _height];

                // For new color detection

                long colorR             = 0;
                long colorG             = 0;
                long colorB             = 0;
                int  coloredPixelsCount = 0;

                // defining search color regions
                int deltaX = (_previousPosition.Right - _previousPosition.Left) / 2;

                int left  = (_previousPosition.Left - deltaX > 0) ? _previousPosition.Left - deltaX : 0;
                int right = (_previousPosition.Right + deltaX < _width - 1) ? _previousPosition.Right + deltaX : _width - 1;

                int deltaY = (_previousPosition.Down - _previousPosition.Up) / 2;

                int up   = (_previousPosition.Up - deltaY > 0) ? _previousPosition.Up - deltaY : 0;
                int down = (_previousPosition.Down + deltaY < _height - 1) ? _previousPosition.Down + deltaY : _height - 1;


                fBitmap.LockBitmap();
                for (int j = 0; j < _height; j++)
                {
                    for (int i = 0; i < _width; i++)
                    {
                        PixelData data = fBitmap.GetPixel(i, j);

                        if ((data.R + _differenceThreshold > _targetPDColor.R) && (data.R - _differenceThreshold < _targetPDColor.R) &&
                            (data.G + _differenceThreshold > _targetPDColor.G) && (data.G - _differenceThreshold < _targetPDColor.G) &&
                            (data.B + _differenceThreshold > _targetPDColor.B) && (data.B - _differenceThreshold < _targetPDColor.B) &&
                            (i >= left && i <= right && j >= up && j <= down))
                        {
                            newMask[i, j] = true;

                            coloredPixelsCount++;
                            colorR += data.R;
                            colorG += data.G;
                            colorB += data.B;
                        }
                    }
                }
                fBitmap.UnlockBitmap();



                PixelData gradientFound = new PixelData();

                if (coloredPixelsCount > 0)
                {
                    gradientFound.R = (byte)(colorR / coloredPixelsCount);
                    gradientFound.G = (byte)(colorG / coloredPixelsCount);
                    gradientFound.B = (byte)(colorB / coloredPixelsCount);
                }
                else
                {
                    gradientFound = _targetPDColor;
                }

                // stamping new info to the frame
                Grayscale.CommonAlgorithms.BT709.Apply(UnmanagedImage.FromManagedImage((Bitmap)videoFrame),
                                                       _motionFrame);
                byte *currFrame = (byte *)_motionFrame.ImageData.ToPointer();
                for (int j = 0; j < _height; j++)
                {
                    for (int i = 0; i < _width; i++, currFrame++)
                    {
                        if (j >= up && j <= down &&
                            i >= left && i <= right &&
                            newMask[i, j])
                        {
                            *currFrame = 255;
                        }
                        else
                        {
                            *currFrame = 0;
                        }
                    }
                }

                // to start
                currFrame = (byte *)_motionFrame.ImageData.ToPointer();

                bool firstTime = true;

                // Here  - we should find new points
                for (int j = 0; j < _height; j++)
                {
                    for (int i = 0; i < _width; i++, currFrame++)
                    {
                        if (*currFrame == 255)
                        {
                            if (firstTime)
                            {
                                up    = j;
                                down  = j;
                                left  = i;
                                right = i;

                                firstTime = false;
                            }
                            else
                            {
                                if (i < left)
                                {
                                    left = i;
                                }
                                if (i > right)
                                {
                                    right = i;
                                }
                                if (j < up)
                                {
                                    up = j;
                                }
                                if (j > down)
                                {
                                    down = j;
                                }
                            }
                        }
                    }
                }

                // Here - revision. If found object is too small - than we have a problem....
                // let's better leave last links to the object
                if (right - left < SIZE_THRESHOLD || down - up < SIZE_THRESHOLD)
                {
                    if (down - up >= _previousPosition.Down - _previousPosition.Up)
                    {
                        _previousPosition.Up   = up;
                        _previousPosition.Down = down;
                    }
                    if (right - left >= _previousPosition.Right - _previousPosition.Left)
                    {
                        _previousPosition.Right = right;
                        _previousPosition.Left  = left;
                    }
                }
                else
                {
                    _previousPosition.Up    = up;
                    _previousPosition.Down  = down;
                    _previousPosition.Right = right;
                    _previousPosition.Left  = left;

                    // And one more. If we need to calculate new color of the region - let's do it
                    // but not when image is the WHOLE screen
                    if (_dynamicallyCalculateNewColor)
                    {
                        // this is more reliable, but not really tested
                        _targetPDColor.R = gradientFound.R;
                        _targetPDColor.G = gradientFound.G;
                        _targetPDColor.B = gradientFound.B;
                    }
                }
            }
        }
Example #3
0
        public void SetPixel(int x, int y, PixelData colour)
        {
            PixelData *pixel = PixelAt(x, y);

            *pixel = colour;
        }
Example #4
0
        public PixelData GetPixel(int x, int y)
        {
            PixelData returnValue = *PixelAt(x, y);

            return(returnValue);
        }