├── README.md ├── input └── document.jpg ├── output └── document.jpg ├── warp_perspective_basic.py └── warp_perspective.py /README.md: -------------------------------------------------------------------------------- 1 | # Warp_perspective 2 | Warp perspective using OpenCV 3 | -------------------------------------------------------------------------------- /input/document.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codegiovanni/Warp_perspective/HEAD/input/document.jpg -------------------------------------------------------------------------------- /output/document.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codegiovanni/Warp_perspective/HEAD/output/document.jpg -------------------------------------------------------------------------------- /warp_perspective_basic.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | img = cv2.imread('input/document.jpg') 5 | 6 | # Pixel values in the original image 7 | input_points = np.float32([[83, 18], [342, 53], [14, 389], [295, 436]]) 8 | 9 | # Output image size 10 | width = 400 11 | height = int(width * 1.414) # for A4 12 | 13 | # Desired points values in the output image 14 | converted_points = np.float32([[0, 0], [width, 0], [0, height], [width, height]]) 15 | 16 | # Perspective transformation 17 | matrix = cv2.getPerspectiveTransform(input_points, converted_points) 18 | img_output = cv2.warpPerspective(img, matrix, (width, height)) 19 | 20 | cv2.imshow('Original', img) 21 | cv2.imshow('Warped perspective', img_output) 22 | 23 | # cv2.imwrite('output/document.jpg', img_output) 24 | 25 | cv2.waitKey(0) 26 | -------------------------------------------------------------------------------- /warp_perspective.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | def biggest_contour(contours): 6 | biggest = np.array([]) 7 | max_area = 0 8 | for i in contours: 9 | area = cv2.contourArea(i) 10 | if area > 1000: 11 | peri = cv2.arcLength(i, True) 12 | approx = cv2.approxPolyDP(i, 0.015 * peri, True) 13 | if area > max_area and len(approx) == 4: 14 | biggest = approx 15 | max_area = area 16 | return biggest 17 | 18 | 19 | img = cv2.imread('input/document.jpg') 20 | img_original = img.copy() 21 | 22 | # Image modification 23 | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 24 | gray = cv2.bilateralFilter(gray, 20, 30, 30) 25 | edged = cv2.Canny(gray, 10, 20) 26 | 27 | # Contour detection 28 | contours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 29 | contours = sorted(contours, key=cv2.contourArea, reverse=True)[:10] 30 | 31 | biggest = biggest_contour(contours) 32 | 33 | cv2.drawContours(img, [biggest], -1, (0, 255, 0), 3) 34 | 35 | # Pixel values in the original image 36 | points = biggest.reshape(4, 2) 37 | input_points = np.zeros((4, 2), dtype="float32") 38 | 39 | points_sum = points.sum(axis=1) 40 | input_points[0] = points[np.argmin(points_sum)] 41 | input_points[3] = points[np.argmax(points_sum)] 42 | 43 | points_diff = np.diff(points, axis=1) 44 | input_points[1] = points[np.argmin(points_diff)] 45 | input_points[2] = points[np.argmax(points_diff)] 46 | 47 | (top_left, top_right, bottom_right, bottom_left) = input_points 48 | bottom_width = np.sqrt(((bottom_right[0] - bottom_left[0]) ** 2) + ((bottom_right[1] - bottom_left[1]) ** 2)) 49 | top_width = np.sqrt(((top_right[0] - top_left[0]) ** 2) + ((top_right[1] - top_left[1]) ** 2)) 50 | right_height = np.sqrt(((top_right[0] - bottom_right[0]) ** 2) + ((top_right[1] - bottom_right[1]) ** 2)) 51 | left_height = np.sqrt(((top_left[0] - bottom_left[0]) ** 2) + ((top_left[1] - bottom_left[1]) ** 2)) 52 | 53 | # Output image size 54 | max_width = max(int(bottom_width), int(top_width)) 55 | # max_height = max(int(right_height), int(left_height)) 56 | max_height = int(max_width * 1.414) # for A4 57 | 58 | # Desired points values in the output image 59 | converted_points = np.float32([[0, 0], [max_width, 0], [0, max_height], [max_width, max_height]]) 60 | 61 | # Perspective transformation 62 | matrix = cv2.getPerspectiveTransform(input_points, converted_points) 63 | img_output = cv2.warpPerspective(img_original, matrix, (max_width, max_height)) 64 | 65 | # Image shape modification for hstack 66 | gray = np.stack((gray,) * 3, axis=-1) 67 | edged = np.stack((edged,) * 3, axis=-1) 68 | 69 | img_hor = np.hstack((img_original, gray, edged, img)) 70 | cv2.imshow("Contour detection", img_hor) 71 | cv2.imshow("Warped perspective", img_output) 72 | 73 | # cv2.imwrite('output/document.jpg', img_output) 74 | 75 | cv2.waitKey(0) --------------------------------------------------------------------------------