Esempio n. 1
0
class FrameMatchingValidationScreen(GuiBaseFrame):
    def __init__(self, parent, controller, **kw):
        GuiBaseFrame.__init__(self, parent, controller, **kw)
        self.left_video_filename = None
        self.right_video_filename = None
        self.video_frame_loader = None

        self.frame_num = 0

    def init_widgets(self):
        self.buttons = []
        self.content_wrapper = Frame(self)

        self.title_label = Header1Label(self.content_wrapper,
                                        text="Frame Offset Validation")
        self.subtitle_label = PLabel(
            self.content_wrapper,
            text=
            "Use the buttons below to ensure that the video frame offset is valid. Press Next when finished."
        )

        self.left_frame_num_label = PLabel(self.content_wrapper)
        self.right_frame_num_label = PLabel(self.content_wrapper)

        self.left_video_label = PLabel(self.content_wrapper)
        self.right_video_label = PLabel(self.content_wrapper)

        self.left_offset_label = PLabel(self.content_wrapper)
        self.right_offset_label = PLabel(self.content_wrapper)

        self.left_offset_inc_instr = PLabel(
            self.content_wrapper, text="Increase left video offset by:")
        self.right_offset_inc_instr = PLabel(
            self.content_wrapper, text="Increase right video offset by:")

        self.left_offset_inc_10_button = Button(
            self.content_wrapper,
            text="+10",
            command=lambda: self.adjust_left_offset(10))
        self.left_offset_inc_5_button = Button(
            self.content_wrapper,
            text="+5",
            command=lambda: self.adjust_left_offset(5))
        self.left_offset_inc_1_button = Button(
            self.content_wrapper,
            text="+1",
            command=lambda: self.adjust_left_offset(1))
        self.right_offset_inc_1_button = Button(
            self.content_wrapper,
            text="+1",
            command=lambda: self.adjust_right_offset(1))
        self.right_offset_inc_5_button = Button(
            self.content_wrapper,
            text="+5",
            command=lambda: self.adjust_right_offset(5))
        self.right_offset_inc_10_button = Button(
            self.content_wrapper,
            text="+10",
            command=lambda: self.adjust_right_offset(10))
        self.buttons.extend([
            self.left_offset_inc_10_button, self.left_offset_inc_5_button,
            self.left_offset_inc_1_button, self.right_offset_inc_1_button,
            self.right_offset_inc_5_button, self.right_offset_inc_10_button
        ])

        self.video_navigation_label = PLabel(self.content_wrapper,
                                             text="Video frame navigation:")

        self.left_video_frame_inc_10_button = Button(
            self.content_wrapper,
            text=BACK_10_FRAMEs_TEXT,
            command=lambda: self.adjust_frame_num(-10))
        self.left_video_frame_inc_5_button = Button(
            self.content_wrapper,
            text=BACK_5_FRAMEs_TEXT,
            command=lambda: self.adjust_frame_num(-5))
        self.left_video_frame_inc_1_button = Button(
            self.content_wrapper,
            text=BACK_1_FRAME_TEXT,
            command=lambda: self.adjust_frame_num(-1))
        self.right_video_frame_inc_1_button = Button(
            self.content_wrapper,
            text=FORWARD_1_FRAME_TEXT,
            command=lambda: self.adjust_frame_num(1))
        self.right_video_frame_inc_5_button = Button(
            self.content_wrapper,
            text=FORWARD_5_FRAMES_TEXT,
            command=lambda: self.adjust_frame_num(5))
        self.right_video_frame_inc_10_button = Button(
            self.content_wrapper,
            text=FORWARD_10_FRAMES_TEXT,
            command=lambda: self.adjust_frame_num(10))
        self.buttons.extend([
            self.left_video_frame_inc_10_button,
            self.left_video_frame_inc_5_button,
            self.left_video_frame_inc_1_button,
            self.right_video_frame_inc_1_button,
            self.right_video_frame_inc_5_button,
            self.right_video_frame_inc_10_button
        ])

        self.left_video_frame_inc_300_button = Button(
            self.content_wrapper,
            text=BACK_300_FRAMEs_TEXT,
            command=lambda: self.adjust_frame_num(-300))
        self.left_video_frame_inc_150_button = Button(
            self.content_wrapper,
            text=BACK_150_FRAMEs_TEXT,
            command=lambda: self.adjust_frame_num(-150))
        self.left_video_frame_inc_30_button = Button(
            self.content_wrapper,
            text=BACK_30_FRAMEs_TEXT,
            command=lambda: self.adjust_frame_num(-30))
        self.right_video_frame_inc_30_button = Button(
            self.content_wrapper,
            text=FORWARD_30_FRAMES_TEXT,
            command=lambda: self.adjust_frame_num(30))
        self.right_video_frame_inc_150_button = Button(
            self.content_wrapper,
            text=FORWARD_150_FRAMES_TEXT,
            command=lambda: self.adjust_frame_num(150))
        self.right_video_frame_inc_300_button = Button(
            self.content_wrapper,
            text=FORWARD_300_FRAMES_TEXT,
            command=lambda: self.adjust_frame_num(300))
        self.buttons.extend([
            self.left_video_frame_inc_300_button,
            self.left_video_frame_inc_150_button,
            self.left_video_frame_inc_30_button,
            self.right_video_frame_inc_30_button,
            self.right_video_frame_inc_150_button,
            self.right_video_frame_inc_300_button
        ])

        self.next_button = Button(
            self.content_wrapper,
            text="Next",
            command=lambda: self.controller.show_next_frame())

    def add_widgets_to_frame(self):
        self.title_label.grid(row=TITLE_ROW, column=0, columnspan=12)
        self.subtitle_label.grid(row=SUBTITLE_ROW, column=0, columnspan=12)

        self.left_frame_num_label.grid(row=FRAME_NUM_ROW,
                                       column=0,
                                       columnspan=6)
        self.right_frame_num_label.grid(row=FRAME_NUM_ROW,
                                        column=6,
                                        columnspan=6)

        self.left_video_label.grid(row=VIDEO_FRAMES_ROW,
                                   column=0,
                                   columnspan=6)
        self.right_video_label.grid(row=VIDEO_FRAMES_ROW,
                                    column=6,
                                    columnspan=6)

        self.left_offset_label.grid(row=OFFSET_INC_INSTR_ROW,
                                    column=0,
                                    columnspan=2)
        self.right_offset_label.grid(row=OFFSET_INC_INSTR_ROW,
                                     column=10,
                                     columnspan=2)

        self.left_offset_inc_instr.grid(row=OFFSET_INC_INSTR_ROW,
                                        column=3,
                                        columnspan=3)
        self.right_offset_inc_instr.grid(row=OFFSET_INC_INSTR_ROW,
                                         column=6,
                                         columnspan=3)

        self.left_offset_inc_10_button.grid(row=OFFSET_INC_BUTTONS, column=3)
        self.left_offset_inc_5_button.grid(row=OFFSET_INC_BUTTONS, column=4)
        self.left_offset_inc_1_button.grid(row=OFFSET_INC_BUTTONS, column=5)
        self.right_offset_inc_1_button.grid(row=OFFSET_INC_BUTTONS, column=6)
        self.right_offset_inc_5_button.grid(row=OFFSET_INC_BUTTONS, column=7)
        self.right_offset_inc_10_button.grid(row=OFFSET_INC_BUTTONS, column=8)

        self.video_navigation_label.grid(row=VIDEO_NAVIGATION_ROW,
                                         column=0,
                                         columnspan=12)

        self.left_video_frame_inc_10_button.grid(row=VIDEO_BUTTONS_ROW_1,
                                                 column=0,
                                                 columnspan=2)
        self.left_video_frame_inc_5_button.grid(row=VIDEO_BUTTONS_ROW_1,
                                                column=2,
                                                columnspan=2)
        self.left_video_frame_inc_1_button.grid(row=VIDEO_BUTTONS_ROW_1,
                                                column=4,
                                                columnspan=2)
        self.right_video_frame_inc_1_button.grid(row=VIDEO_BUTTONS_ROW_1,
                                                 column=6,
                                                 columnspan=2)
        self.right_video_frame_inc_5_button.grid(row=VIDEO_BUTTONS_ROW_1,
                                                 column=8,
                                                 columnspan=2)
        self.right_video_frame_inc_10_button.grid(row=VIDEO_BUTTONS_ROW_1,
                                                  column=10,
                                                  columnspan=2)

        self.left_video_frame_inc_300_button.grid(row=VIDEO_BUTTONS_ROW_2,
                                                  column=0,
                                                  columnspan=2)
        self.left_video_frame_inc_150_button.grid(row=VIDEO_BUTTONS_ROW_2,
                                                  column=2,
                                                  columnspan=2)
        self.left_video_frame_inc_30_button.grid(row=VIDEO_BUTTONS_ROW_2,
                                                 column=4,
                                                 columnspan=2)
        self.right_video_frame_inc_30_button.grid(row=VIDEO_BUTTONS_ROW_2,
                                                  column=6,
                                                  columnspan=2)
        self.right_video_frame_inc_150_button.grid(row=VIDEO_BUTTONS_ROW_2,
                                                   column=8,
                                                   columnspan=2)
        self.right_video_frame_inc_300_button.grid(row=VIDEO_BUTTONS_ROW_2,
                                                   column=10,
                                                   columnspan=2)

        self.next_button.grid(row=NEXT_BUTTON_ROW, column=0, columnspan=12)

        self.content_wrapper.place(relx=SCREENS_REL_X,
                                   rely=SCREEN_REL_Y_50,
                                   anchor=CENTER)

    def set_video_frame(self, frame_num, left_offset, right_offset):
        _, left_img = \
            self.controller.video_frame_loader.get_left_frame_tkinter_with_resize(frame_num + left_offset,
                                                                                  VIDEO_PREVIEW_WIDTH, VIDEO_PREVIEW_HEIGHT)
        _, right_img = \
            self.controller.video_frame_loader.get_right_frame_tkinter_with_resize(frame_num + right_offset,
                                                                                   VIDEO_PREVIEW_WIDTH, VIDEO_PREVIEW_HEIGHT)

        self.left_video_label.configure(image=left_img)
        self.left_video_label.image = left_img

        self.right_video_label.configure(image=right_img)
        self.right_video_label.image = right_img

    def on_show_frame(self):
        self.update_UI()

    def update_frame(self, data):
        pass

    def on_hide_frame(self):
        pass

    def update_UI(self):
        self.ensure_frame_num_is_valid()

        self.set_video_frame(self.frame_num,
                             self.controller.video_offsets.left_offset,
                             self.controller.video_offsets.right_offset)
        self.left_frame_num_label.configure(
            text=LEFT_FRAME_NUM_PREFIX +
            str(self.frame_num + self.controller.video_offsets.left_offset))
        self.right_frame_num_label.configure(
            text=RIGHT_FRAME_NUM_PREFIX +
            str(self.frame_num + self.controller.video_offsets.right_offset))
        self.left_offset_label.configure(
            text=LEFT_OFFSET_PREFIX +
            str(self.controller.video_offsets.left_offset))
        self.right_offset_label.configure(
            text=RIGHT_OFFSET_PREFIX +
            str(self.controller.video_offsets.right_offset))

    def ensure_frame_num_is_valid(self):
        if self.frame_num < 0:
            self.frame_num = 0

        left_offset = self.controller.video_offsets.left_offset
        right_offset = self.controller.video_offsets.right_offset
        last_frame_left = self.controller.video_frame_loader.last_frame_num_left
        last_frame_right = self.controller.video_frame_loader.last_frame_num_right

        if self.frame_num + left_offset > last_frame_left:
            self.frame_num = last_frame_left - left_offset
        if self.frame_num + right_offset > last_frame_right:
            self.frame_num = last_frame_left - right_offset

    def adjust_frame_num(self, value):
        self.frame_num += value
        self.update_UI()

    def adjust_left_offset(self, value):
        self.controller.video_offsets.left_offset += value
        self.normalize_offsets()
        self.update_UI()

    def adjust_right_offset(self, value):
        self.controller.video_offsets.right_offset += value
        self.normalize_offsets()
        self.update_UI()

    def normalize_offsets(self):
        if self.controller.video_offsets.left_offset > self.controller.video_offsets.right_offset:
            self.controller.video_offsets.left_offset -= self.controller.video_offsets.right_offset
            self.controller.video_offsets.right_offset = 0
        elif self.controller.video_offsets.left_offset < self.controller.video_offsets.right_offset:
            self.controller.video_offsets.right_offset -= self.controller.video_offsets.left_offset
            self.controller.video_offsets.left_offset = 0
        else:
            self.controller.video_offsets.left_offset = 0
            self.controller.video_offsets.right_offset = 0
