Source code for ibeis.gui.clock_offset_gui

# -*- coding: utf-8 -*-
"""
Small GUI for asking the user to enter the clock time shown, and moving along a gid list if the first image isn't a clock
"""
from __future__ import absolute_import, division, print_function
from functools import partial
#from guitool import qtype, APIItemWidget, APIItemModel, FilterProxyModel, ChangeLayoutContext
from guitool.__PYQT__ import QtGui  # , QtCore
from guitool.__PYQT__.QtCore import Qt
#from ibeis.other import ibsfuncs
#from ibeis.expt import results_organizer
#from ibeis.viz import interact
#from ibeis.viz import viz_helpers as vh
#from plottool import fig_presenter
#from plottool import interact_helpers as ih
from plottool import imshow, close_figure, next_fnum
from six.moves import range
import guitool
#import numpy as np
#import six
import utool
import utool as ut
from datetime import date, datetime
from time import mktime
(print, print_, printDBG, rrr, profile) = utool.inject(__name__, '[co_gui]')


[docs]class ClockOffsetWidget(QtGui.QWidget): def __init__(co_wgt, ibs, gid_list, parent=None, hack=False): print('[co_gui] Initializing') print('[co_gui] gid_list = %r' % (gid_list,)) QtGui.QWidget.__init__(co_wgt, parent=parent) co_wgt.fnum = next_fnum() co_wgt.main_layout = QtGui.QVBoxLayout(co_wgt) co_wgt.text_layout = guitool.newWidget(co_wgt, orientation=Qt.Vertical, verticalStretch=10) co_wgt.main_layout.addWidget(co_wgt.text_layout) co_wgt.control_layout = guitool.newWidget(co_wgt, orientation=Qt.Vertical, verticalSizePolicy=QtGui.QSizePolicy.MinimumExpanding) co_wgt.main_layout.addWidget(co_wgt.control_layout) co_wgt.button_layout = guitool.newWidget(co_wgt, orientation=Qt.Horizontal) co_wgt.control_layout.addWidget(co_wgt.button_layout) co_wgt.combo_layout = guitool.newWidget(co_wgt, orientation=Qt.Horizontal) co_wgt.control_layout.addWidget(co_wgt.combo_layout) co_wgt.hack = hack # hack for edting the time of a single image co_wgt.imfig = None co_wgt.imax = None co_wgt.dtime = None co_wgt.ibs = ibs co_wgt.gid_list = gid_list co_wgt.current_gindex = 0 co_wgt.offset = 0 # Set image datetime with first image co_wgt.get_image_datetime() co_wgt.add_label() co_wgt.add_combo_boxes() co_wgt.add_buttons() co_wgt.update_ui()
[docs] def resizeEvent(co_wgt, event): super(ClockOffsetWidget, co_wgt).resizeEvent(event) if co_wgt.image_label is not None: # Hack use signals and slots if hasattr(co_wgt.image_label, '_on_resize_slot'): co_wgt.image_label._on_resize_slot() #print('resizeEvent')
[docs] def get_image_datetime(co_wgt): # Function that extracts the unixtime from an image and stores it utime = co_wgt.ibs.get_image_unixtime(co_wgt.gid_list[co_wgt.current_gindex]) if not isinstance(utime, (float, int)) or utime is None: utime = -1 utime = float(utime) co_wgt.dtime = datetime.fromtimestamp(utime)
[docs] def update_ui(co_wgt): if not co_wgt.hack: if co_wgt.current_gindex == 0: co_wgt.button_list[0].setEnabled(False) else: co_wgt.button_list[0].setEnabled(True) if co_wgt.current_gindex == len(co_wgt.gid_list) - 1: co_wgt.button_list[1].setEnabled(False) else: co_wgt.button_list[1].setEnabled(True) #TODO Either integrate this into utool or check if it's already there def extract_tuple(li, idx): return list(zip(*li)[idx]) # Update option setting, assume datetime has been updated co_wgt.combo_list[1].setCurrentIndex(extract_tuple(co_wgt.opt_list['year'], 1).index(co_wgt.dtime.year)) co_wgt.combo_list[3].setCurrentIndex(extract_tuple(co_wgt.opt_list['month'], 1).index(co_wgt.dtime.month)) co_wgt.combo_list[5].setCurrentIndex(extract_tuple(co_wgt.opt_list['day'], 1).index(co_wgt.dtime.day)) co_wgt.combo_list[7].setCurrentIndex(extract_tuple(co_wgt.opt_list['hour'], 1).index(co_wgt.dtime.hour)) co_wgt.combo_list[9].setCurrentIndex(extract_tuple(co_wgt.opt_list['minute'], 1).index(co_wgt.dtime.minute)) co_wgt.combo_list[11].setCurrentIndex(extract_tuple(co_wgt.opt_list['second'], 1).index(co_wgt.dtime.second)) # Redraw image if not co_wgt.hack: if co_wgt.imfig is not None: close_figure(co_wgt.imfig) image = co_wgt.ibs.get_images(co_wgt.gid_list[co_wgt.current_gindex]) figtitle = "Time Synchronization Picture" co_wgt.imfig, co_wgt.imax = imshow(image, fnum=co_wgt.fnum, title=figtitle) co_wgt.imfig.show()
[docs] def show_helpmsg(co_wgt): msg = ut.textblock( """ This step is for synchronizing the time of the images being imported with the actual time of the imageset. Use the Previous and Next buttons until the 'Time Synchronization Picture' is of the clock taken at the beginning of the imageset. Once found, change the date and time in the boxes below to match the time of the clock in the image, and correct the date if necessary. Once done, click 'Set' and the difference will be applied to all images currently being imported. If you are sure the camera was synchronized, you can skip this step by pressing 'Skip'. """) guitool.user_info(co_wgt, msg=msg, title='Time Sync Help')
[docs] def add_label(co_wgt): # Very simply adds the text _LABEL = partial(guitool.newLabel, parent=co_wgt) if not co_wgt.hack: text = ut.codeblock( ''' * Find the image of the clock * Set the sliders to correspond with the clock * Click Set * Skip if time synchonization is not relevant to you ''' ) main_label = _LABEL(text=text, align='left') co_wgt.text_layout.addWidget(main_label) else: text = ut.codeblock( ''' * Set the time for image %r ''' % (co_wgt.gid_list,) ) gpath = co_wgt.ibs.get_image_paths(co_wgt.gid_list[co_wgt.current_gindex]) image_label = _LABEL(text='', gpath=gpath) # align='left') co_wgt.image_label = image_label co_wgt.text_layout.addWidget(image_label) #main_label = _LABEL(text=text, align='left') #co_wgt.text_layout.addWidget(main_label)
[docs] def add_buttons(co_wgt): _BUTTON = partial(guitool.newButton, parent=co_wgt) if not co_wgt.hack: co_wgt.button_list = [ _BUTTON(text='Previous Image', clicked=co_wgt.go_prev), _BUTTON(text='Next Image', clicked=co_wgt.go_next), _BUTTON(text='Skip', clicked=co_wgt.cancel), _BUTTON(text='Set', clicked=co_wgt.accept), _BUTTON(text='Help', clicked=co_wgt.show_helpmsg), ] else: co_wgt.button_list = [ _BUTTON(text='Accept', clicked=co_wgt.accept), ] # Copying from inspect_gui for button in co_wgt.button_list: co_wgt.button_layout.addWidget(button)
[docs] def add_combo_boxes(co_wgt): _CBOX = partial(guitool.newComboBox, parent=co_wgt) _LABEL = partial(guitool.newLabel, parent=co_wgt, align='right') def to_opt_list(x): return [("%02d" % i, i) for i in x] year_list = [datetime.fromtimestamp(unixtime).year for unixtime in co_wgt.ibs.get_image_unixtime(co_wgt.gid_list) if unixtime is not None] max_year = max(year_list + [date.today().year]) + 1 min_year = min(year_list + [1970]) - 1 #max_year = date.today().year + 1 co_wgt.opt_list = { 'year': to_opt_list(range(min_year, max_year)), 'month': to_opt_list(range(1, 13)) , 'day': to_opt_list(range(1, 32)), # yes this will allow invalid dates, but it's not a real issue 'hour': to_opt_list(range(24)), 'minute': to_opt_list(range(60)), 'second': to_opt_list(range(60)), } co_wgt.combo_list = [ _LABEL(text="YYYY"), _CBOX(changed=partial(co_wgt.change_dt, 'year'), options=co_wgt.opt_list['year'], default=co_wgt.dtime.year), _LABEL(text="MM"), _CBOX(changed=partial(co_wgt.change_dt, 'month'), options=co_wgt.opt_list['month'], default=co_wgt.dtime.month), _LABEL(text="DD"), _CBOX(changed=partial(co_wgt.change_dt, 'day'), options=co_wgt.opt_list['day'], default=co_wgt.dtime.day), _LABEL(text="HH (24H)"), _CBOX(changed=partial(co_wgt.change_dt, 'hour'), options=co_wgt.opt_list['hour'], default=co_wgt.dtime.hour), _LABEL(text="mm"), _CBOX(changed=partial(co_wgt.change_dt, 'minute'), options=co_wgt.opt_list['minute'], default=co_wgt.dtime.minute), _LABEL(text="ss"), _CBOX(changed=partial(co_wgt.change_dt, 'second'), options=co_wgt.opt_list['second'], default=co_wgt.dtime.second), ] for combo in co_wgt.combo_list: co_wgt.combo_layout.addWidget(combo)
@guitool.slot_()
[docs] def go_prev(co_wgt): # Decrement current gid index, then call update co_wgt.current_gindex -= 1 co_wgt.get_image_datetime() co_wgt.update_ui()
@guitool.slot_()
[docs] def go_next(co_wgt): # Increment current gid index, then call update co_wgt.current_gindex += 1 co_wgt.get_image_datetime() co_wgt.update_ui()
@guitool.slot_()
[docs] def cancel(co_wgt): # Just close close_figure(co_wgt.imfig) co_wgt.close()
@guitool.slot_()
[docs] def accept(co_wgt): # Calculate offset # Get current image's actual time image_time = co_wgt.ibs.get_image_unixtime(co_wgt.gid_list[co_wgt.current_gindex]) # Get unixtime from current dtime #TODO put into utool input_time = mktime(co_wgt.dtime.timetuple()) # Go through gid list, and add that offset to every unixtime offset = input_time - image_time print("[co_gui] Unixtime offset is %d" % offset) # Set the unixtimes with the new ones utimes = co_wgt.ibs.get_image_unixtime(co_wgt.gid_list) new_utimes = [time + offset for time in utimes] # SHOULD WE BE USING image_timedelta_posix INSTEAD OF THIS? co_wgt.ibs.set_image_unixtime(co_wgt.gid_list, new_utimes) # Close if not co_wgt.hack: close_figure(co_wgt.imfig) co_wgt.close()
@guitool.slot_(str, int, str)
[docs] def change_dt(co_wgt, attr, val_ind, val): co_wgt.dtime = co_wgt.dtime.replace(**{attr: co_wgt.opt_list[attr][val_ind][1]}) print("[co_gui] Base datetime is %r" % co_wgt.dtime)
[docs]def test_clock_offset(): r""" CommandLine: python -m ibeis.gui.clock_offset_gui --test-test_clock_offset Example: >>> # DISABLE_DOCTEST >>> from ibeis.gui.clock_offset_gui import * # NOQA >>> # build test data >>> # execute function >>> result = test_clock_offset() >>> # verify results >>> print(result) """ import ibeis main_locals = ibeis.main(db='testdb1') ibs = main_locals['ibs'] gid_list = ibs.get_valid_gids() co = ClockOffsetWidget(ibs, gid_list, hack=True) co.show() ibeis.main_loop(main_locals)
if __name__ == '__main__': """ CommandLine: python -m ibeis.gui.clock_offset_gui python -m ibeis.gui.clock_offset_gui --allexamples python -m ibeis.gui.clock_offset_gui --allexamples --noface --nosrc """ import multiprocessing multiprocessing.freeze_support() # for win32 import utool as ut # NOQA ut.doctest_funcs()