예제 #1
0
        public unsafe UnmanagedImage ShowDerivative(UnmanagedImage imageA, UnmanagedImage imageB, DerivativeComponent component)
        {
            UnmanagedImage result  = UnmanagedImage.Create(imageA.Width, imageA.Height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
            byte *         ptrBase = (byte *)result.ImageData.ToPointer();
            byte *         ptr     = ptrBase;

            for (int i = 0; i < imageA.Height - 1; i++)
            {
                for (int j = 0; j < imageA.Width - 1; j++)
                {
                    Derivative3 dI = CalculateDerivative(imageA, imageB, j, i);

                    ptr = ptrBase + (i * result.Stride + j);

                    float value = 0f;

                    switch (component)
                    {
                    case DerivativeComponent.X: value = dI.X; break;

                    case DerivativeComponent.Y: value = dI.Y; break;

                    case DerivativeComponent.t: value = dI.t; break;

                    default: break;
                    }

                    *ptr = (byte)Math.Min(255, Math.Max(0, value));
                }
            }

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Calculates full velocity feild uses integral repsenetations to speed up
        /// </summary>
        public unsafe Point[,] CalculateVelocityField(UnmanagedImage imageA, UnmanagedImage imageB)
        {
            int width  = imageA.Width;
            int height = imageA.Height;

            float[,] IxIx = new float[height, width];
            float[,] IxIy = new float[height, width];
            float[,] IyIy = new float[height, width];
            float[,] ItIx = new float[height, width];
            float[,] ItIy = new float[height, width];

            // calculate integral representation

            //Parallel.For(0, height, (i) =>
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    Derivative3 curdI = CalculateDerivative(imageA, imageB, j, i);

                    IxIx[i, j] = CalcualateIntegralElement(IxIx, i, j, curdI.X * curdI.X);
                    IxIy[i, j] = CalcualateIntegralElement(IxIy, i, j, curdI.X * curdI.Y);
                    IyIy[i, j] = CalcualateIntegralElement(IyIy, i, j, curdI.Y * curdI.Y);
                    ItIx[i, j] = CalcualateIntegralElement(ItIx, i, j, curdI.t * curdI.X);
                    ItIy[i, j] = CalcualateIntegralElement(ItIy, i, j, curdI.t * curdI.Y);
                }
            }

            Point[,] velocities = new Point[height, width];

            int winW = 2 * _winXRadius + 1;
            int winH = 2 * _winYRadius + 1;

            Parallel.For(0, width - winW + 1, (winX) =>
                         //for (int winX = 0; winX <= width - winW; winX++)
            {
                for (int winY = 0; winY <= height - winH; winY++)
                {
                    // calculate G and b into window
                    float IxIxWinValue = GetRegionSumFromIntegralRepresentation(IxIx, winX, winY, winW, winH);
                    float IxIyWinValue = GetRegionSumFromIntegralRepresentation(IxIy, winX, winY, winW, winH);
                    float IyIyWinValue = GetRegionSumFromIntegralRepresentation(IyIy, winX, winY, winW, winH);
                    float ItIxWinValue = GetRegionSumFromIntegralRepresentation(ItIx, winX, winY, winW, winH);
                    float ItIyWinValue = GetRegionSumFromIntegralRepresentation(ItIy, winX, winY, winW, winH);

                    float[,] G = new float[2, 2] {
                        { IxIxWinValue, IxIyWinValue }, { IxIyWinValue, IyIyWinValue }
                    };
                    float[] b = new float[2] {
                        ItIxWinValue, ItIyWinValue
                    };

                    velocities[winY + _winYRadius, winX + _winXRadius] = Solve2x2LinearMatrixEquation(G, b);
                }
            });

            return(velocities);
        }