class VideoSelectionScreen(GuiBaseFrame):
    def __init__(self, parent, controller, **kw):
        GuiBaseFrame.__init__(self, parent, controller, **kw)

    def init_widgets(self):
        self.content_wrapper = Frame(self)

        self.init_video_info()

        self.screen_title_label = Header1Label(self.content_wrapper,
                                               text="Video Selection")
        self.instruction_label = PLabel(
            self.content_wrapper,
            text="Please choose your left and right video files. "
            "Press Next when finished.\n"
            "(Files must be in MKV format).")
        self.left_video_filename_preview_label = PLabel(
            self.content_wrapper, text="No Video Selected")
        self.left_video_button = Button(
            self.content_wrapper,
            text="Choose Left Video",
            command=lambda: self.select_video_through_button_press(LEFT))
        self.right_video_filename_preview_label = PLabel(
            self.content_wrapper, text="No Video Selected")
        self.right_video_button = Button(
            self.content_wrapper,
            text="Choose Right Video",
            command=lambda: self.select_video_through_button_press(RIGHT))
        self.next_button = Button(self.content_wrapper,
                                  text="Next",
                                  state=DISABLED,
                                  command=lambda: self.next_screen())

        self.add_img_previews()

    def add_widgets_to_frame(self):
        self.content_wrapper.grid_columnconfigure(0, weight=1)
        self.content_wrapper.grid_columnconfigure(1, weight=1)

        self.screen_title_label.grid(row=SCREEN_TITLE_ROW,
                                     column=0,
                                     columnspan=CENTER_SCREEN_COLSPAN)
        self.instruction_label.grid(row=INSTRUCTION_ROW,
                                    column=LEFT_VIDEO_THUMBNAIL_COL,
                                    columnspan=CENTER_SCREEN_COLSPAN)

        self.left_video_thumbnail.grid(row=THUMBNAIL_ROW,
                                       column=LEFT_VIDEO_THUMBNAIL_COL)
        self.left_video_filename_preview_label.grid(
            row=FILENAME_PREVIEW_ROW, column=LEFT_VIDEO_THUMBNAIL_COL)
        self.left_video_button.grid(row=CHOOSE_VIDEO_BUTTON_ROW,
                                    column=LEFT_VIDEO_THUMBNAIL_COL)

        self.right_video_thumbnail.grid(row=THUMBNAIL_ROW,
                                        column=RIGHT_VIDEO_THUMBNAIL_COL)
        self.right_video_filename_preview_label.grid(
            row=FILENAME_PREVIEW_ROW, column=RIGHT_VIDEO_THUMBNAIL_COL)
        self.right_video_button.grid(row=CHOOSE_VIDEO_BUTTON_ROW,
                                     column=RIGHT_VIDEO_THUMBNAIL_COL)

        self.next_button.grid(row=NEXT_BUTTON_ROW,
                              column=0,
                              columnspan=CENTER_SCREEN_COLSPAN)
        self.content_wrapper.place(relx=SCREENS_REL_X,
                                   rely=SCREEN_REL_Y_47,
                                   anchor=CENTER)

    def init_video_info(self):
        self.left_video_selected = False
        self.right_video_selected = False
        self.left_video_filename = None
        self.right_video_filename = None

    def next_screen(self):
        self.controller.set_video_filenames(self.left_video_filename,
                                            self.right_video_filename)
        self.controller.show_next_frame()

    def add_img_previews(self):
        img_not_available = cv2.imread(
            get_asset_filename(IMG_NOT_AVAILABLE_FILENAME))
        img_not_available = cv2_bgr_image_to_tkinter_with_resize(
            img_not_available, VIDEO_PREVIEW_WIDTH, VIDEO_PREVIEW_HEIGHT)

        self.left_video_thumbnail = Label(self.content_wrapper,
                                          image=img_not_available)
        self.left_video_thumbnail.image = img_not_available
        self.right_video_thumbnail = Label(self.content_wrapper,
                                           image=img_not_available)
        self.right_video_thumbnail.image = img_not_available

    def select_video_through_button_press(self, video_side=LEFT):
        selected_video_filename = select_video_filename()
        self.set_video_thumbnail_based_on_filename(selected_video_filename,
                                                   video_side)

    def set_next_button_state(self):
        if self.left_video_selected and self.right_video_selected:
            self.next_button.configure(state=NORMAL)

    def on_show_frame(self):
        if does_tmp_file_exist_basename(VIDEOS_SELECTED_TMP_FILENAME):
            video_filenames = read_tmp_file(VIDEOS_SELECTED_TMP_FILENAME)
            video_filenames = ast.literal_eval(video_filenames)
            self.set_video_thumbnail_based_on_filename(video_filenames[LEFT],
                                                       LEFT)
            self.set_video_thumbnail_based_on_filename(video_filenames[RIGHT],
                                                       RIGHT)

    def on_hide_frame(self):
        video_filenames_used = {
            LEFT: self.left_video_filename,
            RIGHT: self.right_video_filename
        }
        write_to_tmp_file(VIDEOS_SELECTED_TMP_FILENAME,
                          str(video_filenames_used))

    def set_video_thumbnail_based_on_filename(self,
                                              video_filename,
                                              video_side=LEFT):
        if os.path.isfile(
                os.path.join(os.path.dirname(video_filename),
                             os.path.basename(video_filename))):
            vc_object = cv2.VideoCapture(video_filename)
            _, img = vc_object.read()
            vc_object.release()

            img = cv2_bgr_image_to_tkinter_with_resize(img,
                                                       VIDEO_PREVIEW_WIDTH,
                                                       VIDEO_PREVIEW_HEIGHT)
            self.update_ui(video_filename, img, True, video_side)

    def update_ui(self, filename, img, video_selected, video_side=LEFT):
        if video_selected and video_side == LEFT:
            self.left_video_selected = True
            self.left_video_filename = filename
            self.left_video_filename_preview_label.config(
                text=os.path.basename(os.path.normpath(filename)))
            self.set_next_button_state()

            self.left_video_thumbnail.configure(image=img)
            self.left_video_thumbnail.image = img
        elif video_selected and video_side == RIGHT:
            self.right_video_selected = True
            self.right_video_filename = filename
            self.right_video_filename_preview_label.config(
                text=os.path.basename(os.path.normpath(filename)))
            self.set_next_button_state()

            self.right_video_thumbnail.configure(image=img)
            self.right_video_thumbnail.image = img
