Esempio n. 1
1
        private static Rectangle process(Gray<byte>[,] probabilityMap, Rectangle roi, TermCriteria termCriteria, out CentralMoments centralMoments)
        {
            Rectangle imageArea = new Rectangle(0, 0, probabilityMap.Width(), probabilityMap.Height());

            Rectangle searchWindow = roi;
            RawMoments moments = new RawMoments(order: 1);

            // Mean shift with fixed number of iterations
            int i = 0;
            double shift = Byte.MaxValue;
            while (termCriteria.ShouldTerminate(i, shift) == false && !searchWindow.IsEmptyArea())
            {
                // Locate first order moments
                moments.Compute(probabilityMap, searchWindow);

                int shiftX = (int)(moments.CenterX - searchWindow.Width / 2f);
                int shiftY = (int)(moments.CenterY - searchWindow.Height / 2f);

                // Shift the mean (centroid)
                searchWindow.X += shiftX;
                searchWindow.Y += shiftY;

                // Keep the search window inside the image
                searchWindow.Intersect(imageArea);
                
                shift = System.Math.Abs((double)shiftX) + System.Math.Abs((double)shiftY); //for term criteria only
                i++;
            }

            if (searchWindow.IsEmptyArea() == false)
            {
                // Locate second order moments and perform final shift
                moments.Order = 2;
                moments.Compute(probabilityMap, searchWindow);

                searchWindow.X += (int)(moments.CenterX - searchWindow.Width / 2f);
                searchWindow.Y += (int)(moments.CenterY - searchWindow.Height / 2f);

                // Keep the search window inside the image
                searchWindow.Intersect(imageArea);
            }

            centralMoments = new CentralMoments(moments); // moments to be used by camshift
            return searchWindow;
        }
Esempio n. 2
0
        private unsafe static void goodFeaturesToTrack(Gray <float>[,] integralDxx, Gray <float>[,] integralDxy, Gray <float>[,] integralDyy,
                                                       int winSize, float minEigValue, Gray <float>[,] strengthImg)
        {
            minEigValue = System.Math.Max(1E-3f, minEigValue);
            int normFactor = winSize * winSize * 255;

            int maxCol = integralDxx.Width() - winSize;
            int maxRow = integralDxx.Height() - winSize;

            for (int row = 0; row < maxRow; row++)
            {
                for (int col = 0; col < maxCol; col++)
                {
                    var Dxx = integralDxx.GetSum(col, row, winSize, winSize);
                    var Dxy = integralDxy.GetSum(col, row, winSize, winSize);
                    var Dyy = integralDyy.GetSum(col, row, winSize, winSize);

                    var eigenVal = calcMinEigenVal(Dxx, Dxy, Dyy);
                    eigenVal /= normFactor;

                    if (eigenVal > minEigValue)
                    {
                        strengthImg[winSize / 2 + row, winSize / 2 + col] = eigenVal;
                    }
                }
            }
        }
        private unsafe static void goodFeaturesToTrack(Gray<float>[,] integralDxx, Gray<float>[,] integralDxy, Gray<float>[,] integralDyy,
                                                       int winSize, float minEigValue, Gray<float>[,] strengthImg)
        {
            minEigValue = System.Math.Max(1E-3f, minEigValue);
            int normFactor = winSize * winSize * 255;

            int maxCol = integralDxx.Width() - winSize;
            int maxRow = integralDxx.Height() - winSize;

            for (int row = 0; row < maxRow; row++)
            {
                for (int col = 0; col < maxCol; col++)
                {
                    var Dxx = integralDxx.GetSum(col, row, winSize, winSize);
                    var Dxy = integralDxy.GetSum(col, row, winSize, winSize);
                    var Dyy = integralDyy.GetSum(col, row, winSize, winSize);

                    var eigenVal = calcMinEigenVal(Dxx, Dxy, Dyy);
                    eigenVal /= normFactor;

                    if (eigenVal > minEigValue)
                    {
                        strengthImg[winSize / 2 + row, winSize / 2 + col] = eigenVal;
                    }
                }
            }
        }
        private static ComplexF[,] prepareImage(Gray <float>[,] image, int biggestKernelWidth, int biggestKernelHeight,
                                                ConvolutionBorder options,
                                                out int fillX, out int fillY)
        {
            int FFTNumOfCols = (int)System.Math.Pow(2.0, System.Math.Ceiling(System.Math.Log(biggestKernelWidth + image.Width(), 2.0)));
            int FFTNumOfRows = (int)System.Math.Pow(2.0, System.Math.Ceiling(System.Math.Log(biggestKernelHeight + image.Height(), 2.0)));

            fillX = System.Math.Min(image.Width(), biggestKernelWidth / 2);
            fillY = System.Math.Min(image.Height(), biggestKernelHeight / 2);

            var paddedImage = new Gray <float> [FFTNumOfRows, FFTNumOfCols];

            //center
            image.CopyTo(paddedImage, new Point(fillX, fillY));

            if (options == ConvolutionBorder.BorderMirror)
            {
                mirrorBorders(image, paddedImage, fillX, fillY);
            }

            var paddedImageCmplx = paddedImage.ToComplex();

            paddedImageCmplx.FFT(FourierTransform.Direction.Forward, true);
            return(paddedImageCmplx);
        }
