Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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()
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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
Exemplo n.º 9
0
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
Exemplo n.º 10
0
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()
Exemplo n.º 11
0
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
Exemplo n.º 12
0
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