/// <summary> /// Extracts shape inside the given RotatedRect and un-warps it /// </summary> /// <param name="input">Input image</param> /// <param name="points">Sorted corners of the shape</param> /// <param name="corners">Downscaling option, biggest size with be re-scaled to this value. 0 means no downscaling (default value)</param> /// <returns>New OpenCV Mat with un-warped object</returns> public static Mat UnwrapShape(this Mat img, Point2f[] corners, int maxSize = 0) { if (corners.Length != 4) { throw new OpenCvSharpException("argument 'points' must be of length = 4"); } // grab bounds corners, sort them in correct order and // get width/height of the shape float width = (float)Point2f.Distance(corners[0], corners[1]); // lt -> rt float height = (float)Point2f.Distance(corners[0], corners[3]); // lt -> lb // downscaling if (maxSize > 0 && (width > maxSize || height > maxSize)) { if (width > height) { var s = maxSize / width; width = maxSize; height = height * s; } else { var s = maxSize / height; height = maxSize; width = width * s; } } // compute transform Point2f[] destination = new Point2f[] { new Point2f(0, 0), new Point2f(width, 0), new Point2f(width, height), new Point2f(0, height) }; var transform = Cv2.GetPerspectiveTransform(corners, destination); // un-warp return(img.WarpPerspective(transform, new Size(width, height), InterpolationFlags.Cubic)); }
private static Mat FourPointTransform(Mat image, Mat pts) { //obtain a consistent order of the points and unpack them //individually Tuple <Point2f, Point2f, Point2f, Point2f> orderedPoints = OrderPoints(pts); Point2f tl = orderedPoints.Item1, tr = orderedPoints.Item2, br = orderedPoints.Item3, bl = orderedPoints.Item4; //compute the width of the new image, which will be the //maximum distance between bottom-right and bottom-left //x-coordiates or the top-right and top-left x-coordinates double widthA = Point2f.Distance(bl, br); double widthB = Point2f.Distance(tl, tr); int maxWidth = Math.Max((int)widthA, (int)widthB); //compute the height of the new image, which will be the //maximum distance between the top-right and bottom-right //y-coordinates or the top-left and bottom-left y-coordinates double heightA = Point2f.Distance(tr, br); double heightB = Point2f.Distance(tl, bl); int maxHeight = Math.Max((int)heightA, (int)heightB); //now that we have the dimensions of the new image, construct //the set of destination points to obtain a "birds eye view", //(i.e. top-down view) of the image, again specifying points //in the top-left, top-right, bottom-right, and bottom-left //order var dst = new[] { new Point2f(0, 0), new Point2f(maxWidth - 1, 0), new Point2f(maxWidth - 1, maxHeight - 1), new Point2f(0, maxHeight - 1), }; //compute the perspective transform matrix and then apply it using (Mat m = Cv2.GetPerspectiveTransform(new[] { tl, tr, br, bl }, dst)) { Mat warped = image.WarpPerspective(m, new Size(maxWidth, maxHeight)); return(warped); } }