import cv2
import numpy as np

cap = cv2.VideoCapture(0)

while True:
    img = cap.read()[1]
    orig = img.copy()

    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (5, 5), 0)

    _, thres = cv2.threshold(blur, 200, 255, cv2.THRESH_BINARY)

    cts, _ = cv2.findContours(thres, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    contour = max(cts, key=cv2.contourArea)

    epsilon = 0.02 * cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, epsilon, True)

    if len(approx) == 4:
        pts = approx.reshape(4, 2)

        rect = np.zeros((4, 2), dtype="float32")
        s = pts.sum(axis=1)
        rect[0] = pts[np.argmin(s)]
        rect[2] = pts[np.argmax(s)]

        diff = np.diff(pts, axis=1)
        rect[1] = pts[np.argmin(diff)]
        rect[3] = pts[np.argmax(diff)]

        (tl, tr, br, bl) = rect

        widthA = np.linalg.norm(br - bl)
        widthB = np.linalg.norm(tr - tl)
        maxWidth = max(int(widthA), int(widthB))

        heightA = np.linalg.norm(tr - br)
        heightB = np.linalg.norm(tl - bl)
        maxHeight = max(int(heightA), int(heightB))

        dst = np.array(
            [
                [0, 0],
                [maxWidth - 1, 0],
                [maxWidth - 1, maxHeight - 1],
                [0, maxHeight - 1],
            ],
            dtype="float32",
        )

        M = cv2.getPerspectiveTransform(rect, dst)
        warped = cv2.warpPerspective(orig, M, (maxWidth, maxHeight))

        cv2.putText(
            warped,
            "llpoDaM rapa>|<",
            (0, 50),
            cv2.FONT_HERSHEY_SIMPLEX,
            1,
            (0, 0, 0),
            2,
        )

        M_inv = cv2.getPerspectiveTransform(dst, rect)
        warped_back = cv2.warpPerspective(warped, M_inv, (orig.shape[1], orig.shape[0]))

        mask = np.zeros_like(gray)
        cv2.fillConvexPoly(mask, approx, 255)

        masked = cv2.bitwise_and(orig, orig, mask=cv2.bitwise_not(mask))
        final = cv2.add(masked, warped_back)

        cv2.imshow("img", final)
        cv2.waitKey(1)
    else:
        cv2.imshow("img", orig)
        cv2.waitKey(1)
