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))
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))