import numpy as np

'''  
    Course first-pass filter to elimate clearly mis-sized streaks as well as those that are too close to the edge.

    Filters found streaks, defaults choose longer, narrower streaks above a certain size threshold;
    streaks are also filtered to remove those near edges

    Input: streaks, pandas dataframe of streaks generated by measure (lists contour number, area, perimeter, centroid, bbox properties)

    Output: final_filtered, pandas dataframe of filtered streaks

    Parameters
    ----------

    min_height: minimum bbox height of contours to use for filtering, default is 7

    min_aspect: minimum aspect ratio (bbox width / bbox height) of contours to use for filtering, default is 2

    remove_edges: boolean, if True (default) removes contours whose centroid is within edge_filter of the image border

    edge_filter: size in pixels of excluded region for edge filtering, default is 100

    image_size: tuple (width, height), size of image to use for edge filtering
                '''


def filter(streaks, min_height = 7, min_aspect = 2, remove_edges = True, edge_filter = 100, image_size = (2048, 2048)):
    height_filter = streaks[streaks.bbox_height > min_height]
    aspect_filter = height_filter[(height_filter.bbox_width / height_filter.bbox_height) > 2]

    if remove_edges:
        high_x = aspect_filter[aspect_filter.x > edge_filter]
        center_x = high_x[high_x.x < (image_size[0] - edge_filter)]

        high_y = center_x[center_x.y > edge_filter]
        center_y = high_y[high_y.y < (image_size[1] - edge_filter)]

        edge_filtered = center_y

    else:
        edge_filtered = aspect_filter

    final_filtered = edge_filtered

    return final_filtered



'''
Basic contour filtering, removes only contours which are open (i.e intersect with the edge) and
contours which are too small, below a minimum diagonal size

This should be used if your contours are not rectangles, and thus the bounding box filtering will not work 
well.  Note that this function filters contours, not the dataframe of measurements

Input: Input: contours, list of contours, each item in the list contains x & y positions of each contour

Output: list of filtered contours, each item in the list contains x & y positions of each contour

Parameters
----------
min_diag_size: float, diagonal size threshold to use for filtering out small contours, 
'''

def filter_diag_size(contours, min_diag_size = 80):
    filtered = []
    for i, contour in enumerate(contours):

        x = contour[:,1]; y = contour[:,0];  #seperate x & y points

        #check that contour is closed, e.g. it does not interect the image edge, if closed then measure
        if contour[0][0] != contour[-1][0] or contour[0][1] != contour[-1][1]: 
            pass
        else:
            width = max(x)-min(x)
            height = max(y)- min(y) 
            diag_size = np.sqrt(width**2 + height**2)
            if diag_size > min_diag_size:
                filtered.append(contour)

    return filtered
