Created
December 4, 2023 13:44
-
-
Save pogpog/d93227149a6140d3d749a29d6ca1e418 to your computer and use it in GitHub Desktop.
Rounded corner detection by averaging
This file contains hidden or 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 | |
import imutils | |
def find_rectangle_corners(image_path, flip_image=False): | |
# Read the image | |
image = cv2.imread(image_path) | |
# Convert the image to grayscale | |
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) | |
# Apply GaussianBlur to reduce noise and help with edge detection | |
blurred = cv2.GaussianBlur(gray, (5, 5), 0) | |
# Apply Canny edge detector | |
edges = cv2.Canny(blurred, 50, 150) | |
# Find contours in the edged image | |
contours1, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) | |
contours2 = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) | |
ext = get_extreme_contour_points(contours2) | |
# Filter contours based on their area | |
valid_contours = [cnt for cnt in contours1 if cv2.contourArea(cnt) > 100] | |
# Find the largest contour (assuming it is the rectangle) | |
largest_contour = max(valid_contours, key=cv2.contourArea) | |
# Approximate the contour to a polygon | |
epsilon = 0.02 * cv2.arcLength(largest_contour, True) | |
approx_corners = cv2.approxPolyDP(largest_contour, epsilon, True) | |
mean_corners = mean_3d_arrays(approx_corners, ext) | |
# Draw the contour and the approximated polygon on the original image | |
# cv2.drawContours(image, [approx_corners], 0, (0, 255, 0), 2) | |
cv2.drawContours(image, [mean_corners], 0, (0, 255, 0), 2) | |
# Display the image | |
cv2.imshow("Image with Rectangle", image) | |
cv2.waitKey(3000) | |
cv2.destroyAllWindows() | |
cv2.imwrite(f"corners{'_flipped' if flip_image else ''}.jpg", image) | |
# Return the approximated corners | |
return mean_corners | |
def mean_3d_arrays(a1, a2): | |
return np.mean(np.array([a1, a2]), axis=0).astype(np.int32) | |
def get_extreme_contour_points(contours): | |
cnts = imutils.grab_contours(contours) | |
c = max(cnts, key=cv2.contourArea) | |
# compute the extreme points of the contour | |
extLeft = [c[c[:, :, 0].argmin()][0]] | |
extRight = [c[c[:, :, 0].argmax()][0]] | |
extTop = [c[c[:, :, 1].argmin()][0]] | |
extBot = [c[c[:, :, 1].argmax()][0]] | |
print(extLeft) | |
return np.array([extTop, extLeft, extBot, extRight]) | |
def rotate_image(image, angle): | |
image_center = tuple(np.array(image.shape[1::-1]) / 2) | |
rot_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0) | |
result = cv2.warpAffine(image, rot_mat, image.shape[1::-1], flags=cv2.INTER_LINEAR) | |
return result | |
if __name__ == "__main__": | |
input_image_path = "okf-driving-licence-skewed.jpg" | |
rectangle_corners = find_rectangle_corners(input_image_path) | |
rectangle_corners2 = find_rectangle_corners(input_image_path, True) | |
print("Approximated Rectangle Corners:", rectangle_corners) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment