Esempio n. 1
0
def find_offset_range(video_filenames, folder, offset, cut_off_end=2.0):
    """
    Find frame & time ranges where to clip provided video files based on specified offset & cut-off.
    """
    source_videos = []
    frame_durations = []
    frame_offsets = []
    ranges = []
    frame_rates = []
    ix_vid = 0

    for file_name in video_filenames:
        camera = Camera(os.path.join(folder, file_name))
        frame_durations.append(camera.frame_count)
        source_videos.append(camera)
        frame_offset = int(camera.fps * offset[ix_vid])
        frame_offsets.append(frame_offset)
        trim_frames = int(camera.fps * cut_off_end)
        frame_rates.append(camera.fps)
        ranges.append((frame_offset, camera.frame_count - trim_frames))
        del camera  # explicitly release video file
        ix_vid += 1

    return __sync_ranges(frame_durations, frame_rates, ranges, frame_offsets)
Esempio n. 2
0
    def __init__(self, args):
        """
        Base constructor
        """
        self.args = args

        self.aux_data_file = {}
        # load or initialize auxiliary data
        if args.aux_data_file is not None:
            self.aux_data_path = os.path.join(self.args.folder,
                                              self.args.aux_data_file)
            if osp.isfile(self.aux_data_path):
                npz_archive = np.load(osp.join(args.folder,
                                               args.aux_data_file))
                # convert to dict
                for key in npz_archive:
                    self.aux_data_file[key] = npz_archive[key]

        # set up board (3D object points of checkerboard used for calibration)
        self.object_points = []
        self.board_dims = (args.board_width, args.board_height)
        self.board_object_corner_set = np.zeros(
            (args.board_height * args.board_width, 1, 3), np.float32)
        self.board_object_corner_set[:, :, :2] = np.indices(
            self.board_dims).T.reshape(-1, 1, 2)
        self.board_object_corner_set *= args.board_square_size

        self.pixel_difference_factor = 1.0 / (self.board_dims[0] *
                                              self.board_dims[1] * 3 * 256.0)

        # some vars set to default
        self.criteria_subpix = (cv2.TERM_CRITERIA_EPS +
                                cv2.TERM_CRITERIA_MAX_ITER, 40, 0.001)

        if args.output is None:
            args.output = "intrinsics{0:s}.xml".format(
                re.sub(r"-|:", "",
                       str(datetime.datetime.now())[:-7]).replace(" ", "-"))

        self.videos = [
            Video(os.path.join(args.folder, video_filename))
            for video_filename in args.videos
        ]
        if args.input_calibration is not None:
            intrinsic_arr = []
            # load calibration files
            initial_calibration = []
            for calib_file in args.input_calibration:
                initial_calibration.append(
                    load_opencv_calibration(
                        os.path.join(args.folder, calib_file)))

            for calibration_info in initial_calibration:
                if type(calibration_info) == MultiStereoRig:
                    for rig in calibration_info.rigs:
                        for camera in rig.cameras:
                            intrinsic_arr.append(camera.intrinsics)
                elif type(calibration_info) == Rig:
                    for camera in calibration_info.cameras:
                        intrinsic_arr.append(camera.intrinsics)
                elif type(calibration_info) == Camera:
                    intrinsic_arr.append(calibration_info.intrinsics)
                elif type(calibration_info) == Camera.Intrinsics:
                    intrinsic_arr.append(calibration_info)
                else:
                    raise RuntimeError("Unsupported calibration file format.")

            if len(intrinsic_arr) != len(args.videos):
                raise ValueError(
                    "The total number of intrinsics in all the provided input calibration files "
                    +
                    "combined ({:d}) does not equal the total number provided of video file paths ({:d})."
                    + "These numbers must match.".format(
                        len(intrinsic_arr), len(args.videos)))

            self.cameras = [
                Camera(intrinsics=intrinsics) for intrinsics in intrinsic_arr
            ]
            if len(initial_calibration) == 1 and (
                    type(initial_calibration[0]) == Rig
                    or type(initial_calibration[0]) == MultiStereoRig):
                self.rig = initial_calibration[0]
            else:
                self.rig = Rig(tuple(self.cameras))
        else:
            self.cameras = [
                Camera(resolution=video.frame_dims) for video in self.videos
            ]
            self.rig = Rig(tuple(self.cameras))
Esempio n. 3
0
def find_calibration_conversion_range(video_filenames,
                                      folder,
                                      offset,
                                      board_dims,
                                      seek_time_interval=1.0,
                                      cut_off_end=20.0,
                                      verbose=True):
    """
    Find ranges where to clip the videos for calibration, i.e. the first frame where the calibration
    board appears and the last, as constrained by provided offset between the videos, the
    specified cut-off at the end (in seconds), and the seek interval (in seconds).
    @type video_filenames: list[str]
    @param video_filenames: names of the video files
    @type folder: str
    @param folder: path of the folder where the video files reside
    @type board_dims: tuple[int]
    @param board_dims: dimensions of the calibration board
    @type offset: list[int]
    @param offset: time offset, in frames, from the first video
    @type seek_time_interval: float
    @param seek_time_interval: time interval in seconds
    @type cut_off_end: float
    @param cut_off_end: how much (minimum) to cut off the end of both videos (seconds)
    @type verbose: bool
    @param verbose: whether to print progress & results to standard output
    @rtype: list[tuple[int]]
    @return proper ranges to clip the videos for calibration.
    """
    source_videos = []
    for file_name in video_filenames:
        camera = Camera(os.path.join(folder, file_name))
        source_videos.append(camera)

    ix_vid = 0
    ranges = []
    frame_offsets = []
    frame_durations = []
    frame_rates = []
    for camera in source_videos:
        frame_durations.append(camera.frame_count)
        frame_offset = int(camera.fps * offset[camera.index])
        frame_offsets.append(frame_offset)
        frame_rates.append(camera.fps)

        i_frame = frame_offset
        camera.scroll_to_frame(i_frame)
        camera.read_next_frame()
        skip_interval = int(seek_time_interval * camera.fps)

        # find the first frame with corners past the offset mark
        cont_cap = True
        if verbose:
            print("Seeking first frame of {0:s} usable for calibration...".
                  format(camera.name))
        while cont_cap:
            found_corners = camera.try_approximate_corners(board_dims)
            i_frame += skip_interval
            camera.scroll_to_frame(i_frame)
            if i_frame > (camera.frame_count - 1):
                camera.more_frames_remain = False
                break
            camera.read_next_frame()
            cont_cap = camera.more_frames_remain and not found_corners
            if verbose:
                print('.', end="", flush=True)

        if not camera.more_frames_remain:
            raise ValueError(
                "Could not find a frame in the video containing the checkerboard!"
            )

        start_frame = i_frame

        if verbose:
            print("\nFound at frame {0:d} ({1:.3f} s).".format(
                start_frame, start_frame / camera.fps))

        # find the last frame with corners
        i_frame = camera.frame_count - 1 - int(camera.fps * cut_off_end)
        camera.scroll_to_frame(i_frame)
        camera.read_next_frame()
        found_corners = False
        if verbose:
            print("Seeking last usable frame of {0:s}...".format(camera.name))
        while not found_corners:
            found_corners = camera.try_approximate_corners(board_dims)
            i_frame -= skip_interval
            camera.scroll_to_frame(i_frame)
            camera.read_next_frame()
            if verbose:
                print('.', end="", flush=True)
        # add one for exclusive right bound
        end_frame = i_frame + 1

        if verbose:
            print("\nFound at frame {0:d} ({1:.3f} s).".format(
                end_frame, end_frame / camera.fps))

        del camera  # explicitly release video file

        ranges.append((start_frame, end_frame))
        ix_vid += 1

    return __sync_ranges(frame_durations, frame_rates, ranges, frame_offsets)