def TracksPx_to_TracksMetric(filteredFeatures, minimumTrackedFeatures, interior_orient, eor_mat, unit_gcp,
                             frame_rate_cam, TrackEveryNthFrame, waterlevel_pt, directoryOutput, dir_imgs, 
                             img_list, veloStdThresh, lspiv):
    #scale tracks in image space to tracks in object space to get flow velocity in m/s
    waterlevel = waterlevel_pt

    image = cv2.imread(dir_imgs + img_list[0], 0)

    if lspiv:
        xy_start_tr = np.asarray(filteredFeatures[['x','y']])
        xy_tr = np.asarray(filteredFeatures[['x_tr', 'y_tr']])
        id_features = np.asarray(filteredFeatures['id'])        
        
    else:
        #get first and last position in image space of each tracked feature
        filteredFeatures_1st = filteredFeatures.groupby('id', as_index=False).head(1)   
        filteredFeatures_last = filteredFeatures.groupby('id', as_index=False).tail(1)  
        filteredFeatures_count = np.asarray(filteredFeatures.groupby('id', as_index=False).count())[:,2]  

        xy_start_tr = np.asarray(filteredFeatures_1st[['x', 'y']])
        xy_tr = np.asarray(filteredFeatures_last[['x_tr', 'y_tr']])

    #intersect first and last position with waterlevel
    XY_start_tr = refF.LinePlaneIntersect(xy_start_tr, waterlevel, interior_orient, eor_mat, unit_gcp) / unit_gcp
    XY_tr = refF.LinePlaneIntersect(xy_tr, waterlevel, interior_orient, eor_mat, unit_gcp) / unit_gcp

    #get corresponding distance in object space
    dist_metric = np.sqrt(np.square(XY_start_tr[:,0] - XY_tr[:,0]) + (np.square(XY_start_tr[:,1] - XY_tr[:,1]))) 

    #get corresponding temporal observation span
    if lspiv:
        trackingDuration = np.ones((id_features.shape[0],1), dtype=np.float) * TrackEveryNthFrame / np.float(frame_rate_cam)
    else:
        frame_rate_cam = np.ones((filteredFeatures_count.shape[0],1), dtype=np.float) * np.float(frame_rate_cam)
        nbrTrackedFrames = TrackEveryNthFrame * (filteredFeatures_count+1)
        trackingDuration = nbrTrackedFrames.reshape(frame_rate_cam.shape[0],1) / frame_rate_cam 

    #get velocity
    velo = dist_metric.reshape(trackingDuration.shape[0],1) / trackingDuration
    
    if lspiv:
        filteredFeaturesPIV = pd.DataFrame(id_features, columns=['id'])        
        filteredFeaturesPIV = filterFeatureOrganise(filteredFeaturesPIV, XY_start_tr, XY_tr, xy_tr, dist_metric, velo, 
                                                    False, None, filteredFeatures[['x','y']])
        drawF.draw_tracks(filteredFeaturesPIV.groupby('id', as_index=False).mean(), image, directoryOutput, 'TracksReferenced_rawPIV.jpg', 'velo', True)
        filteredFeaturesPIV.to_csv(directoryOutput + 'TracksReferenced_rawPIV.txt', sep='\t', index=False)
               
        #filter outliers considering mean and std dev for each grid cell
        filteredFeaturesPIV.loc[:,'veloMean'] = pd.Series(np.empty((len(filteredFeaturesPIV))))        
        filteredFeaturesPIV.loc[:,'veloStd'] = pd.Series(np.empty((len(filteredFeaturesPIV))))
        filteredFeatureMean = filteredFeaturesPIV.groupby('id', as_index=False).velo.mean()
        filteredFeaturesStd = filteredFeaturesPIV.groupby('id', as_index=False).velo.std()
        filteredFeaturesId = filteredFeaturesPIV.groupby('id', as_index=False).id.mean()
        
        featureCount = 0
        while featureCount < len(filteredFeaturesId)-1:
            filteredFeaturesPIV.loc[filteredFeaturesPIV.id == filteredFeaturesId.loc[featureCount], 'veloMean'] = filteredFeatureMean.loc[featureCount,'velo']
            filteredFeaturesPIV.loc[filteredFeaturesPIV.id == filteredFeaturesId.loc[featureCount], 'veloStd'] = filteredFeaturesStd.loc[featureCount,'velo']  
            featureCount = featureCount + 1
 
        filteredFeaturesPIV.loc[:,'threshPos'] = filteredFeaturesPIV.veloMean + 5 * filteredFeaturesPIV.veloStd
        filteredFeaturesPIV.loc[:,'threshNeg'] = filteredFeaturesPIV.veloMean - 5 * filteredFeaturesPIV.veloStd
        filteredFeaturesPIV = filteredFeaturesPIV[filteredFeaturesPIV.velo < filteredFeaturesPIV.threshPos]
        filteredFeaturesPIV = filteredFeaturesPIV[filteredFeaturesPIV.velo > filteredFeaturesPIV.threshNeg]     
        
        #also filter based on direction
        #...
        
        filteredFeaturesPIV_grouped = filteredFeaturesPIV.groupby('id', as_index=False).mean()
        filteredFeaturesCount = filteredFeaturesPIV.groupby('id', as_index=False).count()
        filteredFeaturesPIV_grouped.loc[:,'count'] = filteredFeaturesCount.loc[:,'velo']
        filteredFeaturesPIV_grouped = filteredFeaturesPIV_grouped.drop(columns=['veloMean','veloStd','threshPos','threshNeg'])
        
        filteredFeatures = filteredFeaturesPIV_grouped
        
    else:
        filteredFeatures_1st = filterFeatureOrganise(filteredFeatures_1st, XY_start_tr, XY_tr, xy_tr, dist_metric, velo, 
                                                     True, filteredFeatures_count)
        filteredFeatures = filteredFeatures_1st

    #write referenced tracking results to file
    print('nbr of tracked features: ' + str(filteredFeatures.shape[0]) + '\n')
    filteredFeatures.to_csv(directoryOutput + 'TracksReferenced_raw.txt', sep='\t', index=False)
    drawF.draw_tracks(filteredFeatures, image, directoryOutput, 'TracksReferenced_raw.jpg', 'velo', True)

    #filter for outlier velocities
    MeanVeloAll = filteredFeatures.velo.mean()
    StdVeloAll = filteredFeatures.velo.std()
    threshVelo_Pos = MeanVeloAll + veloStdThresh * StdVeloAll
    threshVelo_Neg = MeanVeloAll - veloStdThresh * StdVeloAll

    filteredFeatures = filteredFeatures[filteredFeatures.velo < threshVelo_Pos]
    filteredFeatures = filteredFeatures[filteredFeatures.velo > threshVelo_Neg]

    #write filtered tracking results to file and draw final tracking results to image  
    print('nbr of final tracked features: ' + str(filteredFeatures.shape[0]) + '\n')
    filteredFeatures.to_csv(directoryOutput + 'TracksFiltered.txt', sep='\t', index=False)
    drawF.draw_tracks(filteredFeatures, image, directoryOutput, 'TracksFiltered.jpg', 'velo', True)
