/// <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); }
/// <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); }
/* /// <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; }
/// <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); }