예제 #3
0
        //public Point IterativeCalculateVelocity(UnmanagedImage imageA, UnmanagedImage imageB, IntPoint point, bool weightedWindow, int maxIterations)
        //{
        //    float[,] G = new float[2, 2];
        //    float[] b;

        //    #region Calculating G
        //    for (int i = point.Y - WindowHalfHeight; i < point.Y + WindowHalfHeight; i++)
        //    {
        //        for (int j = point.X - WindowHalfWidth; j < point.X + WindowHalfWidth; j++)
        //        {
        //            Derivative3 dIij = CalculateDerivative(imageA, imageB, j, i);

        //            if (!weightedWindow)
        //            {
        //                G[0, 0] += dIij.X * dIij.X;
        //                G[1, 1] += dIij.Y * dIij.Y;
        //                G[0, 1] += dIij.X * dIij.Y;
        //                G[1, 0] = G[0, 1];
        //            }
        //            else // weightedWindow
        //            {
        //                int dx = j - point.X;
        //                int dy = i - point.Y;

        //                float w = alpha * (float)Math.Exp(beta * (dx * dx + dy * dy) / (float)(WindowHalfWidth * WindowHalfWidth + WindowHalfHeight * WindowHalfHeight));

        //                G[0, 0] += w * dIij.X * dIij.X;
        //                G[1, 1] += w * dIij.Y * dIij.Y;
        //                G[0, 1] += w * dIij.X * dIij.Y;
        //                G[1, 0] = G[0, 1];
        //            }
        //        }
        //    }
        //    #endregion

        //    Point shift = new Point();

        //    for (int iter = 0; iter < maxIterations; iter++)
        //    {
        //        #region Iteration: Calculating vector b
        //        b = new float[2];

        //        for (int i = point.Y - WindowHalfHeight; i < point.Y + WindowHalfHeight; i++)
        //        {
        //            for (int j = point.X - WindowHalfWidth; j < point.X + WindowHalfWidth; j++)
        //            {
        //                Derivative3 dIij = CalculateDerivative(imageA, imageB, j, i, (int)Math.Round(shift.X), (int)Math.Round(shift.Y));

        //                if (!weightedWindow)
        //                {
        //                    b[0] += dIij.X * dIij.t;
        //                    b[1] += dIij.Y * dIij.t;
        //                }
        //                else // weightedWindow
        //                {
        //                    int dx = j - point.X;
        //                    int dy = i - point.Y;

        //                    float w = alpha * (float)Math.Exp(beta * (dx * dx + dy * dy) / (float)(WindowHalfWidth * WindowHalfWidth + WindowHalfHeight * WindowHalfHeight));

        //                    b[0] += w * dIij.X * dIij.t;
        //                    b[1] += w * dIij.Y * dIij.t;
        //                }
        //            }
        //        }
        //        #endregion

        //        Point dP = SolveMatrixEquation(G, b);

        //        if (dP.EuclideanNorm() < 1f)
        //            return shift + dP;

        //        shift += dP;
        //    }

        //    return shift;
        //}
        public Point CalculateVelocity(UnmanagedImage imageA, UnmanagedImage imageB, IntPoint point, bool weightedWindow)
        {
            float[,] G = new float[2, 2];
            float[] b = new float[2];

            int px = point.X;
            int py = point.Y;

            for (int i = py - _winYRadius; i < py + _winYRadius; i++)
            {
                for (int j = px - _winXRadius; j < px + _winXRadius; j++)
                {
                    Derivative3 d = CalculateDerivative(imageA, imageB, j, i);

                    if (!weightedWindow)
                    {
                        G[0, 0] += d.X * d.X;
                        G[1, 1] += d.Y * d.Y;
                        G[0, 1] += d.X * d.Y;
                        G[1, 0]  = G[0, 1];

                        b[0] += d.X * d.t;
                        b[1] += d.Y * d.t;
                    }
                    else // weightedWindow
                    {
                        int dxAbs = j - px; dxAbs = dxAbs < 0 ? -dxAbs : dxAbs;
                        int dyAbs = i - py; dyAbs = dyAbs < 0 ? -dyAbs : dyAbs;

                        float w = _weight[dxAbs, dyAbs];

                        G[0, 0] += w * d.X * d.X;
                        G[1, 1] += w * d.Y * d.Y;
                        G[0, 1] += w * d.X * d.Y;
                        G[1, 0]  = G[0, 1];

                        b[0] += w * d.X * d.t;
                        b[1] += w * d.Y * d.t;
                    }
                }
            }

            return(Solve2x2LinearMatrixEquation(G, b));
        }