Beispiel #2
0
def TracksPx_to_TracksMetric(filteredFeatures, interior_orient, eor_mat,
                             unit_gcp, frame_rate_cam, TrackEveryNthFrame,
                             waterlevel_pt, directoryOutput, img_name,
                             veloStdThresh, lspiv, cellsizeFilter, searchMask):
    #scale tracks in image space to tracks in object space to get flow velocity in m/s
    waterlevel = waterlevel_pt

    image = cv2.imread(img_name, 0)

    if lspiv:
        xy_start_tr = np.asarray(filteredFeatures[['x', 'y']])
        xy_tr = np.asarray(filteredFeatures[['x_tr', 'y_tr']])
        id_features = np.asarray(filteredFeatures['id'])

    else:
        #get first and last position in image space of each tracked feature
        filteredFeatures_1st = filteredFeatures.groupby('id',
                                                        as_index=False).head(1)
        filteredFeatures_last = filteredFeatures.groupby(
            'id', as_index=False).tail(1)
        filteredFeatures_count = np.asarray(
            filteredFeatures.groupby('id', as_index=False).count())[:, 2]

        xy_start_tr = np.asarray(filteredFeatures_1st[['x', 'y']])
        xy_tr = np.asarray(filteredFeatures_last[['x_tr', 'y_tr']])

    #intersect first and last position with waterlevel
    XY_start_tr = refF.LinePlaneIntersect(
        xy_start_tr, waterlevel, interior_orient, eor_mat, unit_gcp) / unit_gcp
    XY_tr = refF.LinePlaneIntersect(xy_tr, waterlevel, interior_orient,
                                    eor_mat, unit_gcp) / unit_gcp

    #get corresponding distance in object space
    dist_metric = np.sqrt(
        np.square(XY_start_tr[:, 0] - XY_tr[:, 0]) +
        (np.square(XY_start_tr[:, 1] - XY_tr[:, 1])))

    #get corresponding temporal observation span
    if lspiv:
        trackingDuration = np.ones(
            (id_features.shape[0], 1),
            dtype=np.float) * TrackEveryNthFrame / np.float(frame_rate_cam)
    else:
        frame_rate_cam = np.ones((filteredFeatures_count.shape[0], 1),
                                 dtype=np.float) * np.float(frame_rate_cam)
        nbrTrackedFrames = TrackEveryNthFrame * (filteredFeatures_count + 1)
        trackingDuration = nbrTrackedFrames.reshape(frame_rate_cam.shape[0],
                                                    1) / frame_rate_cam

    #get velocity
    velo = dist_metric.reshape(trackingDuration.shape[0], 1) / trackingDuration

    if lspiv:
        filteredFeaturesPIV = pd.DataFrame(id_features, columns=['id'])
        filteredFeaturesPIV = filterFeatureOrganise(
            filteredFeaturesPIV, XY_start_tr, XY_tr, xy_tr, dist_metric, velo,
            False, None, filteredFeatures[['x', 'y']])
        drawF.draw_tracks(
            filteredFeaturesPIV.groupby('id', as_index=False).mean(), image,
            directoryOutput, 'TracksReferenced_raw_PIV.jpg', 'velo', True)
        filteredFeaturesPIVRawOut = filteredFeaturesPIV[[
            'X', 'Y', 'Z', 'velo', 'dist_metric'
        ]]
        filteredFeaturesPIVRawOut.columns = ['X', 'Y', 'Z', 'velo', 'dist']
        filteredFeaturesPIVRawOut.rename(columns={"dist_metric": "dist"})
        filteredFeaturesPIVRawOut.to_csv(directoryOutput +
                                         'TracksReferenced_raw_PIV.txt',
                                         sep='\t',
                                         index=False)
        del filteredFeaturesPIVRawOut

        #write referenced tracking results to file
        print('nbr of tracked features: ' + str(filteredFeatures.shape[0]) +
              '\n')

        #filter outliers considering mean and std dev for each grid cell
        filteredFeaturesPIV.loc[:, 'veloMean'] = pd.Series(
            np.empty((len(filteredFeaturesPIV))))
        filteredFeaturesPIV.loc[:, 'veloStd'] = pd.Series(
            np.empty((len(filteredFeaturesPIV))))
        filteredFeatureMean = filteredFeaturesPIV.groupby(
            'id', as_index=False).velo.mean()
        filteredFeaturesStd = filteredFeaturesPIV.groupby(
            'id', as_index=False).velo.std()
        filteredFeaturesPIV["id_copy"] = filteredFeaturesPIV.id
        filteredFeaturesId = filteredFeaturesPIV.groupby(
            'id_copy', as_index=False).id.mean()
        filteredFeaturesId = filteredFeaturesId.id

        featureCount = 0
        while featureCount < len(filteredFeaturesId) - 1:
            filteredFeaturesPIV.loc[
                filteredFeaturesPIV.id == filteredFeaturesId.loc[featureCount],
                'veloMean'] = filteredFeatureMean.loc[featureCount, 'velo']
            filteredFeaturesPIV.loc[
                filteredFeaturesPIV.id == filteredFeaturesId.loc[featureCount],
                'veloStd'] = filteredFeaturesStd.loc[featureCount, 'velo']
            featureCount = featureCount + 1

        filteredFeaturesPIV.loc[:,
                                'threshPos'] = filteredFeaturesPIV.veloMean + veloStdThresh * filteredFeaturesPIV.veloStd
        filteredFeaturesPIV.loc[:,
                                'threshNeg'] = filteredFeaturesPIV.veloMean - veloStdThresh * filteredFeaturesPIV.veloStd
        filteredFeaturesPIV = filteredFeaturesPIV[
            filteredFeaturesPIV.velo < filteredFeaturesPIV.threshPos]
        filteredFeaturesPIV = filteredFeaturesPIV[
            filteredFeaturesPIV.velo > filteredFeaturesPIV.threshNeg]

        filteredFeaturesPIV_grouped = filteredFeaturesPIV.groupby(
            'id', as_index=False).mean()
        filteredFeaturesCount = filteredFeaturesPIV.groupby(
            'id', as_index=False).count()
        filteredFeaturesPIV_grouped.loc[:,
                                        'count'] = filteredFeaturesCount.loc[:,
                                                                             'velo']
        filteredFeaturesPIV_grouped = filteredFeaturesPIV_grouped.drop(
            columns=['veloMean', 'veloStd', 'threshPos', 'threshNeg'])

        filteredFeatures = filteredFeaturesPIV_grouped

        drawF.draw_tracks(filteredFeatures, image, directoryOutput,
                          'TracksFiltered_PIV.jpg', 'velo', True)
        filteredFeaturesPIVOut = filteredFeatures[[
            'X', 'Y', 'Z', 'velo', 'dist_metric'
        ]]
        filteredFeaturesPIVOut.columns = ['X', 'Y', 'Z', 'velo', 'dist']
        filteredFeaturesPIVOut.rename(columns={"dist_metric": "dist"})
        filteredFeaturesPIVOut.to_csv(directoryOutput +
                                      'TracksFiltered_PIV.txt',
                                      sep='\t',
                                      index=False)
        del filteredFeaturesPIVOut

    else:
        filteredFeatures_1st = filterFeatureOrganise(filteredFeatures_1st,
                                                     XY_start_tr, XY_tr, xy_tr,
                                                     dist_metric, velo, True,
                                                     filteredFeatures_count)
        filteredFeatures = filteredFeatures_1st.copy()
        filteredFeatures = filteredFeatures.reset_index(drop=True)
        filteredFeaturesRawPTVOut = filteredFeatures[[
            'X', 'Y', 'Z', 'velo', 'dist_metric', 'count'
        ]]
        filteredFeaturesRawPTVOut.columns = [
            'X', 'Y', 'Z', 'velo', 'dist', 'count'
        ]
        filteredFeaturesRawPTVOut.to_csv(directoryOutput +
                                         'TracksReferenced_raw_PTV.txt',
                                         sep='\t',
                                         index=False)
        del filteredFeaturesRawPTVOut
        drawF.draw_tracks(filteredFeatures, image, directoryOutput,
                          'TracksReferenced_raw_PTV.jpg', 'velo', True)

        #write referenced tracking results to file
        print('nbr of tracked features: ' + str(filteredFeatures.shape[0]) +
              '\n')
        ''''''
        if not cellsizeFilter == 0:
            #filter outliers area-based with regular raster
            xy_cell = filterF.DefineRFeatures_forRasterbasedFilter(
                image, searchMask, cellsizeFilter * 4)
            XYZ_cell = refF.LinePlaneIntersect(xy_cell, waterlevel,
                                               interior_orient, eor_mat,
                                               unit_gcp) / unit_gcp
            XYZxy = pd.DataFrame(np.hstack((XYZ_cell, xy_cell)))
            XYZxy.columns = ['X', 'Y', 'Z', 'x', 'y']
            XYZxy['id'] = range(1, len(XYZxy) + 1)

            filteredFeaturesRaster = filterF.NN_filter(filteredFeatures, XYZxy,
                                                       cellsizeFilter * 4,
                                                       False)
            filteredFeaturesRaster = filteredFeaturesRaster.reset_index(
                drop=True)
            del XYZxy

            drawF.draw_tracks(filteredFeaturesRaster, image, directoryOutput,
                              'filteredTracks_raster_PTV.jpg', 'velo', True)
            filteredFeaturesRaster = filteredFeaturesRaster[[
                'X', 'Y', 'Z', 'velo', 'dist', 'count'
            ]]
            filteredFeaturesRaster.to_csv(directoryOutput +
                                          'tracksFiltered_rasterBased_PTV.txt',
                                          sep='\t',
                                          index=False)
            del filteredFeaturesRaster

        #filter outliers area-based with features in proximity
        filteredFeaturesLocally = filterF.NN_filter(filteredFeatures,
                                                    filteredFeatures,
                                                    cellsizeFilter, False)
        drawF.draw_tracks(filteredFeaturesLocally, image, directoryOutput,
                          'filteredTracks_locally_PTV.jpg', 'velo', True)
        filteredFeaturesLocally = filteredFeaturesLocally[[
            'X', 'Y', 'Z', 'velo', 'dist', 'count'
        ]]
        filteredFeaturesLocally.to_csv(directoryOutput +
                                       'tracksFiltered_locally_PTV.txt',
                                       sep='\t',
                                       index=False)

        # else:
    #filter for outlier velocities using velocity threshold
    MeanVeloAll = filteredFeatures.velo.mean()
    StdVeloAll = filteredFeatures.velo.std()
    threshVelo_Pos = MeanVeloAll + veloStdThresh * StdVeloAll
    threshVelo_Neg = MeanVeloAll - veloStdThresh * StdVeloAll

    filteredFeatures = filteredFeatures[filteredFeatures.velo < threshVelo_Pos]
    filteredFeatures = filteredFeatures[filteredFeatures.velo > threshVelo_Neg]

    drawF.draw_tracks(filteredFeatures, image, directoryOutput,
                      'TracksFiltered_PTV_VeloThresh.jpg', 'velo', True)
    filteredFeatures = filteredFeatures[[
        'X', 'Y', 'Z', 'velo', 'dist_metric', 'count'
    ]]
    filteredFeatures.columns = ['X', 'Y', 'Z', 'velo', 'dist', 'count']
    filteredFeatures.rename(columns={"dist_metric": "dist"})
    filteredFeatures.to_csv(directoryOutput +
                            'TracksFiltered_PTV_VeloThresh.txt',
                            sep='\t',
                            index=False)

    #write filtered tracking results to file and draw final tracking results to image
    print('nbr of final tracked features: ' + str(filteredFeatures.shape[0]) +
          '\n')
