Beispiel #1
0
def process_sequence_properties(import_path,
                                cutoff_distance=600.0,
                                cutoff_time=60.0,
                                interpolate_directions=False,
                                flag_duplicates=False,
                                duplicate_distance=0.1,
                                duplicate_angle=5,
                                offset_angle=0.0,
                                verbose=False,
                                rerun=False,
                                skip_subfolders=False,
                                video_import_path=None):

    # sanity check if video file is passed
    if video_import_path and not os.path.isdir(video_import_path):
        print("Error, video path " + video_import_path +
              " does not exist, exiting...")
        sys.exit(1)

    # in case of video processing, adjust the import path
    if video_import_path:
        # set sampling path
        video_sampling_path = "mapillary_sampled_video_frames"
        import_path = os.path.join(
            os.path.abspath(import_path),
            video_sampling_path) if import_path else os.path.join(
                os.path.abspath(video_import_path), video_sampling_path)

    # basic check for all
    if not import_path or not os.path.isdir(import_path):
        print("Error, import directory " + import_path +
              " does not exist, exiting...")
        sys.exit(1)

    sequences = []
    if skip_subfolders:
        process_file_list = processing.get_process_file_list(
            import_path, "sequence_process", rerun, verbose, True, import_path)
        if not len(process_file_list):
            if verbose:
                print("No images to run sequence process in root " +
                      import_path)
                print(
                    "If the images have already been processed and not yet uploaded, they can be processed again, by passing the argument --rerun"
                )
        else:
            # LOAD TIME AND GPS POINTS ------------------------------------
            file_list, capture_times, lats, lons, directions = processing.load_geotag_points(
                process_file_list, verbose)
            # ---------------------------------------

            # SPLIT SEQUENCES --------------------------------------
            if len(capture_times) and len(lats) and len(lons):
                sequences.extend(
                    processing.split_sequences(capture_times, lats, lons,
                                               file_list, directions,
                                               cutoff_time, cutoff_distance,
                                               verbose))
        # ---------------------------------------
    else:
        # sequence limited to the root of the files
        for root, dirs, files in os.walk(import_path):
            if os.path.join(".mapillary", "logs") in root:
                continue
            if len(files):
                process_file_list = processing.get_process_file_list(
                    import_path, "sequence_process", rerun, verbose, True,
                    root)
                if not len(process_file_list):
                    if verbose:
                        print("No images to run sequence process in root " +
                              root)
                        print(
                            "If the images have already been processed and not yet uploaded, they can be processed again, by passing the argument --rerun"
                        )
                    continue
                # LOAD TIME AND GPS POINTS ------------------------------------
                file_list, capture_times, lats, lons, directions = processing.load_geotag_points(
                    process_file_list, verbose)
                # ---------------------------------------
                # SPLIT SEQUENCES --------------------------------------
                if len(capture_times) and len(lats) and len(lons):
                    sequences.extend(
                        processing.split_sequences(capture_times, lats, lons,
                                                   file_list, directions,
                                                   cutoff_time,
                                                   cutoff_distance, verbose))
                # ---------------------------------------
    if flag_duplicates:
        if verbose:
            print(
                "Flagging images as duplicates if consecutive distance difference less than {} and angle difference less than {}"
                .format(duplicate_distance, duplicate_angle))

    # process for each sequence
    for sequence in sequences:
        file_list = sequence["file_list"]
        directions = sequence["directions"]
        latlons = sequence["latlons"]
        capture_times = sequence["capture_times"]

        # COMPUTE DIRECTIONS --------------------------------------
        interpolated_directions = [
            compute_bearing(ll1[0], ll1[1], ll2[0], ll2[1])
            for ll1, ll2 in zip(latlons[:-1], latlons[1:])
        ]
        if len(interpolated_directions):
            interpolated_directions.append(interpolated_directions[-1])
        else:
            interpolated_directions.append(directions[-1])
        # use interpolated directions if direction not available or if flag for
        # interpolate_directions
        for i, d in enumerate(directions):
            directions[i] = d if (
                d is not None and not interpolate_directions
            ) else (interpolated_directions[i] + offset_angle) % 360.0
        # ---------------------------------------

        # INTERPOLATE TIMESTAMPS, in case of identical timestamps
        capture_times = processing.interpolate_timestamp(capture_times)

        final_file_list = file_list[:]
        final_directions = directions[:]
        final_capture_times = capture_times[:]
        # FLAG DUPLICATES --------------------------------------
        if flag_duplicates:
            final_file_list = [file_list[0]]
            final_directions = [directions[0]]
            final_capture_times = [capture_times[0]]
            prev_latlon = latlons[0]
            prev_direction = directions[0]
            for i, filename in enumerate(file_list[1:]):
                log_root = uploader.log_rootpath(filename)
                duplicate_flag_path = os.path.join(log_root, "duplicate")
                sequence_process_success_path = os.path.join(
                    log_root, "sequence_process_success")
                k = i + 1
                distance = gps_distance(latlons[k], prev_latlon)
                if directions[k] is not None and prev_direction is not None:
                    direction_diff = diff_bearing(directions[k],
                                                  prev_direction)
                else:
                    # dont use bearing difference if no bearings are
                    # available
                    direction_diff = 360
                if distance < duplicate_distance and direction_diff < duplicate_angle:
                    open(duplicate_flag_path, "w").close()
                    open(sequence_process_success_path, "w").close()
                    open(
                        sequence_process_success_path + "_" +
                        str(time.strftime("%Y_%m_%d_%H_%M_%S", time.gmtime())),
                        "w").close()
                else:
                    prev_latlon = latlons[k]
                    prev_direction = directions[k]
                    final_file_list.append(filename)
                    final_directions.append(directions[k])
                    final_capture_times.append(capture_times[k])
        # ---------------------------------------

        # FINALIZE ------------------------------------
        for i in range(0, len(final_file_list), MAX_SEQUENCE_LENGTH):
            finalize_sequence_processing(
                str(uuid.uuid4()), final_file_list[i:i + MAX_SEQUENCE_LENGTH],
                final_directions[i:i + MAX_SEQUENCE_LENGTH],
                final_capture_times[i:i + MAX_SEQUENCE_LENGTH], import_path,
                verbose)
    print("Sub process ended")
def interpolation(data,
                  file_in_path=None,
                  file_format="csv",
                  time_column=0,
                  delimiter=",",
                  time_utc=False,
                  time_format="%Y-%m-%dT%H:%M:%SZ",
                  header=False,
                  keep_original=False,
                  import_path=None,
                  max_time_delta=1,
                  verbose=False):

    if not data:
        print("Error, you must specify the data for interpolation.")
        print('Choose between "missing_gps" or "identical_timestamps"')
        sys.exit(1)

    if not import_path and not file_in_path:
        print(
            "Error, you must specify a path to data, either path to directory with images or path to an external log file."
        )
        sys.exit(1)

    if file_in_path:
        if not os.path.isfile(file_in_path):
            print("Error, specified input file does not exist, exiting...")
            sys.exit(1)
        if file_format != "csv":
            print(
                "Only csv file format is supported at the moment, exiting...")
            sys.exit(1)

        csv_data = process_csv.read_csv(file_in_path,
                                        delimiter=delimiter,
                                        header=header)

        if data == "identical_timestamps":
            timestamps = csv_data[time_column]
            timestamps_datetime = [
                process_csv.format_time(timestamp, time_utc, time_format)
                for timestamp in timestamps
            ]

            timestamps_interpolated = processing.interpolate_timestamp(
                timestamps_datetime)

            csv_data[time_column] = format_datetime(timestamps_interpolated,
                                                    time_utc, time_format)

            file_out = file_in_path if not keep_original else file_in_path[:
                                                                           -4] + "_processed." + file_format

            with open(file_out, "w") as csvfile:
                csvwriter = csv.writer(csvfile, delimiter=delimiter)
                for row in zip(*csv_data):
                    csvwriter.writerow(row)
            sys.exit()
        elif data == "missing_gps":
            print(
                "Error, missing gps interpolation in an external log file not supported yet, exiting..."
            )
            sys.exit(1)
        else:
            print("Error unsupported data for interpolation, exiting...")
            sys.exit(1)

    if import_path:
        if not os.path.isdir(import_path):
            print("Error, specified import path does not exist, exiting...")
            sys.exit(1)

        # get list of files to process
        process_file_list = uploader.get_total_file_list(import_path)
        if not len(process_file_list):
            print("No images found in the import path " + import_path)
            sys.exit(1)

        if data == "missing_gps":
            # get geotags from images and a list of tuples with images missing geotags
            # and their timestamp
            geotags, missing_geotags = processing.get_images_geotags(
                process_file_list)
            if not len(missing_geotags):
                print("No images in directory {} missing geotags, exiting...".
                      format(import_path))
                sys.exit(1)
            if not len(geotags):
                print("No images in directory {} with geotags.".format(
                    import_path))
                sys.exit(1)

            sys.stdout.write(
                "Interpolating gps for {} images missing geotags.".format(
                    len(missing_geotags)))

            for image, timestamp in tqdm(missing_geotags,
                                         desc="Interpolating missing gps"):
                # interpolate
                try:
                    lat, lon, bearing, elevation = interpolate_lat_lon(
                        geotags, timestamp, max_time_delta)
                except Exception as e:
                    print(
                        "Error, {}, interpolation of latitude and longitude failed for image {}"
                        .format(e, image))
                    continue
                # insert into exif
                exif_edit = ExifEdit(image)
                if lat and lon:
                    exif_edit.add_lat_lon(lat, lon)
                else:
                    print("Error, lat and lon not interpolated for image {}.".
                          format(image))
                if bearing:
                    exif_edit.add_direction(bearing)
                else:
                    if verbose:
                        print(
                            "Warning, bearing not interpolated for image {}.".
                            format(image))
                if elevation:
                    exif_edit.add_altitude(elevation)
                else:
                    if verbose:
                        print(
                            "Warning, altitude not interpolated for image {}.".
                            format(image))

                meta = {}

                add_meta_tag(meta, "booleans", "interpolated_gps", True)

                exif_edit.add_image_history(meta["MAPMetaTags"])

                file_out = image if not keep_original else image[:-4] + "_processed."
                exif_edit.write(filename=file_out)

        elif data == "identical_timestamps":

            sys.stdout.write("Loading image timestamps.")

            # read timestamps
            timestamps = []
            for image in tqdm(process_file_list,
                              desc="Interpolating identical timestamps"):

                # load exif
                exif = ExifRead(image)
                timestamp = exif.extract_capture_time()
                if timestamp:
                    timestamps.append(timestamp)
                else:
                    print(
                        "Capture could not be extracted for image {}.".format(
                            image))

            # interpolate
            timestamps_interpolated = processing.interpolate_timestamp(
                timestamps)

            print("")
            sys.stdout.write("Interpolating identical timestamps.")
            counter = 0

            # write back
            for image, timestamp in tqdm(
                    zip(process_file_list, timestamps_interpolated),
                    desc="Writing capture time in image EXIF"):

                # print progress
                counter += 1
                sys.stdout.write('.')
                if (counter % 100) == 0:
                    print("")

                # load exif
                exif_edit = ExifEdit(image)
                exif_edit.add_date_time_original(timestamp)

                # write to exif
                file_out = image if not keep_original else image[:-4] + "_processed."
                exif_edit.write(filename=file_out)

            sys.exit()
        else:
            print("Error unsupported data for interpolation, exiting...")
            sys.exit(1)
    print("")
def interpolation(data,
                  file_in_path=None,
                  file_format="csv",
                  time_column=0,
                  delimiter=",",
                  time_utc=False,
                  time_format="%Y-%m-%dT%H:%M:%SZ",
                  header=False,
                  keep_original=False,
                  import_path=None,
                  max_time_delta=1,
                  verbose=False):

    if not data:
        print_error("Error, you must specify the data for interpolation." +
            'Choose between "missing_gps" or "identical_timestamps"')
        sys.exit(1)

    if not import_path and not file_in_path:
        print_error("Error, you must specify a path to data, either path to directory with images or path to an external log file.")
        sys.exit(1)

    if file_in_path:
        if not os.path.isfile(file_in_path):
            print_error("Error, specified input file does not exist, exiting...")
            sys.exit(1)
        if file_format != "csv":
            print_error("Only csv file format is supported at the moment, exiting...")
            sys.exit(1)

        csv_data = process_csv.read_csv(
            file_in_path, delimiter=delimiter, header=header)

        if data == "identical_timestamps":
            timestamps = csv_data[time_column]
            timestamps_datetime = [process_csv.format_time(
                timestamp, time_utc, time_format) for timestamp in timestamps]

            timestamps_interpolated = processing.interpolate_timestamp(
                timestamps_datetime)

            csv_data[time_column] = format_datetime(
                timestamps_interpolated, time_utc, time_format)

            file_out = file_in_path if not keep_original else file_in_path[
                :-4] + "_processed." + file_format

            with open(file_out, "w") as csvfile:
                csvwriter = csv.writer(csvfile, delimiter=delimiter)
                for row in zip(*csv_data):
                    csvwriter.writerow(row)
            sys.exit()
        elif data == "missing_gps":
            print_error(
                "Error, missing gps interpolation in an external log file not supported yet, exiting...")
            sys.exit(1)
        else:
            print_error("Error unsupported data for interpolation, exiting...")
            sys.exit(1)

    if import_path:
        if not os.path.isdir(import_path):
            print_error("Error, specified import path does not exist, exiting...")
            sys.exit(1)

        # get list of files to process
        process_file_list = uploader.get_total_file_list(import_path)
        if not len(process_file_list):
            print("No images found in the import path " + import_path)
            sys.exit(1)

        if data == "missing_gps":
            # get geotags from images and a list of tuples with images missing geotags
            # and their timestamp
            geotags, missing_geotags = processing.get_images_geotags(
                process_file_list)
            if not len(missing_geotags):
                print("No images in directory {} missing geotags, exiting...".format(
                    import_path))
                sys.exit(1)
            if not len(geotags):
                print("No images in directory {} with geotags.".format(import_path))
                sys.exit(1)

            sys.stdout.write("Interpolating gps for {} images missing geotags.".format(
                len(missing_geotags)))

            for image, timestamp in tqdm(missing_geotags, desc="Interpolating missing gps"):
                # interpolate
                try:
                    lat, lon, bearing, elevation = interpolate_lat_lon(
                        geotags, timestamp, max_time_delta)
                except Exception as e:
                    print_error("Error, {}, interpolation of latitude and longitude failed for image {}".format(
                        e, image))
                    continue
                # insert into exif
                exif_edit = ExifEdit(image)
                if lat and lon:
                    exif_edit.add_lat_lon(lat, lon)
                else:
                    print_error(
                        "Error, lat and lon not interpolated for image {}.".format(image))
                if bearing:
                    exif_edit.add_direction(bearing)
                else:
                    if verbose:
                        print(
                            "Warning, bearing not interpolated for image {}.".format(image))
                if elevation:
                    exif_edit.add_altitude(elevation)
                else:
                    if verbose:
                        print(
                            "Warning, altitude not interpolated for image {}.".format(image))

                meta = {}

                add_meta_tag(meta, "booleans", "interpolated_gps", True)

                exif_edit.add_image_history(meta["MAPMetaTags"])

                file_out = image if not keep_original else image[:-
                                                                 4] + "_processed."
                exif_edit.write(filename=file_out)

        elif data == "identical_timestamps":

            sys.stdout.write("Loading image timestamps.")

            # read timestamps
            timestamps = []
            for image in tqdm(process_file_list, desc="Interpolating identical timestamps"):

                # load exif
                exif = ExifRead(image)
                timestamp = exif.extract_capture_time()
                if timestamp:
                    timestamps.append(timestamp)
                else:
                    print("Capture could not be extracted for image {}.".format(image))

            # interpolate
            timestamps_interpolated = processing.interpolate_timestamp(
                timestamps)

            print("")
            sys.stdout.write("Interpolating identical timestamps.")
            counter = 0

            # write back
            for image, timestamp in tqdm(zip(process_file_list, timestamps_interpolated), desc="Writing capture time in image EXIF"):

                # print progress
                counter += 1
                sys.stdout.write('.')
                if (counter % 100) == 0:
                    print("")

                # load exif
                exif_edit = ExifEdit(image)
                exif_edit.add_date_time_original(timestamp)

                # write to exif
                file_out = image if not keep_original else image[
                    :-4] + "_processed."
                exif_edit.write(filename=file_out)

            sys.exit()
        else:
            print_error("Error unsupported data for interpolation, exiting...")
            sys.exit(1)
    print("")
def process_sequence_properties(import_path,
                                cutoff_distance=600.0,
                                cutoff_time=60.0,
                                interpolate_directions=False,
                                keep_duplicates=False,
                                duplicate_distance=0.1,
                                duplicate_angle=5,
                                offset_angle=0.0,
                                verbose=False,
                                rerun=False,
                                skip_subfolders=False,
                                video_import_path=None):

    # sanity check if video file is passed
    if video_import_path and not os.path.isdir(video_import_path) and not os.path.isfile(video_import_path):
        print("Error, video path " + video_import_path +
              " does not exist, exiting...")
        sys.exit(1)

    # in case of video processing, adjust the import path
    if video_import_path:
        # set sampling path
        video_sampling_path = "mapillary_sampled_video_frames"
        video_dirname = video_import_path if os.path.isdir(
            video_import_path) else os.path.dirname(video_import_path)
        import_path = os.path.join(os.path.abspath(import_path), video_sampling_path) if import_path else os.path.join(
            os.path.abspath(video_dirname), video_sampling_path)

    # basic check for all
    if not import_path or not os.path.isdir(import_path):
        print_error("Error, import directory " + import_path +
                    " does not exist, exiting...")
        sys.exit(1)

    sequences = []
    if skip_subfolders:
        process_file_list = processing.get_process_file_list(import_path,
                                                             "sequence_process",
                                                             rerun,
                                                             verbose,
                                                             True,
                                                             import_path)
        if not len(process_file_list):
            if verbose:
                print("No images to run sequence process in root " + import_path)
                print(
                    "If the images have already been processed and not yet uploaded, they can be processed again, by passing the argument --rerun")
        else:
            # LOAD TIME AND GPS POINTS ------------------------------------
            file_list, capture_times, lats, lons, directions = processing.load_geotag_points(
                process_file_list, verbose)
            # ---------------------------------------

            # SPLIT SEQUENCES --------------------------------------
            if len(capture_times) and len(lats) and len(lons):
                sequences.extend(processing.split_sequences(
                    capture_times, lats, lons, file_list, directions, cutoff_time, cutoff_distance, verbose))
        # ---------------------------------------
    else:
        # sequence limited to the root of the files
        for root, dirs, files in os.walk(import_path):
            if os.path.join(".mapillary", "logs") in root:
                continue
            if len(files):
                process_file_list = processing.get_process_file_list(import_path,
                                                                     "sequence_process",
                                                                     rerun,
                                                                     verbose,
                                                                     True,
                                                                     root)
                if not len(process_file_list):
                    if verbose:
                        print("No images to run sequence process in root " + root)
                        print(
                            "If the images have already been processed and not yet uploaded, they can be processed again, by passing the argument --rerun")
                    continue
                # LOAD TIME AND GPS POINTS ------------------------------------
                file_list, capture_times, lats, lons, directions = processing.load_geotag_points(
                    process_file_list, verbose)
                # ---------------------------------------
                # SPLIT SEQUENCES --------------------------------------
                if len(capture_times) and len(lats) and len(lons):
                    sequences.extend(processing.split_sequences(
                        capture_times, lats, lons, file_list, directions, cutoff_time, cutoff_distance, verbose))
                # ---------------------------------------
    if not keep_duplicates:
        if verbose:
            print("Flagging images as duplicates if consecutive distance difference less than {} and angle difference less than {}".format(
                duplicate_distance, duplicate_angle))

    # process for each sequence
    for sequence in sequences:
        file_list = sequence["file_list"]
        directions = sequence["directions"]
        latlons = sequence["latlons"]
        capture_times = sequence["capture_times"]

        # COMPUTE DIRECTIONS --------------------------------------
        interpolated_directions = [compute_bearing(ll1[0], ll1[1], ll2[0], ll2[1])
                                   for ll1, ll2 in zip(latlons[:-1], latlons[1:])]
        if len(interpolated_directions):
            interpolated_directions.append(interpolated_directions[-1])
        else:
            interpolated_directions.append(directions[-1])
        # use interpolated directions if direction not available or if flag for
        # interpolate_directions
        for i, d in enumerate(directions):
            directions[i] = d if (
                d is not None and not interpolate_directions) else (interpolated_directions[i] + offset_angle) % 360.0
        # ---------------------------------------

        # COMPUTE SPEED -------------------------------------------
        computed_delta_ts = [(t1 - t0).total_seconds()
                             for t0, t1 in zip(capture_times[:-1], capture_times[1:])]
        computed_distances = [gps_distance(l1, l0)
                              for l0, l1 in zip(latlons[:-1], latlons[1:])]
        computed_speed = gps_speed(
            computed_distances, computed_delta_ts)  # in meters/second
        if len([x for x in computed_speed if x > MAX_CAPTURE_SPEED]) > 0:
            print("Warning: The distance in sequence including images\n{}\nto\n{}\nis too large for the time difference (very high apparent capture speed). Are you sure timestamps and locations are correct?".format(
                file_list[0], file_list[-1]))

        # INTERPOLATE TIMESTAMPS, in case of identical timestamps
        capture_times = processing.interpolate_timestamp(capture_times)

        final_file_list = file_list[:]
        final_directions = directions[:]
        final_capture_times = capture_times[:]
        # FLAG DUPLICATES --------------------------------------
        if not keep_duplicates:
            final_file_list = [file_list[0]]
            final_directions = [directions[0]]
            final_capture_times = [capture_times[0]]
            prev_latlon = latlons[0]
            prev_direction = directions[0]
            for i, filename in enumerate(file_list[1:]):
                log_root = uploader.log_rootpath(filename)
                duplicate_flag_path = os.path.join(log_root,
                                                   "duplicate")
                sequence_process_success_path = os.path.join(log_root,
                                                             "sequence_process_success")
                k = i + 1
                distance = gps_distance(latlons[k],
                                        prev_latlon)
                if directions[k] is not None and prev_direction is not None:
                    direction_diff = diff_bearing(directions[k],
                                                  prev_direction)
                else:
                    # dont use bearing difference if no bearings are
                    # available
                    direction_diff = 360
                if distance < duplicate_distance and direction_diff < duplicate_angle:
                    open(duplicate_flag_path, "w").close()
                    open(sequence_process_success_path, "w").close()
                    open(sequence_process_success_path + "_" +
                         str(time.strftime("%Y_%m_%d_%H_%M_%S", time.gmtime())), "w").close()
                else:
                    prev_latlon = latlons[k]
                    prev_direction = directions[k]
                    final_file_list.append(filename)
                    final_directions.append(directions[k])
                    final_capture_times.append(capture_times[k])
        # ---------------------------------------

        # FINALIZE ------------------------------------
        for i in range(0, len(final_file_list), MAX_SEQUENCE_LENGTH):
            finalize_sequence_processing(str(uuid.uuid4()),
                                         final_file_list[i:i +
                                                         MAX_SEQUENCE_LENGTH],
                                         final_directions[i:i +
                                                          MAX_SEQUENCE_LENGTH],
                                         final_capture_times[i:i +
                                                             MAX_SEQUENCE_LENGTH],
                                         import_path,
                                         verbose)
    print("Sub process ended")
def process_sequence_properties(import_path,
                                cutoff_distance=600.0,
                                cutoff_time=60.0,
                                interpolate_directions=False,
                                flag_duplicates=False,
                                duplicate_distance=0.1,
                                duplicate_angle=5,
                                offset_angle=0.0,
                                verbose=False,
                                rerun=False,
                                skip_subfolders=False):
    # basic check for all
    import_path = os.path.abspath(import_path)
    if not os.path.isdir(import_path):
        print("Error, import directory " + import_path +
              " doesnt not exist, exiting...")
        sys.exit()

    sequences = []
    if skip_subfolders:
        process_file_list = processing.get_process_file_list(import_path,
                                                             "sequence_process",
                                                             rerun,
                                                             verbose,
                                                             True,
                                                             import_path)
        if not len(process_file_list):
            if verbose:
                print("No images to run sequence process in root " + import_path)
                print(
                    "If the images have already been processed and not yet uploaded, they can be processed again, by passing the argument --rerun")
        else:
            # LOAD TIME AND GPS POINTS ------------------------------------
            file_list, capture_times, lats, lons, directions = processing.load_geotag_points(
                process_file_list, import_path, verbose)
            # ---------------------------------------

            # SPLIT SEQUENCES --------------------------------------
            if len(capture_times) and len(lats) and len(lons):
                sequences.extend(processing.split_sequences(
                    capture_times, lats, lons, file_list, directions, cutoff_time, cutoff_distance, verbose))
        # ---------------------------------------
    else:
        # sequence limited to the root of the files
        for root, dirs, files in os.walk(import_path):
            if ".mapillary" in root:
                continue
            if len(files):
                process_file_list = processing.get_process_file_list(import_path,
                                                                     "sequence_process",
                                                                     rerun,
                                                                     verbose,
                                                                     True,
                                                                     root)
                if not len(process_file_list):
                    if verbose:
                        print("No images to run sequence process in root " + root)
                        print(
                            "If the images have already been processed and not yet uploaded, they can be processed again, by passing the argument --rerun")
                    continue

                # LOAD TIME AND GPS POINTS ------------------------------------
                file_list, capture_times, lats, lons, directions = processing.load_geotag_points(
                    process_file_list, import_path, verbose)
                # ---------------------------------------

                # SPLIT SEQUENCES --------------------------------------
                if len(capture_times) and len(lats) and len(lons):
                    sequences.extend(processing.split_sequences(
                        capture_times, lats, lons, file_list, directions, cutoff_time, cutoff_distance, verbose))
                # ---------------------------------------

    # process for each sequence
    for sequence in sequences:
        file_list = sequence["file_list"]
        directions = sequence["directions"]
        latlons = sequence["latlons"]
        capture_times = sequence["capture_times"]

        # COMPUTE DIRECTIONS --------------------------------------
        interpolated_directions = [compute_bearing(ll1[0], ll1[1], ll2[0], ll2[1])
                                   for ll1, ll2 in zip(latlons, latlons[1:])]
        interpolated_directions.append(directions[-1])
        # use interpolated directions if direction not available or if flag for
        # interpolate_directions
        for i, d in enumerate(directions):
            directions[i] = d if (
                d is not None and not interpolate_directions) else (interpolated_directions[i] + offset_angle) % 360.0
        # ---------------------------------------

        # INTERPOLATE TIMESTAMPS, incase of identical timestamps
        capture_times, file_list = processing.interpolate_timestamp(capture_times,
                                                                    file_list)

        final_file_list = file_list[:]
        final_directions = directions[:]
        final_capture_times = capture_times[:]

        # FLAG DUPLICATES --------------------------------------
        if flag_duplicates:
            final_file_list = [file_list[0]]
            final_directions = [directions[0]]
            prev_latlon = latlons[0]
            prev_direction = directions[0]
            for i, filename in enumerate(file_list[1:]):
                log_root = uploader.log_rootpath(import_path,
                                                 filename)
                duplicate_flag_path = os.path.join(log_root,
                                                   "duplicate")
                sequence_process_success_path = os.path.join(log_root,
                                                             "sequence_process_success")
                k = i + 1
                distance = gps_distance(latlons[k],
                                        prev_latlon)
                if directions[k] is not None and prev_direction is not None:
                    direction_diff = diff_bearing(directions[k],
                                                  prev_direction)
                else:
                    # dont use bearing difference if no bearings are
                    # available
                    direction_diff = 360
                if distance < duplicate_distance and direction_diff < duplicate_angle:
                    open(duplicate_flag_path, "w").close()
                    open(sequence_process_success_path, "w").close()
                    open(sequence_process_success_path + "_" +
                         str(time.strftime("%Y_%m_%d_%H_%M_%S", time.gmtime())), "w").close()
                else:
                    prev_latlon = latlons[k]
                    prev_direction = directions[k]
                    final_file_list.append(filename)
                    final_directions.append(directions[k])
        # ---------------------------------------

        # FINALIZE ------------------------------------
        for i in range(0, len(final_file_list), MAX_SEQUENCE_LENGTH):
            finalize_sequence_processing(str(uuid.uuid4()),
                                         final_file_list[i:i +
                                                         MAX_SEQUENCE_LENGTH],
                                         final_directions[i:i +
                                                          MAX_SEQUENCE_LENGTH],
                                         final_capture_times[i:i +
                                                             MAX_SEQUENCE_LENGTH],
                                         import_path,
                                         verbose)