class SrFrameSelection(GuiBaseFrame):
    def __init__(self, parent, controller, **kw):
        GuiBaseFrame.__init__(self, parent, controller, **kw)

    def init_widgets(self):
        self.content_wrapper = Frame(self)
        self.screen_title = Header1Label(self.content_wrapper,
                                         text=SR_FRAME_SELECTION_TITLE)
        self.screen_description = PLabel(
            self.content_wrapper,
            text="Please select a frame that has a satisfactory "
            "stereo rectification result.")

    def add_widgets_to_frame(self):
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)
        self.screen_title.grid(row=0, column=0, columnspan=3)
        self.screen_description.grid(row=1, columnspan=3)
        self.content_wrapper.place(relx=SCREENS_REL_X,
                                   rely=0.48,
                                   anchor=CENTER)

    def on_show_frame(self):
        self.canvas_wrappers = []
        self.canvases = []
        self.page_num = 0

        if len(self.controller.sr_results) == 0:
            self.controller.show_frame(SrNoFramesFoundScreen)
        else:
            pages = int(ceil(len(self.controller.sr_results) / 10.0))
            for page in range(0, pages):
                canvas_wrapper = Frame(self.content_wrapper,
                                       borderwidth="1",
                                       relief="solid")
                canvas = Canvas(canvas_wrapper,
                                width=int(WINDOW_WIDTH * 7 / 8),
                                height=(WINDOW_HEIGHT * 2 / 3))
                scroll_bar = Scrollbar(canvas_wrapper,
                                       orient=VERTICAL,
                                       command=canvas.yview)
                results_list_frame = Frame(canvas)

                canvas.configure(yscrollcommand=scroll_bar.set)
                canvas.create_window(0, 0, window=results_list_frame)
                canvas.bind_all("<Up>", self.on_up_key)
                canvas.bind_all("<Down>", self.on_down_key)
                canvas.bind_all("<Left>", self.on_left_key)
                canvas.bind_all("<Right>", self.on_right_key)

                canvas.grid(row=0, column=0, sticky="nsew")
                scroll_bar.grid(row=0, column=1, sticky="ns")
                canvas_wrapper.grid(row=2,
                                    column=0,
                                    columnspan=3,
                                    sticky="nsew")

                select_buttons_on_page = []

                for row in range(0, RESULTS_PER_PAGE):
                    result_num = page * RESULTS_PER_PAGE + row
                    if result_num < len(self.controller.sr_results):
                        frame_num = self.controller.sr_results[result_num][
                            FRAME_NUM_LABEL]

                        result_entry = Frame(results_list_frame,
                                             borderwidth="1",
                                             relief="solid")
                        description = PLabel(
                            result_entry,
                            text="Frame #" + str(int(frame_num)) + ", Time: " +
                            str(datetime.timedelta(seconds=frame_num / 30)))
                        preview_wrapper = Frame(result_entry)
                        left_video_preview = Label(
                            preview_wrapper,
                            image=self.controller.sr_results[result_num][LEFT])
                        right_video_preview = Label(
                            preview_wrapper,
                            image=self.controller.sr_results[result_num]
                            [RIGHT])
                        select_button = SrSelectButton(
                            preview_wrapper,
                            self.controller,
                            self.controller.sr_results[result_num]
                            [SR_MAP_LABEL],
                            text="Select")

                        select_buttons_on_page.append(select_button)

                        description.pack()
                        left_video_preview.grid(row=row, column=0)
                        right_video_preview.grid(row=row, column=1)
                        select_button.grid(row=row, column=2)
                        preview_wrapper.pack()
                        result_entry.pack()

                for i in range(0, len(select_buttons_on_page)):
                    select_buttons_on_page[i].configure(
                        command=select_buttons_on_page[i].use_sr_map)

                self.master.update_idletasks()
                canvas.config(scrollregion=canvas.bbox("all"))
                canvas.yview_moveto(0)
                self.canvas_wrappers.append(canvas_wrapper)
                self.canvases.append(canvas)

            self.prev_result_page = Button(
                self.content_wrapper,
                text="<",
                command=lambda: self.prev_page_command())
            self.page_info_label = PLabel(
                self.content_wrapper,
                text=get_page_info_label_message(self.page_num,
                                                 len(self.canvases),
                                                 RESULTS_PER_PAGE))
            self.next_result_page = Button(
                self.content_wrapper,
                text=">",
                command=lambda: self.next_page_command())

            self.prev_result_page.grid(row=3, column=0)
            self.page_info_label.grid(row=3, column=1)
            self.next_result_page.grid(row=3, column=2)
            self.canvas_wrappers[self.page_num].tkraise()

    def update_frame(self, data):
        pass

    def on_hide_frame(self):
        pass

    def on_up_key(self, event):
        self.canvases[self.page_num].yview_scroll(-7, 'units')

    def on_down_key(self, event):
        self.canvases[self.page_num].yview_scroll(7, 'units')

    def on_left_key(self, event):
        self.prev_page_command()

    def on_right_key(self, event):
        self.next_page_command()

    def prev_page_command(self):
        if self.page_num > 0:
            self.page_num -= 1
            self.canvas_wrappers[self.page_num].tkraise()
            self.page_info_label.configure(text=get_page_info_label_message(
                self.page_num, len(self.canvases), RESULTS_PER_PAGE))

    def next_page_command(self):
        if self.page_num < len(self.canvas_wrappers) - 1:
            self.page_num += 1
            self.canvas_wrappers[self.page_num].tkraise()
            self.page_info_label.configure(text=get_page_info_label_message(
                self.page_num, len(self.canvases), RESULTS_PER_PAGE))