Created
March 3, 2020 16:20
-
-
Save devarshi16/1b9110db8234791b3140b9ee0e047d4f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cv2 | |
import numpy as np | |
# Finds distance between two points | |
def points_distance(pt1,pt2): | |
return (((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)**(1/2)) | |
# Orders points clockwise | |
# Credits pyimagesearch.com | |
def order_points(pts): | |
# sort the points based on their x-coordinates | |
xSorted = pts[np.argsort(pts[:, 0]), :] | |
# grab the left-most and right-most points from the sorted | |
# x-roodinate points | |
leftMost = xSorted[:2, :] | |
rightMost = xSorted[2:, :] | |
# now, sort the left-most coordinates according to their | |
# y-coordinates so we can grab the top-left and bottom-left | |
# points, respectively | |
leftMost = leftMost[np.argsort(leftMost[:, 1]), :] | |
(tl, bl) = leftMost | |
# now that we have the top-left coordinate, use it as an | |
# anchor to calculate the Euclidean distance between the | |
# top-left and right-most points; by the Pythagorean | |
# theorem, the point with the largest distance will be | |
# our bottom-right point | |
D = dist.cdist(tl[np.newaxis], rightMost, "euclidean")[0] | |
(br, tr) = rightMost[np.argsort(D)[::-1], :] | |
# return the coordinates in top-left, top-right, | |
# bottom-right, and bottom-left order | |
return np.array([tl, tr, br, bl], dtype="float32") | |
# Sort contours left to right, right to left, top to bottom, or bottom to top | |
# Credits pyimagesearch | |
def sort_contours(cnts, method="left-to-right"): | |
# initialize the reverse flag and sort index | |
reverse = False | |
i = 0 | |
# handle if we need to sort in reverse | |
if method == "right-to-left" or method == "bottom-to-top": | |
reverse = True | |
# handle if we are sorting against the y-coordinate rather than | |
# the x-coordinate of the bounding box | |
if method == "top-to-bottom" or method == "bottom-to-top": | |
i = 1 | |
# construct the list of bounding boxes and sort them from top to | |
# bottom | |
boundingBoxes = [cv2.boundingRect(c) for c in cnts] | |
(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes), | |
key=lambda b:b[1][i], reverse=reverse)) | |
# return the list of sorted contours and bounding boxes | |
return (cnts, boundingBoxes) | |
# Crop a quadrilateral and transform it into a rectangle, and return the warped image | |
# Credits pyimagesearch.com | |
def four_point_transform(image, pts): | |
# obtain a consistent order of the points and unpack them | |
# individually | |
rect = order_points(pts) | |
(tl, tr, br, bl) = rect | |
# 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 | |
widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2)) | |
widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2)) | |
maxWidth = 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 | |
heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2)) | |
heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2)) | |
maxHeight = 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 | |
dst = np.array([ | |
[0, 0], | |
[maxWidth - 1, 0], | |
[maxWidth - 1, maxHeight - 1], | |
[0, maxHeight - 1]], dtype = "float32") | |
# compute the perspective transform matrix and then apply it | |
M = cv2.getPerspectiveTransform(rect, dst) | |
warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight)) | |
# return the warped image | |
return warped | |
# Find the min area rectangle around a given contours | |
def minrectangle(cnts): | |
all_pts = [pt for ct in cnts for pt in ct] | |
all_pts = np.array(all_pts).reshape((-1,1,2)).astype(np.int32) | |
min_area_rect = cv2.minAreaRect(all_pts) | |
box = cv2.boxPoints(min_area_rect) | |
box = np.int0(box) | |
return box | |
# Contourize(opencv type contour) given set of points | |
def contourize(pts): | |
cnt = np.array(pts).reshape((-1,1,2)).astype(np.int32) | |
return cnt | |
# Min enclosing rectangle(Horizontal) | |
def min_max_pts(cnts): | |
all_pts = [pt for ct in cnts for pt in ct] | |
x = [x for x,y in all_pts] | |
y = [y for x,y in all_pts] | |
return [min(x),min(y)],[max(x),max(y)] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment