Esempio n. 1
0
    def colourmap(self):
        """ gets colourmap. """
        if not globs._previewer_colour_map:
            colourmap = self.config.previews_colour_map
            if os.path.exists(colourmap):
                self.colormap = tools.load_colormap(colourmap)
            else:
                print("using default colour map")
                self.colormap = plt.get_cmap('jet')

        return globs._previewer_colour_map
def main():

    parser = argparse.ArgumentParser()

    parser.add_argument(
        'source',
        help=
        'a CPTV file to process, or a folder name, or "all" for all files within subdirectories of source folder.'
    )

    parser.add_argument('-p',
                        '--enable-preview',
                        default=False,
                        action='store_true',
                        help='Enables preview MPEG files (can be slow)')
    parser.add_argument(
        '-b',
        '--side-by-side',
        default=False,
        action='store_true',
        help='Output processed footage next to original output in preview MPEG'
    )
    parser.add_argument('-t',
                        '--enable-track-info',
                        default=False,
                        action='store_true',
                        help='Enables output of per track information')
    parser.add_argument('-q',
                        '--high-quality-optical-flow',
                        default=False,
                        action='store_true',
                        help='Enabled higher quality optical flow (slow)')
    parser.add_argument('-v',
                        '--verbose',
                        default=0,
                        action='count',
                        help='Display additional information.')
    parser.add_argument(
        '-w',
        '--workers',
        default=0,
        help=
        'Number of worker threads to use.  0 disables worker pool and forces a single thread.'
    )
    parser.add_argument('-f',
                        '--force-overwrite',
                        default='none',
                        help='Overwrite mode.  Options are all, old, or none.')
    parser.add_argument('-o',
                        '--output-folder',
                        default=os.path.join(DEFAULT_BASE_PATH, "autotagged"),
                        help='Folder to output tracks to')
    parser.add_argument(
        '-s',
        '--source-folder',
        default=os.path.join(DEFAULT_BASE_PATH, "clips"),
        help='Source folder root with class folders containing CPTV files')

    parser.add_argument('-m',
                        '--model',
                        default=os.path.join(HERE, "models", "Model-4f-0.904"),
                        help='Model to use for classification')
    parser.add_argument('-i',
                        '--include-prediction-in-filename',
                        default=False,
                        action='store_true',
                        help='Adds class scores to output files')
    parser.add_argument(
        '--meta-to-stdout',
        default=False,
        action='store_true',
        help='Writes metadata to standard out instead of a file')

    parser.add_argument(
        '--start-date',
        help=
        'Only clips on or after this day will be processed (format YYYY-MM-DD)'
    )
    parser.add_argument(
        '--end-date',
        help=
        'Only clips on or before this day will be processed (format YYYY-MM-DD)'
    )
    parser.add_argument('--disable-gpu',
                        default=False,
                        action='store_true',
                        help='Disables GPU acclelerated classification')

    args = parser.parse_args()

    if not args.meta_to_stdout:
        log_to_stdout()

    clip_classifier = ClipClassifier()
    clip_classifier.enable_gpu = not args.disable_gpu
    clip_classifier.enable_previews = args.enable_preview
    clip_classifier.enable_side_by_side = args.side_by_side
    clip_classifier.output_folder = args.output_folder
    clip_classifier.source_folder = args.source_folder
    clip_classifier.model_path = args.model
    clip_classifier.enable_per_track_information = args.enable_track_info
    clip_classifier.high_quality_optical_flow = args.high_quality_optical_flow
    clip_classifier.include_prediction_in_filename = args.include_prediction_in_filename
    clip_classifier.write_meta_to_stdout = args.meta_to_stdout

    if clip_classifier.high_quality_optical_flow:
        logging.info("High quality optical flow enabled.")

    if not clip_classifier.enable_gpu:
        logging.info("GPU mode disabled.")

    if not os.path.exists(args.model + ".meta"):
        logging.error("No model found named '{}'.".format(args.model +
                                                          ".meta"))
        exit(13)

    if args.start_date:
        clip_classifier.start_date = datetime.strptime(args.start_date,
                                                       "%Y-%m-%d")

    if args.end_date:
        clip_classifier.end_date = datetime.strptime(args.end_date, "%Y-%m-%d")

    # just fetch the classifier now so it doesn't impact the benchmarking on the first clip analysed.
    _ = clip_classifier.classifier

    # apply the colormap
    clip_classifier.colormap = load_colormap(
        resource_path("custom_colormap.dat"))

    clip_classifier.workers_threads = int(args.workers)
    if clip_classifier.workers_threads >= 1:
        logging.info("Using {0} worker threads".format(
            clip_classifier.workers_threads))

    # set overwrite mode
    if args.force_overwrite.lower() not in ['all', 'old', 'none']:
        raise Exception("Valid overwrite modes are all, old, or none.")
    clip_classifier.overwrite_mode = args.force_overwrite.lower()

    # set verbose
    clip_classifier.verbose = args.verbose

    if args.source == "all":
        clip_classifier.process_root(args.source_folder)
    elif os.path.splitext(args.source)[-1].lower() == '.cptv':
        clip_classifier.process_file(
            os.path.join(args.source_folder, args.source))
    else:
        clip_classifier.process_folder(
            os.path.join(args.source_folder, args.source))
Esempio n. 3
0
def parse_params():

    parser = argparse.ArgumentParser()

    parser.add_argument('target', default='all', help='Target to process, "all" processes all folders, "test" runs test cases, "clean" to remove banned clips from db, or a "cptv" file to run a single source.')

    parser.add_argument('-o', '--output-folder', default=os.path.join(DEFAULT_BASE_PATH,"tracks"), help='Folder to output tracks to')
    parser.add_argument('-s', '--source-folder', default=os.path.join(DEFAULT_BASE_PATH,"clips"), help='Source folder root with class folders containing CPTV files')
    parser.add_argument('-c', '--color-map', default="custom_colormap.dat", help='Colormap to use when exporting MPEG files')
    parser.add_argument('-p', '--enable-previews', action='count', help='Enables preview MPEG files (can be slow)')
    parser.add_argument('-t', '--test-file', default='tests.txt', help='File containing test cases to run')
    parser.add_argument('--high-quality-optical-flow', default=False, action='store_true', help='Enables high quality optical flow (much slower).')
    parser.add_argument('-v', '--verbose', action='count', help='Display additional information.')
    parser.add_argument('-w', '--workers', default='0', help='Number of worker threads to use.  0 disables worker pool and forces a single thread.')
    parser.add_argument('-f', '--force-overwrite', default='old', help='Overwrite mode.  Options are all, old, or none.')
    parser.add_argument('-i', '--show-build-information', action='count', help='Show openCV build information and exit.')
    parser.add_argument('-d','--disable-track-filters', default=False, action='store_true', help='Disables filtering of poor quality tracks.')

    args = parser.parse_args()

    if args.show_build_information:
        print(cv2.getBuildInformation())
        return

    # setup extractor
    extractor = CPTVTrackExtractor(args.output_folder)

    extractor.workers_threads = int(args.workers)
    if extractor.workers_threads >= 1:
        print("Using {0} worker threads".format(extractor.workers_threads))

    # set overwrite mode
    if args.force_overwrite.lower() not in ['all','old','none']:
        raise Exception("Valid overwrite modes are all, old, or none.")
    extractor.overwrite_mode = args.force_overwrite.lower()

    # set optical flow
    extractor.high_quality_optical_flow = args.high_quality_optical_flow

    # set verbose
    extractor.verbose = args.verbose

    # this colormap is specially designed for heat maps
    extractor.colormap = tools.load_colormap(args.color_map)

    # load hints.  Hints are a way to give extra information to the tracker when necessary.
    extractor.load_hints("hints.txt")

    extractor.enable_previews = args.enable_previews

    extractor.source_folder = args.source_folder
    extractor.output_folder = args.output_folder

    # allow everything through
    extractor.disable_track_filters = args.disable_track_filters

    if extractor.enable_previews:
        print("Previews enabled.")

    if os.path.splitext(args.target)[1].lower() == '.cptv':
        # run single source
        source_file = tools.find_file(args.source_folder, args.target)
        tag = os.path.basename(os.path.dirname(source_file))
        extractor.overwrite_mode = CPTVTrackExtractor.OM_ALL
        extractor.process_file(source_file, tag=tag)
        return

    if args.target.lower() == 'test':
        print("Running test suite")
        extractor.run_tests(args.source_folder, args.test_file)
        return

    print('Processing tag "{0}"'.format(args.target))

    if args.target.lower() == 'all':
        extractor.clean_all()
        extractor.process_all(args.source_folder)
        return
    if args.target.lower() == 'clean':
        extractor.clean_all()
        return
    else:
        extractor.process_folder(os.path.join(args.source_folder, args.target), tag=args.target, worker_pool_args=(trackdatabase.hdf5_lock,))
        return
    def process_file(self, filename):
        """
        Process a file extracting tracks and identifying them.
        :param filename: filename to process
        :param enable_preview: if true an MPEG preview file is created.
        """

        if not os.path.exists(filename):
            raise Exception("File {} not found.".format(filename))

        start = time.time()

        # extract tracks from file
        tracker = TrackExtractor(filename)

        tracker.reduced_quality_optical_flow = not self.high_quality_optical_flow
        tracker.colormap = load_colormap(resource_path("custom_colormap.dat"))

        tracker.extract()

        if len(tracker.tracks) > 10:
            logging.warning(
                " -warning, found too many tracks.  Using {} of {}".format(
                    10, len(tracker.tracks)))
            tracker.tracks = tracker.tracks[:10]

        base_name = self.get_base_name(filename)

        if self.include_prediction_in_filename:
            mpeg_filename = base_name + "{}" + '.mp4'
        else:
            mpeg_filename = base_name + '.mp4'

        meta_filename = base_name + '.txt'
        track_mpeg_filename = base_name + "-{} {}.mpg"
        track_meta_filename = base_name + "-{}.txt"

        # reset track predictions
        self.track_prediction = {}

        logging.info(os.path.basename(filename) + ":")

        # identify each track
        for i, track in enumerate(tracker.tracks):

            prediction = self.identify_track(track)

            self.track_prediction[track] = prediction

            description = prediction.description(self.classifier.classes)

            logging.info(" - [{}/{}] prediction: {}".format(
                i + 1, len(tracker.tracks), description))

            if self.enable_per_track_information:
                prediction.save(track_meta_filename.format(i + 1))
                if self.enable_previews:
                    self.export_track_preview(
                        track_mpeg_filename.format(i + 1, description), track)

        if self.enable_previews:
            prediction_string = ""
            for label, score in self.get_clip_prediction():
                if score > 0.5:
                    prediction_string = prediction_string + " {} {:.1f}".format(
                        label, score * 10)
            self.export_clip_preview(mpeg_filename.format(prediction_string),
                                     tracker)

        # read in original metadata
        meta_data = self.get_meta_data(filename)

        # record results in text file.
        save_file = {}
        save_file['source'] = filename
        save_file['start_time'] = tracker.video_start_time.isoformat()
        save_file['end_time'] = (
            tracker.video_start_time +
            timedelta(seconds=len(tracker.frames) / 9.0)).isoformat()

        if meta_data:
            save_file['camera'] = meta_data['Device']['devicename']
            save_file['cptv_meta'] = meta_data
            save_file['original_tag'] = meta_data['primary_tag']
        save_file['tracks'] = []
        for track, prediction in self.track_prediction.items():
            track_info = {}
            save_file['tracks'].append(track_info)
            track_info['start_time'] = track.start_time.isoformat()
            track_info['end_time'] = track.end_time.isoformat()
            track_info['label'] = self.classifier.classes[prediction.label()]
            track_info['confidence'] = prediction.confidence()
            track_info['clarity'] = prediction.clarity
            track_info['class_confidence'] = prediction.class_best_confidence

        if self.write_meta_to_stdout:
            output = json.dumps(save_file,
                                indent=4,
                                cls=tools.CustomJSONEncoder)
            print(output)
        else:
            f = open(meta_filename, 'w')
            json.dump(save_file, f, indent=4, cls=tools.CustomJSONEncoder)

        ms_per_frame = (time.time() - start) * 1000 / max(
            1, len(tracker.frames))
        if self.verbose:
            logging.info("Took {:.1f}ms per frame".format(ms_per_frame))