def create_and_start_new_recording(self, trial_name): self.recording = VideoRecording( '{0}_{1}.avi'.format(trial_name, self.name), '{0}_{1}_metadata.dat'.format(trial_name, self.name), self.get_resolution(), frames_per_second, 'XVID', color=False) self.recordingThread = QtCore.QThread(parent=self) self.recording.moveToThread(self.recordingThread) self.recordingThread.start() self.connect(self, QtCore.SIGNAL("NewFrame(PyQt_PyObject)"), self.recording.write)
def new_recording(self, save_dir, file_counter, framerate=0): if not self.triggered: framerate = self.framerate self.recording = VideoRecording(self, save_dir, file_counter, self.get_resolution(), framerate) if not self.recording.isOpened(): error = 'Video-recording could not be started.' self.emit(QtCore.SIGNAL('Raise Error (PyQt_PyObject)'), error) return False self.recordingThread = QtCore.QThread() self.recording.moveToThread(self.recordingThread) self.recordingThread.start() self.connect(self, QtCore.SIGNAL("NewFrame"), self.recording.write)
def new_recording(self, save_dir, file_counter, framerate=0): if not self.triggered: framerate = self.framerate self.recording = VideoRecording(self, save_dir, file_counter, self.get_resolution(), framerate) if not self.recording.isOpened(): error = 'Video-recording could not be started.' self.sig_raise_error.emit(error) return False self.recordingThread = QtCore.QThread() self.recording.moveToThread(self.recordingThread) self.recordingThread.start() self.sig_start_rec.connect(self.recording.start_rec) self.sig_start_rec.emit()
def create_and_start_new_videorecordings(self): # @jan: could choose potentially from PIM1, MJPG, MP42, DIV3, DIVX, U263, I263, FLV1 # works @ mac: MJPG/.avi # works @ mac: mp4v/.mp4 # # CV_FOURCC('P','I','M','1') = MPEG-1 codec if self.trial_counter == 0: self.check_data_dir() trial_name = '{0:s}/trial_{1:04d}'.format(self.data_dir, self.trial_counter) self.tags = list() self.video_recordings = OrderedDict() # self.video_recordings = {cam_name: (VideoRecording('{0}_{1}.mp4'.format(trial_name, cam_name), # '{0}_{1}_metadata.dat'.format(trial_name, cam_name), # cam.get_resolution(), # frames_per_second, # 'mp4v', # color=True) # if not cam.is_raspicam() else # RasPiVideoRecording('{0}_{1}.h264'.format(trial_name, cam_name), # '{0}_{1}_metadata.dat'.format(trial_name, cam_name), # 'h264', # self.cameras[cam_name])) # for cam_name, cam in self.cameras.items()} """ Ordered dict instead of normal dict to keep cameras in the same order""" for cam_name, cam in self.cameras.items(): if cam.is_raspicam(): self.video_recordings[cam_name] = RasPiVideoRecording( '{0}_{1}.h264'.format(trial_name, cam_name), '{0}_{1}_metadata.dat'.format(trial_name, cam_name), 'h264', self.cameras[cam_name]) else: self.video_recordings[cam_name] = VideoRecording( '{0}_{1}.avi'.format(trial_name, cam_name), '{0}_{1}_metadata.dat'.format(trial_name, cam_name), cam.get_resolution(), frames_per_second, 'MJPG', color=True) print(self.video_recordings) """ drop timestamp for start or recording """ trial_info_filename = '{0:s}/trial_{1:04d}_info.dat'.format( self.data_dir, self.trial_counter) self.start_time = datetime.now() timestamp = self.start_time.strftime("%Y-%m-%d %H:%M:%S:%f")[:-3] with open(trial_info_filename, 'w') as f: f.write("start-time:" + "\t" + timestamp + "\n") """ display start time """ time_label = 'start-time: {0:s} --- running: {1:s}'.format( timestamp, str(datetime.now() - self.start_time)[:-7]) self.label_time.setText(time_label)
def create_and_start_new_recording(self, trial_name): self.recording = VideoRecording('{0}_{1}.avi'.format(trial_name, self.name), '{0}_{1}_metadata.dat'.format(trial_name, self.name), self.get_resolution(), frames_per_second, 'XVID', color=False) self.recordingThread = QtCore.QThread(parent=self) self.recording.moveToThread(self.recordingThread) self.recordingThread.start() self.connect(self, QtCore.SIGNAL("NewFrame(PyQt_PyObject)"), self.recording.write)
def new_recording(self, save_dir, cam_name, file_counter, framerate=0): if not self.triggered: # framerate = self.framerate try: framerate = self.get_dispframe()[2] ## get real frame rate to encoder except: framerate = self.framerate print('FPS was not successfully read out and set') self.recording = VideoRecording(self, save_dir, cam_name, file_counter, self.get_resolution(), framerate, color=self.color) pass if not self.recording.isOpened(): error = 'Video-recording could not be started.' self.sig_raise_error.emit(error) return False self.recordingThread = QtCore.QThread() self.recording.moveToThread(self.recordingThread) self.recordingThread.start() self.sig_new_frame.connect(self.recording.write)
class Camera(QtCore.QObject): def __init__(self, device_no=0, post_processor=None, parent=None): """ Initializes a new camera :param post_processor: function that is applies to the frame after grabbing """ QtCore.QObject.__init__(self, parent) self.capture = None self.device_no = device_no self.name = None self.recording = None self.post_processor = post_processor if post_processor is None: self.post_processor = lambda x, y, z: (x, y, z) # DEBUG # self.last_frame = datetime.now() # self.min = 1000. self.open() # create timer for independent frame acquisition self.timer = QtCore.QTimer() self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.grab_frame) def __enter__(self): self.open() return self def __exit__(self, type, value, traceback): self.close() def open(self): capture = cv2.VideoCapture(self.device_no) self.capture = capture # try to increase the resolution of the frame capture; default is 640x480 #~ self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 864) #~ self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 480) self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 1280) self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 720) def is_working(self): return self.capture.isOpened() def get_properties(self): """ :returns: the properties (cv2.cv.CV_CAP_PROP_*) from the camera :rtype: dict """ if self.capture is not None: properties = [e for e in dir(cv2.cv) if "CV_CAP_PROP" in e] ret = {} for e in properties: ret[e[12:].lower()] = self.capture.get(getattr(cv2.cv, e)) return ret else: warnings.warn("Camera needs to be opened first!") return None def get_resolution(self): if self.capture is not None: return int(self.capture.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)), \ int(self.capture.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)) else: raise ValueError( "Camera is not opened or not functional! Capture is None") def grab_frame(self): flag, frame = self.capture.read() dtime = datetime.now() # post-processing if self.color: frame = brg2rgb(frame) else: frame = brg2grayscale(frame) # DEBUG # gap = 1000.*(dtime - self.last_frame).total_seconds() # if self.min > gap: # self.min = gap # sys.stdout.write('\rframerate: {0:3.2f} ms{1:s}; min:{2:3.2f}'.format(gap, 5*' ', self.min,5*' ')) # sys.stdout.flush() # self.last_frame = dtime if not flag: warnings.warn("Coulnd't grab frame from camera!") return None # emit signal with frame and dtime self.emit(QtCore.SIGNAL("NewFrame(PyQt_PyObject)"), self.post_processor(self.name, frame, dtime)) def create_and_start_new_recording(self, trial_name): self.recording = VideoRecording( '{0}_{1}.avi'.format(trial_name, self.name), '{0}_{1}_metadata.dat'.format(trial_name, self.name), self.get_resolution(), frames_per_second, 'XVID', color=False) self.recordingThread = QtCore.QThread(parent=self) self.recording.moveToThread(self.recordingThread) self.recordingThread.start() self.connect(self, QtCore.SIGNAL("NewFrame(PyQt_PyObject)"), self.recording.write) def start_capture(self): self.timer.start(5) # 5 msec def stop_capture(self): self.timer.stop() def stop_recording(self): self.recordingThread.quit() self.recordingThread.wait() self.recording = None self.recordingThread = None def close(self): pass
class Camera(QtCore.QObject): # signals sig_start_rec = pyqtSignal() sig_set_timestamp = pyqtSignal(object) sig_raise_error = pyqtSignal(object) def __init__(self, control, device_no=0, post_processor=None, parent=None): """ Initializes a new camera :param post_processor: function that is applies to the frame after grabbing """ QtCore.QObject.__init__(self, parent) self.mutex = QtCore.QMutex() self.control = control self.filename = 'video' self.framerate = 30. self.triggered = False self.capture = None self.device_no = device_no self.name = None self.recording = None self.post_processor = post_processor if post_processor is None: self.post_processor = lambda *args: args self.saving = False self.frame_dts = deque() self.recframes = deque() self.dispframe = None self.x_resolution = 800 self.y_resolution = 800 # self.open() # create timer for independent frame acquisition # self.timer = QtCore.QTimer() # self.timer.timeout.connect(self.grab_frame) self.sig_set_timestamp.connect(self.control.set_timestamp) self.sig_raise_error.connect(self.control.raise_error) def __exit__(self, type, value, traceback): self.close() def is_working(self): return True def get_resolution(self): return self.x_resolution, self.y_resolution def get_dispframe(self): self.mutex.lock() dispframe = self.dispframe self.mutex.unlock() self.dispframe = None return dispframe def get_recframe(self): if len(self.recframes): self.mutex.lock() recframe = self.recframes.popleft() self.mutex.unlock() return recframe else: return None def get_recframesize(self): self.mutex.lock() s = len(self.recframes) # print(len(self.recframes)) self.mutex.unlock() return s def grab_frame(self, saving=False): QtCore.QThread.msleep(int(1000. / self.framerate)) # grab frame frame = (np.random.random(self.y_resolution * self.x_resolution) * 255).reshape((self.y_resolution, self.x_resolution)) frame = np.require(frame, np.uint8, 'C') dtime = datetime.now() # calculate framerate self.frame_dts.append(dtime) if len(self.frame_dts) > 100: self.frame_dts.popleft() if len(self.frame_dts) > 1: dur = (self.frame_dts[-1] - self.frame_dts[0]).total_seconds() fr = len(self.frame_dts) / dur if dur > 0 else 0 else: fr = 0 # store frames for other threads self.mutex.lock() self.dispframe = (frame, dtime, fr) self.mutex.unlock() if self.is_saving(): self.mutex.lock() dtime = '{:.10f}\n'.format( date2num(dtime)) # change datetime format to float self.recframes.append((frame, dtime)) self.mutex.unlock() # emit signal for recording thread # self.sig_new_frame.emit() # self.emit(QtCore.SIGNAL("NewFrame")) def new_recording(self, save_dir, file_counter, framerate=0): if not self.triggered: framerate = self.framerate self.recording = VideoRecording(self, save_dir, file_counter, self.get_resolution(), framerate) if not self.recording.isOpened(): error = 'Video-recording could not be started.' self.sig_raise_error.emit(error) return False self.recordingThread = QtCore.QThread() self.recording.moveToThread(self.recordingThread) self.recordingThread.start() self.sig_start_rec.connect(self.recording.start_rec) self.sig_start_rec.emit() def is_recording(self): self.mutex.lock() c = self.continuous self.mutex.unlock() return c def is_saving(self): self.mutex.lock() sav = self.saving self.mutex.unlock() return sav def stop_capture(self): self.mutex.lock() self.continuous = False self.mutex.unlock() def start_capture(self): """ for continuous frame acquisition """ print('video capture started') self.continuous = True while self.is_recording(): self.grab_frame() # def stop_capture(self): # self.timer.stop() def start_saving(self): self.mutex.lock() self.saving = True self.mutex.unlock() def stop_saving(self): self.mutex.lock() self.saving = False # self.disconnect(self, QtCore.SIGNAL("NewFrame"), self.recording.write) self.mutex.unlock() # last = self.recording.get_write_count() # double_counter = -1 # while self.get_recframesize() > 0: # if self.triggered: # total = triggered_frames # else: # total = self.recording.get_write_count() + self.get_recframesize() # print('Writing: {} of {}'.format(self.get_recframesize(), total)) # if last == self.recording.get_write_count(): double_counter += 1 # if double_counter == 10: # error = 'Frames cannot be saved.' # self.sig_raise_error.emit(error) # # self.emit(QtCore.SIGNAL('Raise Error (PyQt_PyObject)'), error) # break # QtCore.QThread.msleep(100) self.recording.stop_recording() # reset self.recframes = deque() # wait until all frames are written, then close the recording # if triggered_frames == self.recording.get_write_count(): timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") s = timestamp + ' \t ' + 'Frames written: ' if self.control.cfg['trigger'] is None: s += '{}'.format(self.recording.get_write_count()) else: # debug: triggered_frames = 0 s += '{} of {}'.format(self.recording.get_write_count(), triggered_frames) self.sig_set_timestamp.emit(s) self.recording.release() self.recordingThread.quit() self.recordingThread.wait() self.recording = None self.recordingThread = None def close(self): # release camera pass
class Camera(QtCore.QObject): # signals sig_new_frame = pyqtSignal() sig_start_rec = pyqtSignal() sig_set_timestamp = pyqtSignal(object) sig_raise_error = pyqtSignal(object) def __init__(self, control, device_no=0, color=False, post_processor=None, parent=None): """ Initializes a new camera :param post_processor: function that is applies to the frame after grabbing """ QtCore.QObject.__init__(self, parent) self.mutex = QtCore.QMutex() self.control = control self.filename = 'video' self.framerate = 30. self.triggered = False self.color = control.color self.capture = None self.device_no = device_no self.name = None self.recording = None self.post_processor = post_processor if post_processor is None: self.post_processor = lambda *args: args # self.width = 1280 # self.height = 720 # self.timer = QtCore.QTimer() self.saving = False self.frame_dts = deque() self.recframes = deque() self.dispframe = None self.open() self.empty_frame = np.zeros((np.int(self.height), np.int(self.width), np.int(3))) self.sig_set_timestamp.connect(self.control.set_timestamp) self.sig_raise_error.connect(self.control.raise_error) self def __enter__(self): self.open() return self def __exit__(self, type, value, traceback): self.close() def open(self): # capture = cv2.VideoCapture(self.device_no) # self.capture = capture self.capture = cv2.VideoCapture(self.device_no) # try to increase the resolution of the frame capture; default is 640x480 # ~ self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 864) # ~ self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 480) # TODO: fix arbitrary camera sizes # self.capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) # self.capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) # self.capture.set(cv2.CAP_PROP_FRAME_WIDTH, 320) # self.capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 200) self.capture.set(cv2.CAP_PROP_FPS, int(self.framerate)) # self.capture.set(5, 60) self.width = self.capture.get(cv2.CAP_PROP_FRAME_WIDTH) self.height = self.capture.get(cv2.CAP_PROP_FRAME_HEIGHT) self.capture.set(cv2.CAP_PROP_AUTOFOCUS, 0) def is_working(self): return self.capture.isOpened() def get_properties(self): """ :returns: the properties (cv2.CAP_PROP_*) from the camera :rtype: dict """ if self.capture is not None: properties = [e for e in dir(cv2) if "CAP_PROP" in e] ret = {} for e in properties: ret[e[12:].lower()] = self.capture.get(getattr(cv2, e)) return ret else: warnings.warn("Camera needs to be opened first!") return None def get_resolution(self): if self.capture is not None: return int(self.capture.get(cv2.CAP_PROP_FRAME_WIDTH)), \ int(self.capture.get(cv2.CAP_PROP_FRAME_HEIGHT)) else: raise ValueError("Camera is not opened or not functional! Capture is None") def get_fps(self): if self.capture is not None: return int(self.capture.get(cv2.CAP_PROP_FPS)) else: raise ValueError("Camera is not opened yet") def get_dispframe(self): self.mutex.lock() dispframe = self.dispframe self.mutex.unlock() self.dispframe = None return dispframe def get_recframe(self): self.mutex.lock() if len(self.recframes): recframe = self.recframes.popleft() # print(len(self.recframes)) self.mutex.unlock() return recframe else: self.mutex.unlock() return None def get_recframesize(self): self.mutex.lock() s = len(self.recframes) # print(len(self.recframes)) self.mutex.unlock() return s def grab_frame(self, saving=False): # grab frame flag, frame = self.capture.read() dtime = datetime.now() # calculate framerate self.frame_dts.append(dtime) if len(self.frame_dts) > 100: self.frame_dts.popleft() if len(self.frame_dts) > 1: dur = (self.frame_dts[-1] - self.frame_dts[0]).total_seconds() fr = len(self.frame_dts) / dur if dur > 0 else 0 else: fr = 0 # post-processing try: if self.color: frame = brg2rgb(frame) else: frame = brg2grayscale(frame) except: if self.color: frame = self.empty_frame else: frame = self.empty_frame[:, :, 0] # DEBUG # gap = 1000.*(dtime - self.last_frame).total_seconds() # if self.min > gap: # self.min = gap # sys.stdout.write('\rframerate: {0:3.2f} ms{1:s}; min:{2:3.2f}'.format(gap, 5*' ', self.min,5*' ')) # sys.stdout.flush() # self.last_frame = dtime if not flag: warnings.warn("Couldn't grab frame from camera!") return None # store frames for other threads self.mutex.lock() self.dispframe = (frame, dtime, fr) self.mutex.unlock() if self.is_saving(): self.mutex.lock() dtime = '{:.10f}\n'.format(date2num(dtime)) # change datetime format to float self.recframes.append((frame, dtime)) self.mutex.unlock() # emit signal for recording thread self.sig_new_frame.emit() def new_recording(self, save_dir, cam_name, file_counter, framerate=0): if not self.triggered: # framerate = self.framerate try: framerate = self.get_dispframe()[2] ## get real frame rate to encoder except: framerate = self.framerate print('FPS was not successfully read out and set') self.recording = VideoRecording(self, save_dir, cam_name, file_counter, self.get_resolution(), framerate, color=self.color) pass if not self.recording.isOpened(): error = 'Video-recording could not be started.' self.sig_raise_error.emit(error) return False self.recordingThread = QtCore.QThread() self.recording.moveToThread(self.recordingThread) self.recordingThread.start() self.sig_new_frame.connect(self.recording.write) def is_recording(self): self.mutex.lock() c = self.continuous self.mutex.unlock() return c def is_saving(self): self.mutex.lock() sav = self.saving self.mutex.unlock() return sav def stop_recording(self): self.mutex.lock() self.continuous = False self.mutex.unlock() def start_capture(self): """ for continuous frame acquisition """ self.continuous = True while self.is_recording(): self.grab_frame() def stop_capture(self): self.mutex.lock() self.continuous = False self.mutex.unlock() def start_saving(self): self.mutex.lock() self.saving = True self.mutex.unlock() # def stop_saving(self, triggered_frames): def stop_saving(self): self.mutex.lock() self.saving = False self.sig_new_frame.disconnect(self.recording.write) self.mutex.unlock() last = self.recording.get_write_count() double_counter = -1 #TODO: fix triggered frames properly triggered_frames = 0 while self.get_recframesize() > 0: print('Writing: {} of {}'.format(self.recording.get_write_count(), triggered_frames)) print(self.get_recframesize()) if last == self.recording.get_write_count(): double_counter += 1 if double_counter == 10: error = 'Frames cannot be saved.' self.sig_raise_error.emit(error) break QtCore.QThread.msleep(100) # wait until all frames are written, then close the recording # if triggered_frames == self.recording.get_write_count(): timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") s = timestamp + ' \t ' + 'All frames written: ' s += '{} of {}'.format(self.recording.get_write_count(), triggered_frames) self.sig_set_timestamp.emit(s) self.recording.release() self.recordingThread.quit() self.recordingThread.wait() self.recording = None self.recordingThread = None def close(self): # release camera self.capture.release() pass
class Camera(QtCore.QObject): # signals # sig_new_frame = pyqtSignal() sig_startrec = pyqtSignal() sig_set_timestamp = pyqtSignal(object) sig_raise_error = pyqtSignal(object) def __init__(self, control, device_no=0, fast_and_small_video=False, triggered=False, post_processor=None, parent=None): """ Initializes a new camera :param post_processor: function that is applies to the frame after grabbing """ QtCore.QObject.__init__(self, parent) self.control = control self.fast_and_small_video = fast_and_small_video self.triggered = triggered self.mutex = QtCore.QMutex() self.filename = 'video' self.context = None self.device_no = device_no self.name = None self.post_processor = post_processor if post_processor is None: self.post_processor = lambda *args: args self.saving = False self.frame_dts = deque() self.mode = 0 self.frame_dts = deque() self.recframes = deque() self.dispframe = None self.open() self.sig_set_timestamp.connect(control.set_timestamp) self.sig_raise_error.connect(control.raise_error) # self.connect(self, QtCore.SIGNAL('set timestamp (PyQt_PyObject)'), control.set_timestamp) # self.connect(self, QtCore.SIGNAL('Raise Error (PyQt_PyObject)'), control.raise_error) # def start_capture(self): # if not self.triggered: # QtCore.QTimer().singleShot( 1000, self.continuous_framegrab ) def open(self): self.context = fc2.Context() self.context.connect( *self.context.get_camera_from_index(self.device_no)) # self.reset_camera() if self.fast_and_small_video: width, height = self.set_resolution(3 * 480, 3 * 480) self.framerate = framerate_focus else: self.framerate = framerate_full self.set_resolution() # maximize resolution if self.triggered: self.set_software_trigger() print('Framerate set to: {:.1f} Hz'.format(self.framerate)) self.context.start_capture() self.im = fc2.Image() def set_software_trigger(self): # set camera to software trigger ## source = 7 indicates software trigger self.context.set_trigger_mode(True, 0, 7, 0, 0) def get_resolution(self): if self.context is not None: f7config = self.context.get_format7_configuration() return f7config['height'], f7config['width'] else: raise ValueError("Camera is not opened or not functional!") def get_resolution_params(self): form = self.context.get_format7_info(self.mode)[0] wsteps = form['image_h_step_size'] hsteps = form['image_v_step_size'] max_w = form['max_width'] max_h = form['max_height'] return wsteps, hsteps, max_w, max_h def set_resolution(self, w=0, h=0): ws, hs, mw, mh = self.get_resolution_params() w = mw if w == 0 else w h = mh if h == 0 else h # make sure new resolution fits the requirements wi = int(w / ws) # devide by stepsize to get a multiplicator hi = int(h / hs) w = min( [wi * ws, mw] ) # the use the multiplicator to get a valid value that is lower than the maximum value h = min([hi * hs, mh]) f7config = self.context.get_format7_configuration() if w == 0 and h == 0: f7config['height'] = mh f7config['width'] = mw else: f7config['height'] = h f7config['width'] = w # center new ROI off_w = max([(mw - w) / 2, 0]) f7config['offset_x'] = off_w if off_w % 2 == 0 else off_w - 1 off_h = max([(mh - h) / 2, 0]) f7config['offset_y'] = off_h if off_h % 2 == 0 else off_h - 1 self.context.set_format7_configuration( f7config['mode'], f7config['offset_x'], f7config['offset_y'], f7config['width'], f7config['height'], f7config['pixel_format']) print('Resolution set to: {}, {}'.format(f7config['width'], f7config['height'])) return w, h def set_exposure(self): pass def set_gain(self): pass def set_framerate(self, val=22): p = self.context.get_property(fc2.FRAME_RATE) p['abs_value'] = val p['auto_manual_mode'] = False self.context.set_property(p['type'], p['present'], p['on_off'], p['auto_manual_mode'], p['abs_control'], p['one_push'], p['abs_value'], p['value_a'], p['value_b']) def reset_camera(self): # reset to maximum resolution ws, hs, mw, mh = self.get_resolution_params() f7config = self.context.get_format7_configuration() f7config['width'] = mw f7config['height'] = mh self.context.set_format7_configuration( f7config['mode'], f7config['offset_x'], f7config['offset_y'], f7config['width'], f7config['height'], f7config['pixel_format']) # reset framerate to automatic p = self.context.get_property(fc2.FRAME_RATE) p['auto_manual_mode'] = True self.context.set_property(p['type'], p['present'], p['on_off'], p['auto_manual_mode'], p['abs_control'], p['one_push'], p['abs_value'], p['value_a'], p['value_b']) def get_dispframe(self): self.mutex.lock() dispframe = self.dispframe self.mutex.unlock() # self.dispframe = None return dispframe def get_recframe(self): if len(self.recframes): self.mutex.lock() recframe = self.recframes.popleft() # print(len(self.recframes)) self.mutex.unlock() return recframe else: return None def get_recframesize(self): self.mutex.lock() s = len(self.recframes) # print(len(self.recframes)) self.mutex.unlock() return s def grab_frame(self, saving=False): # print('cam grab'+str(QtCore.QThread.currentThread())) # triggered frame grab: update buffer # if self.triggered: # ret = self.context.fire_software_trigger() try: # print('grabbing frame') frame = np.array(self.context.retrieve_buffer(self.im)) # print('grabbed frame') except fc2.ApiError: print('camera grab frame failed') # add timestamp return dtime = datetime.now() # store frames for other threads # calculate framerate self.frame_dts.append(datetime.now()) if len(self.frame_dts) > 100: self.frame_dts.popleft() if len(self.frame_dts) > 1: dur = (self.frame_dts[-1] - self.frame_dts[0]).total_seconds() fr = len(self.frame_dts) / dur if dur > 0 else 0 else: fr = 0 self.mutex.lock() self.dispframe = (frame, dtime, fr) self.mutex.unlock() if self.is_saving(): self.mutex.lock() dtime = '{:.10f}\n'.format( date2num(dtime)) # change datetime format to float self.recframes.append((frame, dtime)) self.mutex.unlock() # emit signal for recording thread # self.emit(QtCore.SIGNAL("NewFrame")) # store frames for other threads def is_recording(self): self.mutex.lock() c = self.continuous self.mutex.unlock() return c def stop_capture(self): self.mutex.lock() print('stopped camera') self.continuous = False self.mutex.unlock() def start_capture(self): """ for continuous frame acquisition """ self.continuous = True self.set_framerate(self.framerate) while self.is_recording(): self.grab_frame() def new_recording(self, save_dir, file_counter, framerate=0): if not self.triggered: framerate = self.framerate self.recording = VideoRecording(self, save_dir, file_counter, self.get_resolution(), framerate) if not self.recording.isOpened(): error = 'Video-recording could not be started.' self.sig_raise_error.emit(error) # self.emit(QtCore.SIGNAL('Raise Error (PyQt_PyObject)'), error) return False self.recordingThread = QtCore.QThread() self.recording.moveToThread(self.recordingThread) self.recordingThread.start() # self.connect(self, QtCore.SIGNAL("StartRec"), self.recording.start_rec) self.sig_startrec.connect(self.recording.start_rec) self.sig_startrec.emit() def is_saving(self): self.mutex.lock() sav = self.saving self.mutex.unlock() return sav def start_saving(self): self.mutex.lock() self.saving = True self.mutex.unlock() def stop_saving(self): self.mutex.lock() self.saving = False # self.disconnect(self, QtCore.SIGNAL("NewFrame"), self.recording.write) self.mutex.unlock() # last = self.recording.get_write_count() # double_counter = -1 # while self.get_recframesize() > 0: # if self.triggered: # total = triggered_frames # else: # total = self.recording.get_write_count() + self.get_recframesize() # print('Writing: {} of {}'.format(self.get_recframesize(), total)) # if last == self.recording.get_write_count(): double_counter += 1 # if double_counter == 10: # error = 'Frames cannot be saved.' # self.sig_raise_error.emit(error) # # self.emit(QtCore.SIGNAL('Raise Error (PyQt_PyObject)'), error) # break # QtCore.QThread.msleep(100) self.recording.stop_recording() # reset self.recframes = deque() # wait until all frames are written, then close the recording # if triggered_frames == self.recording.get_write_count(): timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") s = timestamp + ' \t ' + 'Frames written: ' if self.control.cfg['trigger'] is None: s += '{}'.format(self.recording.get_write_count()) else: # debug: triggered_frames = 0 s += '{} of {}'.format(self.recording.get_write_count(), triggered_frames) self.sig_set_timestamp.emit(s) self.recording.release() self.recordingThread.quit() self.recordingThread.wait() self.recording = None self.recordingThread = None def close(self): # release camera self.context.set_trigger_mode(False, 0, 7, 0, 0) self.context.stop_capture() self.context.disconnect()
class Camera(QtCore.QObject): def __init__(self, device_no=0, post_processor=None, parent=None): """ Initializes a new camera :param post_processor: function that is applies to the frame after grabbing """ QtCore.QObject.__init__(self, parent) self.capture = None self.device_no = device_no self.name = None self.recording = None self.post_processor = post_processor if post_processor is None: self.post_processor = lambda x, y, z: (x, y, z) # DEBUG # self.last_frame = datetime.now() # self.min = 1000. self.open() # create timer for independent frame acquisition self.timer = QtCore.QTimer() self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.grab_frame) def __enter__(self): self.open() return self def __exit__(self, type, value, traceback): self.close() def open(self): capture = cv2.VideoCapture(self.device_no) self.capture = capture # try to increase the resolution of the frame capture; default is 640x480 #~ self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 864) #~ self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 480) self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 1280) self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 720) def is_working(self): return self.capture.isOpened() def get_properties(self): """ :returns: the properties (cv2.cv.CV_CAP_PROP_*) from the camera :rtype: dict """ if self.capture is not None: properties = [e for e in dir(cv2.cv) if "CV_CAP_PROP" in e] ret = {} for e in properties: ret[e[12:].lower()] = self.capture.get(getattr(cv2.cv, e)) return ret else: warnings.warn("Camera needs to be opened first!") return None def get_resolution(self): if self.capture is not None: return int(self.capture.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)), \ int(self.capture.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)) else: raise ValueError("Camera is not opened or not functional! Capture is None") def grab_frame(self): flag, frame = self.capture.read() dtime = datetime.now() # post-processing if self.color: frame = brg2rgb(frame) else: frame = brg2grayscale(frame) # DEBUG # gap = 1000.*(dtime - self.last_frame).total_seconds() # if self.min > gap: # self.min = gap # sys.stdout.write('\rframerate: {0:3.2f} ms{1:s}; min:{2:3.2f}'.format(gap, 5*' ', self.min,5*' ')) # sys.stdout.flush() # self.last_frame = dtime if not flag: warnings.warn("Coulnd't grab frame from camera!") return None # emit signal with frame and dtime self.emit(QtCore.SIGNAL("NewFrame(PyQt_PyObject)"), self.post_processor(self.name, frame, dtime)) def create_and_start_new_recording(self, trial_name): self.recording = VideoRecording('{0}_{1}.avi'.format(trial_name, self.name), '{0}_{1}_metadata.dat'.format(trial_name, self.name), self.get_resolution(), frames_per_second, 'XVID', color=False) self.recordingThread = QtCore.QThread(parent=self) self.recording.moveToThread(self.recordingThread) self.recordingThread.start() self.connect(self, QtCore.SIGNAL("NewFrame(PyQt_PyObject)"), self.recording.write) def start_capture(self): self.timer.start(5) # 5 msec def stop_capture(self): self.timer.stop() def stop_recording(self): self.recordingThread.quit() self.recordingThread.wait() self.recording = None self.recordingThread = None def close(self): pass
class Camera(QtCore.QObject): def __init__(self, main, device_no=0, color=False, post_processor=None, parent=None): """ Initializes a new camera :param post_processor: function that is applies to the frame after grabbing """ QtCore.QObject.__init__(self, parent) self.mutex = QtCore.QMutex() self.main = main self.filename = 'video' self.framerate = 30. self.triggered = False self.color = color self.capture = None self.device_no = device_no self.name = None self.recording = None self.post_processor = post_processor if post_processor is None: self.post_processor = lambda *args: args self.saving = False self.frame_dts = deque() self.recframes = deque() self.dispframe = None self.open() # # create timer for independent frame acquisition # self.timer = QtCore.QTimer() # self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.grab_frame) self.connect(self, QtCore.SIGNAL('set timestamp (PyQt_PyObject)'), main.set_timestamp) self.connect(self, QtCore.SIGNAL('Raise Error (PyQt_PyObject)'), main.raise_error) def __enter__(self): self.open() return self def __exit__(self, type, value, traceback): self.close() def open(self): capture = cv2.VideoCapture(self.device_no) self.capture = capture # try to increase the resolution of the frame capture; default is 640x480 #~ self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 864) #~ self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 480) self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 1280) self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 720) def is_working(self): return self.capture.isOpened() def get_properties(self): """ :returns: the properties (cv2.cv.CV_CAP_PROP_*) from the camera :rtype: dict """ if self.capture is not None: properties = [e for e in dir(cv2.cv) if "CV_CAP_PROP" in e] ret = {} for e in properties: ret[e[12:].lower()] = self.capture.get(getattr(cv2.cv, e)) return ret else: warnings.warn("Camera needs to be opened first!") return None def get_resolution(self): if self.capture is not None: return int(self.capture.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)), \ int(self.capture.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)) else: raise ValueError( "Camera is not opened or not functional! Capture is None") def get_dispframe(self): self.mutex.lock() dispframe = self.dispframe self.mutex.unlock() self.dispframe = None return dispframe def get_recframe(self): self.mutex.lock() if len(self.recframes): recframe = self.recframes.popleft() # print(len(self.recframes)) self.mutex.unlock() return recframe else: self.mutex.unlock() return None def get_recframesize(self): self.mutex.lock() s = len(self.recframes) # print(len(self.recframes)) self.mutex.unlock() return s def grab_frame(self, saving=False): # grab frame flag, frame = self.capture.read() dtime = datetime.now() # calculate framerate self.frame_dts.append(dtime) if len(self.frame_dts) > 100: self.frame_dts.popleft() if len(self.frame_dts) > 1: dur = (self.frame_dts[-1] - self.frame_dts[0]).total_seconds() fr = len(self.frame_dts) / dur if dur > 0 else 0 else: fr = 0 # post-processing if self.color: frame = brg2rgb(frame) else: frame = brg2grayscale(frame) # DEBUG # gap = 1000.*(dtime - self.last_frame).total_seconds() # if self.min > gap: # self.min = gap # sys.stdout.write('\rframerate: {0:3.2f} ms{1:s}; min:{2:3.2f}'.format(gap, 5*' ', self.min,5*' ')) # sys.stdout.flush() # self.last_frame = dtime if not flag: warnings.warn("Coulnd't grab frame from camera!") return None # store frames for other threads self.mutex.lock() self.dispframe = (frame, dtime, fr) self.mutex.unlock() if self.is_saving(): self.mutex.lock() dtime = '{:.10f}\n'.format( date2num(dtime)) # change datetime format to float self.recframes.append((frame, dtime)) self.mutex.unlock() # emit signal for recording thread self.emit(QtCore.SIGNAL("NewFrame")) def new_recording(self, save_dir, file_counter, framerate=0): if not self.triggered: framerate = self.framerate self.recording = VideoRecording(self, save_dir, file_counter, self.get_resolution(), framerate) if not self.recording.isOpened(): error = 'Video-recording could not be started.' self.emit(QtCore.SIGNAL('Raise Error (PyQt_PyObject)'), error) return False self.recordingThread = QtCore.QThread() self.recording.moveToThread(self.recordingThread) self.recordingThread.start() self.connect(self, QtCore.SIGNAL("NewFrame"), self.recording.write) def is_recording(self): self.mutex.lock() c = self.continuous self.mutex.unlock() return c def is_saving(self): self.mutex.lock() sav = self.saving self.mutex.unlock() return sav def stop_recording(self): self.mutex.lock() self.continuous = False self.mutex.unlock() def start_capture(self): """ for continuous frame acquisition """ self.continuous = True while self.is_recording(): self.grab_frame() def start_saving(self): self.mutex.lock() self.saving = True self.mutex.unlock() def stop_saving(self, triggered_frames): self.mutex.lock() self.saving = False self.disconnect(self, QtCore.SIGNAL("NewFrame"), self.recording.write) self.mutex.unlock() last = self.recording.get_write_count() double_counter = -1 while self.get_recframesize() > 0: print('Writing: {} of {}'.format(self.recording.get_write_count(), triggered_frames)) print(self.get_recframesize()) if last == self.recording.get_write_count(): double_counter += 1 if double_counter == 10: error = 'Frames cannot be saved.' self.emit(QtCore.SIGNAL('Raise Error (PyQt_PyObject)'), error) break QtCore.QThread.msleep(100) # wait until all frames are written, then close the recording # if triggered_frames == self.recording.get_write_count(): timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") s = timestamp + ' \t ' + 'All frames written: ' s += '{} of {}'.format(self.recording.get_write_count(), triggered_frames) self.emit(QtCore.SIGNAL('set timestamp (PyQt_PyObject)'), s) self.recording.release() self.recordingThread.quit() self.recordingThread.wait() self.recording = None self.recordingThread = None def close(self): # release camera self.capture.release() pass