def __init__(self, gt_path, video_path, metric_func, init=True, classifier=None): self.classifier = classifier self.capture = create_capture(video_path) self.converter = VideoFrameConverter(self.capture) self.ground_truth = GTHVideoSubstrates(gt_path, self.capture) self.classes = self.ground_truth.classes_present self.metric = metric_func self.training_frames = [] # Stores all frames used in training self.x = [] # frames n_samples * n_features self.y = [] # labels n_samples self.classifier.ground_truth = gt_path self.classifier.video_path = video_path self.training_c_to_frames = {} self._setup_training_dict() if init: self.train()
def load_video(self): path = self.lbl_path.text() self.cap = create_capture(path) self.vid = VideoFrameConverter(self.cap) self.sld_pos.setRange(0, self.vid.num_frames) self.sld_pos.setValue(0) self.timer = QTimer(self) self.timer.timeout.connect(self._play) self.timer.start(27) self.update()
def __init__(self, capture, video_src, output_dir, annotator, existing_data=None): """ frameskip at 700 is *roughly* 30seconds """ self._capture = capture self._converter = VideoFrameConverter(capture) self._frames_num_total = self._converter.num_frames self._output_dir = output_dir self._video_src = video_src self._complete = False self._existing_data = existing_data self.set_annotator(annotator) self._ground_truth = { STR_AUTH: annotator, STR_DATE: time.time(), STR_VERS: APP_VERSION, STR_COMP: False, STR_FILE: video_src, STR_DATA: {}, STR_EXST: None } if self._existing_data is not None: self._build_from_existing_data()
class ValidWindow(unittest.TestCase): def setUp(self): path_gp = p.get_path(p.KEY_GOPRO) self.fp = path_gp + "Site 2.MP4" self.cap = create_capture(self.fp) self.conv = VideoFrameConverter(self.cap) def test_site_2(self): patches = self.conv.get_frame_mxn_patches_generator(20, 20) assert True
class EXPMLVidSubstrateBase(object): def __init__(self, gt_path, video_path, metric_func, init=True, classifier=None): self.classifier = classifier self.capture = create_capture(video_path) self.converter = VideoFrameConverter(self.capture) self.ground_truth = GTHVideoSubstrates(gt_path, self.capture) self.classes = self.ground_truth.classes_present self.metric = metric_func self.training_frames = [] # Stores all frames used in training self.x = [] # frames n_samples * n_features self.y = [] # labels n_samples self.classifier.ground_truth = gt_path self.classifier.video_path = video_path self.training_c_to_frames = {} self._setup_training_dict() if init: self.train() def _setup_training_dict(self): for k in self.classes: if k not in self.training_c_to_frames: self.training_c_to_frames[k] = [x for x in self.get_training_frames(k)] # def process_frame(self, frame): # """ # Default frame processor, simply uses self.metric function pointer on # the entire frame passed through. Converts the representation to a # n x 1 vector for speed by default. Returns processed data in the form # of a generator. # """ # data = self.metric(frame) # # #if isinstance(data, np.ndarray): # # data = data.ravel() # # yield data def train(self): """ Trains the classifier, looks to process_frame to deliver the metric-affected version of the whole frame, or subsections thereof. This method doesn't really care if process_frame returns 1 or more results, it just collates the training vectors X and Y before passing to sklearn for fitting. """ # Thread safe lists here? @todo: multiprocessing for k, v in self.training_c_to_frames.iteritems(): for i in v: self.converter.set_current_frame(i) self.x.append(self.metric(self.converter.capture_next_frame(True))) self.y.append(k) log.info("Beginning fitting for " + self.classifier.identifier) # Keep a reference to the frames we have chosen for this iteration self.classifier.training_data = self.training_frames self.classifier.raw_classifier.fit(np.array(self.x), np.array(self.y)) def process_frame(self, frame): return self.metric(frame) def get_training_frames(self, klass, n=None): """ Generator method that records the training frames selected in this iteration, and yields the frames sequentially for given klass. Parameter n is optional, and may indeed be deprecated. It is to limit the number below 10% of all frames, and was only relevant for Gabor full-frame image representations. """ frames, _ = self.ground_truth.get_sample_frames_for_class(klass, n=n) self.training_frames.extend(frames) # Keep a reference to them for f in frames: yield f def get_data_from_frame(self, frame): return frame
class WTrackerMarking(QMainWindow): """ Main Tracking Window """ STR_WIN_TITLE = 'Mark Video' STR_CLK = 'clicked()' STR_SPECIFY_VIDEO = 'Specify Video' def __init__(self, def_path=None): super(WTrackerMarking, self).__init__(None) self._trackers = HLDTrackers() self.paused = False self.timer = QTimer(self) # Widgets lbl_path_str = QLabel("Video Path:") path = def_path if def_path is not None else os.getcwd() self.lbl_path = QLabel(path) self.lbl_path.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) lbl_sld_pos = QLabel("Position:") btn_path = QPushButton("&Path...") btn_load = QPushButton("&Load") btn_vid_toggle = QPushButton("&Start/Stop") btn_reset_video = QPushButton("&Reset Video") btn_reset_track = QPushButton("Reset &Trackers") self.sld_pos = QWVideoPositionSlider(Qt.Horizontal, self, self.pause, self.unpause) self.sld_pos.valueChanged[int].connect(self.update_position) btn_rem_tracker = QPushButton("&Delete") self.cmb_trackers = QComboBox(self) self.cmb_tracker_types = QComboBox(self) self._build_cmb_trackers() # Images self.win_vid_filters = WTrackerOutputWindow(self) self.frm_vid_output = QWVideoFrameLabel(self) self.frm_vid_output.setGeometry(10, 10, 400, 100) # Callbacks self.connect(btn_path, SIGNAL(self.STR_CLK), self.set_path) self.connect(btn_load, SIGNAL(self.STR_CLK), self.load_video) self.connect(btn_vid_toggle, SIGNAL(self.STR_CLK), self.toggle_video) self.connect(btn_reset_video, SIGNAL(self.STR_CLK), self.do_reset_video) self.connect(btn_reset_track, SIGNAL(self.STR_CLK), self.do_reset_trackers) self.connect(btn_rem_tracker, SIGNAL(self.STR_CLK), self.remove_tracker) # Layouts lyt_main = QVBoxLayout() lyt_top = QHBoxLayout() lyt_top.addWidget(lbl_path_str) lyt_top.addWidget(self.lbl_path, 1) lyt_top.addWidget(btn_path) lyt_btm = QHBoxLayout() lyt_btm.addWidget(btn_load) lyt_btm.addWidget(btn_vid_toggle) lyt_btm.addWidget(btn_reset_video) lyt_btm.addWidget(btn_reset_track) lyt_btm.addWidget(self.cmb_tracker_types) lyt_btm.addWidget(lbl_sld_pos) lyt_btm.addWidget(self.sld_pos) lyt_btm.addWidget(self.cmb_trackers) lyt_btm.addWidget(btn_rem_tracker) lyt_main.setAlignment(Qt.AlignTop) lyt_main.addLayout(lyt_top) lyt_main.addLayout(lyt_btm) lyt_main.addWidget(self.frm_vid_output) lyt_main.setMargin(10) lyt_main.setSpacing(10) widget = QWidget() widget.setLayout(lyt_main) self.setCentralWidget(widget) self.setGeometry(260, 20, 1000, 55) self.setWindowTitle(self.STR_WIN_TITLE) ## Overridden functions, handle child window def show(self): super(WTrackerMarking, self).show() self.win_vid_filters.show() def hide(self): self.win_vid_filters.hide() super(WTrackerMarking, self).hide() def close(self): self.win_vid_filters.close() super(WTrackerMarking, self).close() ## Object functions def _build_cmb_trackers(self, default='MOSSE'): for t in TRACKER_TYPES.keys(): self.cmb_tracker_types.addItem(t) id_ref = self.cmb_tracker_types.findText(default) self.cmb_tracker_types.setCurrentIndex(id_ref) def add_tracker(self, rect): tracker_name = self.cmb_tracker_types.currentText() tracker = TRACKER_TYPES[str(tracker_name)] frame_gray = cvtColor(self.vid.current_frame, COLOR_BGR2GRAY) # This now depends on the value of the combobox new_tracker = tracker(frame_gray, rect) self.trackers.add(new_tracker) tracker_id = str(new_tracker.get_id()) self.cmb_trackers.addItem(tracker_id) id_ref = self.cmb_trackers.findText(tracker_id) self.cmb_trackers.setCurrentIndex(id_ref) def remove_tracker(self): tracker_id = self.current_tracker_id self.trackers.remove(tracker_id) tracker_ref = self.cmb_trackers.findText(tracker_id) self.cmb_trackers.removeItem(tracker_ref) def do_reset_video(self): self.timer.stop() self.load_video() def do_reset_trackers(self): self.trackers.reset() self.cmb_trackers.clear() def toggle_video(self): self.paused = not self.paused def set_path(self): path = QFileDialog.getOpenFileName(self, self.STR_SPECIFY_VIDEO, self.lbl_path.text()) if path: self.lbl_path.setText(QDir.toNativeSeparators(path)) def load_video(self): path = self.lbl_path.text() self.cap = create_capture(path) self.vid = VideoFrameConverter(self.cap) self.sld_pos.setRange(0, self.vid.num_frames) self.sld_pos.setValue(0) self.timer = QTimer(self) self.timer.timeout.connect(self._play) self.timer.start(27) self.update() def pause(self): self.paused = True def unpause(self): self.paused = False def _play(self): if self.paused: return frame = self.vid.get_next_frame() if frame: if self.trackers.active: raw_frame = self.vid.current_frame frame_gray = cvtColor(raw_frame, COLOR_BGR2GRAY) self.trackers.update_all(frame_gray) self.trackers.write_to_frame(raw_frame) frame = convert_single_frame(raw_frame) tracker = self.trackers.get(self.current_tracker_id) vis = cvtColor(tracker.state_vis, COLOR_GRAY2RGB) q_vis = convert_single_frame(vis) self.win_vid_filters.update_image(q_vis) self.frm_vid_output.setPixmap(frame) else: self.timer.stop() self.load_video() def update_position(self, value): self.vid.set_current_frame(value) @property def trackers(self): return self._trackers @trackers.setter def trackers(self, new_trackers): self._trackers = new_trackers @property def current_tracker_id(self): return str(self.cmb_trackers.currentText())
def __init__(self, input_json, capture): self._input_json = input_json self._capture = capture self._converter = VideoFrameConverter(capture) self._classes = {} self._parse_json(input_json)
def setUp(self): path_gp = p.get_path(p.KEY_GOPRO) self.fp = path_gp + "Site 2.MP4" self.cap = create_capture(self.fp) self.conv = VideoFrameConverter(self.cap)
class EXPMLVidSubstrateBase(object): def __init__(self, gt_path, video_path, metric_func, init=True, classifier=None): self.classifier = classifier self.capture = create_capture(video_path) self.converter = VideoFrameConverter(self.capture) self.ground_truth = GTHVideoSubstrates(gt_path, self.capture) self.classes = self.ground_truth.classes_present self.metric = metric_func self.training_frames = [] # Stores all frames used in training self.x = [] # frames n_samples * n_features self.y = [] # labels n_samples self.classifier.ground_truth = gt_path self.classifier.video_path = video_path self.training_c_to_frames = {} self._setup_training_dict() if init: self.train() def _setup_training_dict(self): for k in self.classes: if k not in self.training_c_to_frames: self.training_c_to_frames[k] = [ x for x in self.get_training_frames(k) ] # def process_frame(self, frame): # """ # Default frame processor, simply uses self.metric function pointer on # the entire frame passed through. Converts the representation to a # n x 1 vector for speed by default. Returns processed data in the form # of a generator. # """ # data = self.metric(frame) # # #if isinstance(data, np.ndarray): # # data = data.ravel() # # yield data def train(self): """ Trains the classifier, looks to process_frame to deliver the metric-affected version of the whole frame, or subsections thereof. This method doesn't really care if process_frame returns 1 or more results, it just collates the training vectors X and Y before passing to sklearn for fitting. """ # Thread safe lists here? @todo: multiprocessing for k, v in self.training_c_to_frames.iteritems(): for i in v: self.converter.set_current_frame(i) self.x.append( self.metric(self.converter.capture_next_frame(True))) self.y.append(k) log.info("Beginning fitting for " + self.classifier.identifier) # Keep a reference to the frames we have chosen for this iteration self.classifier.training_data = self.training_frames self.classifier.raw_classifier.fit(np.array(self.x), np.array(self.y)) def process_frame(self, frame): return self.metric(frame) def get_training_frames(self, klass, n=None): """ Generator method that records the training frames selected in this iteration, and yields the frames sequentially for given klass. Parameter n is optional, and may indeed be deprecated. It is to limit the number below 10% of all frames, and was only relevant for Gabor full-frame image representations. """ frames, _ = self.ground_truth.get_sample_frames_for_class(klass, n=n) self.training_frames.extend(frames) # Keep a reference to them for f in frames: yield f def get_data_from_frame(self, frame): return frame