Esempio n. 1
0
        /// <summary>
        /// Create a rotation matrix for rotating an image
        /// </summary>
        /// <param name="angle">The rotation angle in degrees. Positive values mean couter-clockwise rotation (the coordiate origin is assumed at image centre). </param>
        /// <param name="center">The rotation center</param>
        /// <param name="srcImageSize">The source image size</param>
        /// <param name="dstImageSize">The minimun size of the destination image</param>
        /// <returns>The rotation matrix that rotate the source image to the destination image.</returns>
        public static RotationMatrix2D CreateRotationMatrix(PointF center, double angle, Size srcImageSize, out Size dstImageSize)
        {
            RotationMatrix2D rotationMatrix = new RotationMatrix2D(center, angle, 1);

            PointF[] corners = new PointF[] {
                new PointF(0, 0),
                new PointF(srcImageSize.Width - 1, 0),
                new PointF(srcImageSize.Width - 1, srcImageSize.Height - 1),
                new PointF(0, srcImageSize.Height - 1)
            };
            rotationMatrix.RotatePoints(corners);
            int minX = (int)Math.Round(Math.Min(Math.Min(corners[0].X, corners[1].X), Math.Min(corners[2].X, corners[3].X)));
            int maxX = (int)Math.Round(Math.Max(Math.Max(corners[0].X, corners[1].X), Math.Max(corners[2].X, corners[3].X)));
            int minY = (int)Math.Round(Math.Min(Math.Min(corners[0].Y, corners[1].Y), Math.Min(corners[2].Y, corners[3].Y)));
            int maxY = (int)Math.Round(Math.Max(Math.Max(corners[0].Y, corners[1].Y), Math.Max(corners[2].Y, corners[3].Y)));

            using (Matrix <double> offset = new Matrix <double>(2, 3))
            {
                offset[0, 2] = minX;
                offset[1, 2] = minY;
                CvInvoke.Subtract(rotationMatrix, offset, rotationMatrix);
                //rotationMatrix[0, 2] -= minX;
                //rotationMatrix[1, 2] -= minY;
            }
            dstImageSize = new Size(maxX - minX + 1, maxY - minY + 1);
            return(rotationMatrix);
        }
Esempio n. 2
0
        /// <summary>
        /// Return a clone of the Matrix
        /// </summary>
        /// <returns>A clone of the Matrix</returns>
        public new RotationMatrix2D <T> Clone()
        {
            RotationMatrix2D <T> clone = new RotationMatrix2D <T>();

            CvInvoke.cvCopy(_ptr, clone, IntPtr.Zero);
            return(clone);
        }
