import numpy as np
import cv2 as cv

def areaFilter(minArea, inputImage):
    componentsNumber, labeledImage, componentStats, componentCentroids = \
                                                                         cv.connectedComponentsWithStats(inputImage, connectivity=4)

    remainingComponentLabels = [i for i in range(1, componentsNumber) if componentStats[i][4] >= minArea]

    filteredImage = np.where(np.isin(labeledImage, remainingComponentLabels) == True, 255, 0).astype('uint8')

    return filteredImage

width = 1920
height = 1080

K = np.eye(3)
K[0,0] = K[1,1] = 1000
K[0:2, 2] = (width-1)/2.0, (height-1)/2.0

# Distortion coeffitients, same as above
distorsion_coefs = np.float32([-0.54,  0.28, 0., 0., 0.])


#Projectivitat proves pel half
H = np.float32([[-7.30119000e-01, -1.66590532e+00, 7.57976639e+02],
        [-8.21318034e-02, -4.92790821e+00, 1.41734853e+03],
        [-7.38042212e-05, -3.96366618e-03, 1.00000000e+00]])

#Projectivitat real pel half
H = np.float32([[-1.28474393e+00, -2.20012398e+00,  9.27906304e+02],
        [ 1.37846004e+00, -1.34043355e+01,  3.10329381e+03],
        [ 8.12016683e-04, -6.65822804e-03,  1.00000000e+00]])

#Projectivitat original pel full
H = np.float32([[-1.11820478e+00, -1.44434783e+00,  1.22173190e+03],
        [ 1.15380049e+00, -1.00482878e+01,  4.57791522e+03],
        [ 5.96037882e-04, -3.75442027e-03,  1.00000000e+00]])



cap = cv.VideoCapture('debrecen.mov')

win_name = "Stream"
cv.namedWindow(win_name, cv.WINDOW_NORMAL)

while cap.isOpened():
    ret, frame = cap.read()
    # if frame is read correctly ret is True
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
        #gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)

    undistorted_im = cv.undistort(frame, K, np.float32([-0.2,  0., 0., 0., 0.]))
    topdown = cv.warpPerspective(undistorted_im, H, dsize=(3000, 2200))

    #topdown = cv.warpPerspective(undistorted_im, H, dsize=(1500, 1100))

    gray = cv.cvtColor(topdown, cv.COLOR_BGR2GRAY)
    blur = cv.medianBlur(gray, 5)
    sharpen_kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
    sharpen = cv.filter2D(blur, -1, sharpen_kernel)


    _, thresh = cv.threshold(sharpen, 95, 255, cv.THRESH_BINARY_INV)
    """ 
    hsv = cv.cvtColor(topdown, cv.COLOR_BGR2HSV)
    lower = np.array([99, 9, 84], np.uint8)
    upper = np.array([123, 53, 150], np.uint8)

    mask = cv.inRange(hsv, lower, upper)
    """




    kernel = cv.getStructuringElement(cv.MORPH_RECT, (3,3))
    close = cv.morphologyEx(thresh, cv.MORPH_CLOSE, kernel, iterations=5)
    close = cv.medianBlur(close, 7)

    minArea = 10000#3000 
    close_filt = areaFilter(minArea, close)


    cnts = cv.findContours(close_filt, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]


    min_area = 12000
    max_area = 20000
    image_number = 0
    for c in cnts:
    #print("Aspect ratio for point", )
        x,y,w,h = cv.boundingRect(c)
        area = cv.contourArea(c)

        aspect_ratio = float(w)/h
        if aspect_ratio < 1.5 and aspect_ratio > 0.8 and area < 100000:
    #ROI = topdown[y:y+h, x:x+w]
            cv.rectangle(topdown, (x, y), (x + w, y + h), (36,255,12), 5)
            image_number += 1

    #cv.imshow(win_name, topdown)
    cv.imshow(win_name, topdown)
    cv.resizeWindow(win_name, 1080, 720)
    if cv.waitKey(1) == ord('q'):
        break



cap.release()
cv.destroyAllWindows()