def FilterTracks(trackedFeaturesOutput_undist, dir_imgs, img_list, directoryOutput,
                 minDistance_px, maxDistance_px, minimumTrackedFeatures, 
                 threshAngleSteadiness, threshAngleRange,
                 binNbrMainflowdirection, MainFlowAngleBuffer, lspiv):
    '''filter tracks considering several filter parameters'''
    #transform dataframe to numpy array and get feature ids
    trackedFeaturesOutput_undist = np.asarray(trackedFeaturesOutput_undist)
    trackedFeaturesOutput_undist = np.asarray(trackedFeaturesOutput_undist[:,1:4], dtype=np.float)
    featureIDs_fromTracking = np.unique(trackedFeaturesOutput_undist[:,0])
    Features_px = np.empty((1,6))
    
    for feature in featureIDs_fromTracking:
        processFeature = trackedFeaturesOutput_undist[trackedFeaturesOutput_undist[:,0] == feature, 1:3]
        
        #get distance between tracked features across subsequent frames in image space
        if lspiv:
            xy_start_tr = np.ones((processFeature.shape[0]-1,processFeature.shape[1])) * processFeature[0,:]
        else:
            xy_start_tr = processFeature[:-1,:]
        xy_tr = processFeature[1:,:]        
        dist = np.sqrt(np.square(xy_start_tr[:,0] - xy_tr[:,0]) + (np.square(xy_start_tr[:,1] - xy_tr[:,1])))
        
        feature_px = np.hstack((np.ones((xy_start_tr.shape[0],1)) * feature, xy_start_tr))
        feature_px = np.hstack((feature_px, xy_tr))
        feature_px = np.hstack((feature_px, dist.reshape(dist.shape[0],1)))
        
        Features_px = np.vstack((Features_px, feature_px))
    
    Features_px = Features_px[1:,:]

    Features_px = pd.DataFrame({'id' : Features_px[:,0], 'x' : Features_px[:,1], 'y' : Features_px[:,2],
                               'x_tr' : Features_px[:,3], 'y_tr' : Features_px[:,4], 'dist' : Features_px[:,5]})
    
    #draw all tracks from frame to frame into image
    image = cv2.imread(dir_imgs + img_list[0], 0)
    drawF.draw_tracks(Features_px, image, directoryOutput, 'TracksRaw_px.jpg', 'dist', False)   
    print('nbr features prior filtering: ' + str(np.unique(Features_px.id).shape[0]) + '\n')
    nbr_features_raw = np.unique(Features_px.id).shape[0]
       
    #minimum tracking distance
    if lspiv:
        filteredFeatures = Features_px[Features_px.dist > minDistance_px]
    else:
        filteredFeatures_id = Features_px[Features_px.dist < minDistance_px]
        filteredFeatures_id = filteredFeatures_id.id.unique()
        filteredFeatures = Features_px[~Features_px.id.isin(filteredFeatures_id)]
    filteredFeatures = filteredFeatures.reset_index(drop=True)
    drawF.draw_tracks(filteredFeatures, image, directoryOutput, 'TracksFilteredMinDist.png', 'dist', True)
    print('nbr features after minimum distance filter: ' + str(np.unique(filteredFeatures.id).shape[0]))
    nbr_features_mindist = np.unique(filteredFeatures.id).shape[0]
        
    #maximum tracking distance
    if lspiv:
        filteredFeatures = filteredFeatures[filteredFeatures.dist < maxDistance_px]
    else:    
        filteredFeatures_id = Features_px[Features_px.dist > maxDistance_px]
        filteredFeatures_id = filteredFeatures_id.id.unique()
        filteredFeatures = filteredFeatures[~filteredFeatures.id.isin(filteredFeatures_id)]
    filteredFeatures = filteredFeatures.reset_index(drop=True)
    drawF.draw_tracks(filteredFeatures, image, directoryOutput, 'TracksFilteredMaxDist.png', 'dist', True)
    print('nbr features after maximum distance filter: ' + str(np.unique(filteredFeatures.id).shape[0]))
    nbr_features_maxdist = np.unique(filteredFeatures.id).shape[0]
              
    #minimum tracking counts
    try:
        filteredFeatures = filterF.TrackFilterMinCount(filteredFeatures, minimumTrackedFeatures)
        drawF.draw_tracks(filteredFeatures, image, directoryOutput, 'TracksFilteredMinCount.png', 'dist', True)
        print('nbr features after minimum count filter: ' + str(np.unique(filteredFeatures.id).shape[0]))
    except:
        print('error during filtering minimum count')
    nbr_features_mincount = np.unique(filteredFeatures.id).shape[0]
             
    #get track vector for each tracked feature
    y_track = filteredFeatures.y_tr.values - filteredFeatures.y.values
    x_track = filteredFeatures.x_tr.values - filteredFeatures.x.values
    track = np.hstack((x_track.reshape(filteredFeatures.shape[0],1), y_track.reshape(filteredFeatures.shape[0],1)))
    #get angle for each track
    angle = filterF.angleBetweenVecAndXaxis(track)    
    filteredFeatures['angle'] = pd.Series(angle, index=filteredFeatures.index)
        
    #directional steadiness
    filteredFeatures, steady_angle = filterF.TrackFilterSteadiness(filteredFeatures, threshAngleSteadiness)
    drawF.draw_tracks(filteredFeatures, image, directoryOutput, 'TracksFilteredSteady.png', 'dist', True)
    print('nbr features after steadiness filter: ' + str(np.unique(filteredFeatures.id).shape[0]))
    nbr_features_steady = np.unique(filteredFeatures.id).shape[0]
        
    #range of directions per track
    filteredFeatures, range_angle = filterF.TrackFilterAngleRange(filteredFeatures, threshAngleRange)
    drawF.draw_tracks(filteredFeatures, image, directoryOutput, 'TracksFilteredRangeAngle.png', 'dist', True)
    print('nbr features after range angle filter: ' + str(np.unique(filteredFeatures.id).shape[0]))
    nbr_features_rangeangle = np.unique(filteredFeatures.id).shape[0]
             
    #filter tracks outside main flow direction
    filteredFeatures, flowdir_angle = filterF.TrackFilterMainflowdirection(filteredFeatures, binNbrMainflowdirection, MainFlowAngleBuffer)
    drawF.draw_tracks(filteredFeatures, image, directoryOutput, 'TracksFilteredFlowDir.png', 'dist', True)
    print('nbr features after flow directions filter: ' + str(np.unique(filteredFeatures.id).shape[0]))
    nbr_features_mainflowdir = np.unique(filteredFeatures.id).shape[0]        

    #save filter results
    filteredFeatures.to_csv(directoryOutput + 'TracksFiltered_px.txt', sep='\t', index=False)
    
    return filteredFeatures, [nbr_features_raw, nbr_features_mindist, nbr_features_maxdist, nbr_features_mincount,
                              steady_angle, nbr_features_steady, range_angle, nbr_features_rangeangle, flowdir_angle, nbr_features_mainflowdir]
    feature_px = np.hstack((feature_px, xy_tr))
    feature_px = np.hstack((feature_px, dist.reshape(dist.shape[0], 1)))

    Features_px = np.vstack((Features_px, feature_px))
Features_px = Features_px[1:, :]

Features_px = pd.DataFrame({
    'id': Features_px[:, 0],
    'x': Features_px[:, 1],
    'y': Features_px[:, 2],
    'x_tr': Features_px[:, 3],
    'y_tr': Features_px[:, 4],
    'dist': Features_px[:, 5]
})
image = cv2.imread(dir_imgs + img_list[0], 0)
drawF.draw_tracks(Features_px, image, directoryOutput, 'TracksRaw_px.png',
                  'dist', False)
print('nbr features prior filtering: ' +
      str(np.unique(Features_px.id).shape[0]))
nbr_features_raw = np.unique(Features_px.id).shape[0]

#minimum tracking distance
# filteredFeatures = Features_px[Features_px.dist > minDistance_px]
filteredFeatures_id = Features_px[Features_px.dist <= minDistance_px]
filteredFeatures_id = filteredFeatures_id.id.unique()
filteredFeatures = Features_px[~Features_px.id.isin(filteredFeatures_id)]
filteredFeatures = filteredFeatures.reset_index(drop=True)
try:
    drawF.draw_tracks(filteredFeatures, image, directoryOutput,
                      'TracksFilteredMinDist.png', 'dist', True)
except:
    print('drawing minimum distance filtered tracks failed')