Esempio n. 3
0
        /// <summary>
        /// Estimate rigid transformation between 2 point sets.
        /// </summary>
        /// <param name="src">The points from the source image</param>
        /// <param name="dest">The corresponding points from the destination image</param>
        /// <param name="fullAffine">Indicates if full affine should be performed</param>
        /// <returns>If success, the 2x3 rotation matrix that defines the Affine transform. Otherwise null is returned.</returns>
        public static RotationMatrix2D <double> EstimateRigidTransform(PointF[] src, PointF[] dest, bool fullAffine)
        {
            RotationMatrix2D <double> result = new RotationMatrix2D <double>();
            GCHandle handleA = GCHandle.Alloc(src, GCHandleType.Pinned);
            GCHandle handleB = GCHandle.Alloc(dest, GCHandleType.Pinned);
            bool     success;

            using (Matrix <float> a = new Matrix <float>(src.Length, 1, 2, handleA.AddrOfPinnedObject(), 2 * sizeof(float)))
                using (Matrix <float> b = new Matrix <float>(dest.Length, 1, 2, handleB.AddrOfPinnedObject(), 2 * sizeof(float)))
                {
                    success = CvInvoke.cvEstimateRigidTransform(a, b, result, fullAffine);
                }
            handleA.Free();
            handleB.Free();

            if (success)
            {
                return(result);
            }
            else
            {
                result.Dispose();
                return(null);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Return a clone of the Matrix
        /// </summary>
        /// <returns>A clone of the Matrix</returns>
        public new RotationMatrix2D Clone()
        {
            RotationMatrix2D clone = new RotationMatrix2D();

            CopyTo(clone);
            //CvInvoke.cvCopy(_ptr, clone, IntPtr.Zero);
            return(clone);
        }
Esempio n. 5
0
        /// <summary>
        /// Calculates the matrix of an affine transform such that:
        /// (x'_i,y'_i)^T=map_matrix (x_i,y_i,1)^T
        /// where dst(i)=(x'_i,y'_i), src(i)=(x_i,y_i), i=0..2.
        /// </summary>
        /// <param name="src">Coordinates of 3 triangle vertices in the source image. If the array contains more than 3 points, only the first 3 will be used</param>
        /// <param name="dest">Coordinates of the 3 corresponding triangle vertices in the destination image. If the array contains more than 3 points, only the first 3 will be used</param>
        /// <returns>The 2x3 rotation matrix that defines the Affine transform</returns>
        public static RotationMatrix2D <double> GetAffineTransform(PointF[] src, PointF[] dest)
        {
            Debug.Assert(src.Length >= 3, "The source should contain at least 3 points");
            Debug.Assert(dest.Length >= 3, "The destination should contain at least 3 points");

            RotationMatrix2D <double> rot = new RotationMatrix2D <double>();

            CvInvoke.cvGetAffineTransform(src, dest, rot);
            return(rot);
        }
Esempio n. 6
0
        /// <summary>
        /// Generate a random point cloud around the ellipse.
        /// </summary>
        /// <param name="e">The region where the point cloud will be generated. The axes of e corresponds to std of the random point cloud.</param>
        /// <param name="numberOfPoints">The number of points to be generated</param>
        /// <returns>A random point cloud around the ellipse</returns>
        public static PointF[] GeneratePointCloud(Ellipse e, int numberOfPoints)
        {
            PointF[] cloud  = new PointF[numberOfPoints];
            GCHandle handle = GCHandle.Alloc(cloud, GCHandleType.Pinned);

            using (Matrix <float> points = new Matrix <float>(numberOfPoints, 2, handle.AddrOfPinnedObject()))
                using (Matrix <float> xValues = points.GetCol(0))
                    using (Matrix <float> yValues = points.GetCol(1))
                        using (RotationMatrix2D <float> rotation = new RotationMatrix2D <float>(e.MCvBox2D.center, e.MCvBox2D.angle, 1.0))
                        {
                            xValues.SetRandNormal(new MCvScalar(e.MCvBox2D.center.X), new MCvScalar(e.MCvBox2D.size.Width / 2.0f));
                            yValues.SetRandNormal(new MCvScalar(e.MCvBox2D.center.Y), new MCvScalar(e.MCvBox2D.size.Height / 2.0f));
                            rotation.RotatePoints(points);
                        }
            handle.Free();
            return(cloud);
        }
Esempio n. 7
0
        /*
          /// <summary>
          /// Re-project pixels on a 1-channel disparity map to array of 3D points.
          /// </summary>
          /// <param name="disparity">Disparity map</param>
          /// <param name="Q">The re-projection 4x4 matrix, can be arbitrary, e.g. the one, computed by cvStereoRectify</param>
          /// <returns>The reprojected 3D points</returns>
          public static MCvPoint3D32f[] ReprojectImageTo3D(Image<Gray, Byte> disparity, Matrix<double> Q)
          {
         Size size = disparity.Size;
         MCvPoint3D32f[] points3D = new MCvPoint3D32f[size.Width * size.Height];
         GCHandle handle = GCHandle.Alloc(points3D, GCHandleType.Pinned);

         using (Matrix<float> pts = new Matrix<float>(size.Height, size.Width, 3, handle.AddrOfPinnedObject(), 0))
            CvInvoke.ReprojectImageTo3D(disparity, pts, Q, false, CvEnum.DepthType.Cv32F);

         handle.Free();
         return points3D;
          }*/
        /// <summary>
        /// Generate a random point cloud around the ellipse. 
        /// </summary>
        /// <param name="e">The region where the point cloud will be generated. The axes of e corresponds to std of the random point cloud.</param>
        /// <param name="numberOfPoints">The number of points to be generated</param>
        /// <returns>A random point cloud around the ellipse</returns>
        public static PointF[] GeneratePointCloud(Ellipse e, int numberOfPoints)
        {
            PointF[] cloud = new PointF[numberOfPoints];
             GCHandle handle = GCHandle.Alloc(cloud, GCHandleType.Pinned);
             using (Matrix<float> points = new Matrix<float>(numberOfPoints, 2, handle.AddrOfPinnedObject()))
             using (Matrix<float> xValues = points.GetCol(0))
             using (Matrix<float> yValues = points.GetCol(1))
             using (RotationMatrix2D rotation = new RotationMatrix2D(e.RotatedRect.Center, e.RotatedRect.Angle, 1.0))
             using (Mat tmp = new Mat())
             {
            rotation.ConvertTo(tmp, DepthType.Cv32F);
            xValues.SetRandNormal(new MCvScalar(e.RotatedRect.Center.X), new MCvScalar(e.RotatedRect.Size.Width / 2.0f));
            yValues.SetRandNormal(new MCvScalar(e.RotatedRect.Center.Y), new MCvScalar(e.RotatedRect.Size.Height / 2.0f));
            rotation.RotatePoints(points);
             }
             handle.Free();
             return cloud;
        }
Esempio n. 8
0
        /// <summary>
        /// Create a rotation matrix for rotating an image
        /// </summary>
        /// <param name="angle">The rotation angle in degrees. Positive values mean couter-clockwise rotation (the coordiate origin is assumed at image centre). </param>
        /// <param name="center">The rotation center</param>
        /// <param name="srcImageSize">The source image size</param>
        /// <param name="dstImageSize">The minimun size of the destination image</param>
        /// <returns>The rotation matrix that rotate the source image to the destination image.</returns>
        public static RotationMatrix2D <float> CreateRotationMatrix(PointF center, double angle, Size srcImageSize, out Size dstImageSize)
        {
            RotationMatrix2D <float> rotationMatrix = new RotationMatrix2D <float>(center, angle, 1);

            PointF[] corners = new PointF[] {
                new PointF(0, 0),
                new PointF(srcImageSize.Width - 1, 0),
                new PointF(srcImageSize.Width - 1, srcImageSize.Height - 1),
                new PointF(0, srcImageSize.Height - 1)
            };
            rotationMatrix.RotatePoints(corners);
            int minX = (int)Math.Round(Math.Min(Math.Min(corners[0].X, corners[1].X), Math.Min(corners[2].X, corners[3].X)));
            int maxX = (int)Math.Round(Math.Max(Math.Max(corners[0].X, corners[1].X), Math.Max(corners[2].X, corners[3].X)));
            int minY = (int)Math.Round(Math.Min(Math.Min(corners[0].Y, corners[1].Y), Math.Min(corners[2].Y, corners[3].Y)));
            int maxY = (int)Math.Round(Math.Max(Math.Max(corners[0].Y, corners[1].Y), Math.Max(corners[2].Y, corners[3].Y)));

            rotationMatrix[0, 2] -= minX;
            rotationMatrix[1, 2] -= minY;

            dstImageSize = new Size(maxX - minX + 1, maxY - minY + 1);
            return(rotationMatrix);
        }