Esempio n. 5
0
        private static Rectangle process(Gray <byte>[,] probabilityMap, Rectangle roi, TermCriteria termCriteria, out CentralMoments centralMoments)
        {
            Rectangle imageArea = new Rectangle(0, 0, probabilityMap.Width(), probabilityMap.Height());

            Rectangle  searchWindow = roi;
            RawMoments moments      = new RawMoments(order: 1);

            // Mean shift with fixed number of iterations
            int    i     = 0;
            double shift = Byte.MaxValue;

            while (termCriteria.ShouldTerminate(i, shift) == false && !searchWindow.IsEmptyArea())
            {
                // Locate first order moments
                moments.Compute(probabilityMap, searchWindow);

                int shiftX = (int)(moments.CenterX - searchWindow.Width / 2f);
                int shiftY = (int)(moments.CenterY - searchWindow.Height / 2f);

                // Shift the mean (centroid)
                searchWindow.X += shiftX;
                searchWindow.Y += shiftY;

                // Keep the search window inside the image
                searchWindow.Intersect(imageArea);

                shift = System.Math.Abs((double)shiftX) + System.Math.Abs((double)shiftY); //for term criteria only
                i++;
            }

            if (searchWindow.IsEmptyArea() == false)
            {
                // Locate second order moments and perform final shift
                moments.Order = 2;
                moments.Compute(probabilityMap, searchWindow);

                searchWindow.X += (int)(moments.CenterX - searchWindow.Width / 2f);
                searchWindow.Y += (int)(moments.CenterY - searchWindow.Height / 2f);

                // Keep the search window inside the image
                searchWindow.Intersect(imageArea);
            }

            centralMoments = new CentralMoments(moments); // moments to be used by camshift
            return(searchWindow);
        }
        /// <summary>
        /// Computes gradient orientations from the color image. Orientation from the channel which has the maximum gradient magnitude is taken as the orientation for a location.
        /// </summary>
        /// <param name="frame">Image.</param>
        /// <param name="magnitudeSqrImage">Squared magnitude image.</param>
        /// <param name="minValidMagnitude">Minimal valid magnitude.</param>
        /// <returns>Orientation image (angles are in degrees).</returns>
        public static unsafe Gray<int>[,] Compute(Gray<byte>[,] frame, out Gray<int>[,] magnitudeSqrImage, int minValidMagnitude)
        {
            var minSqrMagnitude = minValidMagnitude * minValidMagnitude;

            var orientationImage = new Gray<int>[frame.Height(), frame.Width()];
            var _magnitudeSqrImage = orientationImage.CopyBlank();

            using (var uFrame = frame.Lock())
            {
                ParallelLauncher.Launch(thread =>
                {
                    computeGray(thread, (byte*)uFrame.ImageData, uFrame.Stride, orientationImage, _magnitudeSqrImage, minSqrMagnitude);
                },
                frame.Width() - 2 * kernelRadius, frame.Height() - 2 * kernelRadius);
            }

            magnitudeSqrImage = _magnitudeSqrImage;
            return orientationImage;
        }
        private static Gray<byte>[,] QuantizeOrientations(Gray<int>[,] orientDegImg)
        {
            var quantizedUnfilteredOrient = new Gray<byte>[orientDegImg.Height(), orientDegImg.Width()];

            using (var uOrientDegImg = orientDegImg.Lock())
            using (var uQuantizedUnfilteredOrient = quantizedUnfilteredOrient.Lock())
            {
                int* orientDegImgPtr = (int*)uOrientDegImg.ImageData;
                byte* qOrinetUnfilteredPtr = (byte*)uQuantizedUnfilteredOrient.ImageData;
                int qOrinetUnfilteredStride = uQuantizedUnfilteredOrient.Stride;

                int imgWidth = uOrientDegImg.Width;
                int imgHeight = uOrientDegImg.Height;

                for (int j = 0; j < imgHeight; j++)
                {
                    for (int i = 0; i < imgWidth; i++)
                    {
                        int angle = orientDegImgPtr[i];
                        qOrinetUnfilteredPtr[i] = AngleQuantizationTable[angle]; //[0-360] -> [...] -> [0-7] (for mapping see "CalculateAngleQuantizationTable()")
                    }

                    orientDegImgPtr += imgWidth; //<Gray<int>> is always alligned
                    qOrinetUnfilteredPtr += qOrinetUnfilteredStride;
                }
            }

            //quantizedUnfilteredOrient.Mul(36).Save("quantizedUnfilteredImg.bmp");
            return quantizedUnfilteredOrient;
        }
        /// <summary>
        /// Creates linear response maps.
        /// </summary>
        /// <param name="orientationDegImg">Orientation image (in degrees).</param>
        /// <param name="neigborhood">Spread neighborhood size.</param>
        public LinearizedMaps(Gray<int>[,] orientationDegImg, int neigborhood)
        {
            this.NeigborhoodSize = neigborhood;
            this.ImageSize = orientationDegImg.Size();
            
            this.LinearMapSize = new Size(orientationDegImg.Width() / neigborhood, orientationDegImg.Height() / neigborhood);
            this.ImageValidSize = new Size(this.LinearMapSize.Width * neigborhood, this.LinearMapSize.Height * neigborhood);

            this.LinearMaps = calculate(orientationDegImg);
        }