from typing import Tuple
import cv2
import numpy as np
def grayScale(img : np.ndarray) -> np.ndarray:
return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
def blur(img : np.ndarray, k: int = 3, std : int = 0) -> np.ndarray:
return cv2.GaussianBlur(img, (k,k), std)
def binary(img : np.ndarray) -> np.ndarray:
return cv2.Canny(img, 100, 255)
def retBiggestContour(img : np.ndarray) -> Tuple[np.ndarray, Tuple[int, int]]:
contours, _ = cv2.findContours(img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnt = sorted(contours, key = cv2.contourArea)[-1]
_, (w,h), angle = cv2.minAreaRect(cnt)
w,h = int(w), int(h)
if angle > 45 or angle < -45:
w,h = h,w
return cnt, (w,h)
def extract(img : np.ndarray,
cnt : np.ndarray,
w : int,
h : int
) -> np.ndarray:
cnt = cnt.reshape(cnt.shape[0], cnt.shape[-1])
s1 = sorted(cnt, key = lambda x : (x[0], x[1]))
s2 = sorted(cnt, key = lambda x : (x[1], x[0]))
corner1, corner3 = s1[0], s1[-1]
corner2, corner4 = s2[0], s2[-1]
corners = np.array([corner1, corner2, corner3, corner4])
target_corners = np.array([(0,0), (w,0), (w,h), (0,h)])
H, _ = cv2.findHomography(corners, target_corners, params = None)
transformed_image = cv2.warpPerspective(
img, H, (img.shape[1], img.shape[0]))
transformed_image = transformed_image[:h, :w]
return transformed_image
def transform(img : np.ndarray) -> np.ndarray:
T = cv2.GaussianBlur(img, (11,11),0)-10
return (img > T).astype(np.uint8) * 255
if __name__ == "__main__":
img = cv2.imread("G:/py/i/wenzi.jpg")
gray = grayScale(img)
blurred = blur(gray)
edged = binary(blurred)
cnt, (w,h) = retBiggestContour(edged)
img = extract(gray, cnt, w, h)
img = transform(img)
cv2.namedWindow('img',cv2.WINDOW_NORMAL)
cv2.imshow('img',img)
k = cv2.waitKey(0)&0xFF
if k == 27:
cv2.destroyAllWindows()
elif k == ord('q'):
cv2.destroyAllWindows()