def __init__(self, parent_win=None): BaseWidget.__init__(self, 'Videos and intervals selector', parent_win=parent_win) self._panel = ControlEmptyWidget(default=VideosSelectorDialog( parent_win=self)) self._interval = ControlBoundingSlider('Interval', horizontal=True) self.formset = ['_panel', '_interval'] self._intervals = {} self._panel.value.video_selection_changed_event = self.__video_selection_changed_event self._interval.changed_event = self.__update_intervals_event
def __init__(self, title=''): super(BaseApp, self).__init__(title) self._progress = ControlProgress('Processing') self._boundings = ControlBoundingSlider('Ranges', horizontal=True) #Only creates the variable if didn't exists yet. if not hasattr(self, '_modules_tabs'): self._modules_tabs = {} self.formset = [(' ', 'Frames bounding', ' '), '_boundings', self._modules_tabs, '_progress'] #Controls organization definition self.mainmenu = [{ 'File': [{ 'Open csv file': self.__open_tracking_file }, '-', { 'Export data': self.export_tracking_file }, '-', { 'Exit': exit }] }] self._data = None #Events definition self._csvParser = CsvParserDialog() self._csvParser.load_file_event = self.load_tracking_file self._boundings.changed = self.frames_boundings_changed
def __init__(self): super(Example1, self).__init__('dir examples') self.parent = None self._directory = ControlDir('Choose a directory') self._file = ControlFile('Choose a file') self._filetree = ControlFilesTree('Choose a file') self._image = ControlImage('Image') self._boundaries = ControlBoundingSlider('Bounding', horizontal=True) self._button = ControlButton('Click') self._button.value = self.onButtonClick # self._directory.value=self.onButtonClick self._checkbox = ControlCheckBox('Choose a directory') self._checkboxList = ControlCheckBoxList('Choose a file') self._player = ControlPlayer('Choose a file') self._slider = ControlSlider('Slider') self._player.show() self._checkboxList.value = [('Item 1', True), ('Item 2', False), ('Item 3', True)] self._combobox = ControlCombo('Choose a item') self._list = ControlList('List label') self._progress = ControlProgress('Progress bar') self._visvisVolume = ControlVisVisVolume('Visvis') self._timeline = ControlEventTimeline('Timeline') self._combobox.add_item('Item 1', 'Value 1') self._combobox.add_item('Item 2', 'Value 2') self._combobox.add_item('Item 3', 'Value 3') self._combobox.add_item('Item 4') self._list.value = [('Item1', 'Item2', 'Item3',), ('Item3', 'Item4', 'Item5',)] imageWithVolume = np.zeros((100, 100, 100), np.uint8) imageWithVolume[30:40, 30:50, :] = 255 imageWithVolume[30:40, 70:72, :] = 255 self._visvisVolume.value = imageWithVolume self._visvis = ControlVisVis('Visvis') values1 = [(i, random.random(), random.random()) for i in range(130)] values2 = [(i, random.random(), random.random()) for i in range(130)] self._visvis.value = [values1, values2] self.formset = [ '_visvis' , '_directory' , '_button' , '_file' , '_boundaries' , '_filetree' , '_image' , '_slider' , ('_checkboxList', '_player') , ('_checkbox', ' ') , ('_combobox', ' ') , '_progress' , '=' , ('_visvisVolume', '||', '_list') , '_timeline' ]
def __init__(self, parent_win=None): BaseWidget.__init__(self, 'Datasets', parent_win=parent_win) self._panel = ControlEmptyWidget(default=DatasetsSelectorDialog( parent_win=self)) self._interval = ControlBoundingSlider('Interval', horizontal=True) self._apply_btn = ControlButton('Apply') self.formset = [ '_panel', '_interval', '_apply_btn', ] self._intervals = {} self._panel.value.video_selection_changed_event = self.__video_selection_changed_event self._interval.changed_event = self.__update_intervals_event self._apply_btn.hide()
def __init__(self, **kwargs): BaseWidget.__init__(self, 'Find blobs') Class.__init__(self, **kwargs) try: self.layout().setContentsMargins(10, 5, 10, 5) self.setMinimumHeight(55) except: pass self._area_range = ControlBoundingSlider('Filter by area', default=[100, 90000], mininum=0, maximum=100000, horizontal=True) self._formset = ['_area_range'] self._area_range.changed_event = self.__area_range_changed_event
def __init__(self, parent=None, parent_win=None): BaseWidget.__init__(self, 'Events stats', parent_win=parent_win) self._parent = parent self._bounds = ControlBoundingSlider('Frames range', 1, 100, horizontal=True) self._nframes = ControlNumber('Merge in a group of', 1800) self._videofsp = ControlNumber('FPS', 30.0) self._analyseButton = ControlButton('Calculate graphs') self._events = ControlCheckBoxList() self._graph = ControlVisVis('Graph') self._showTotalCounts = ControlCheckBox('Show total events counting') self._showEvtsCounts = ControlCheckBox('Show events counting', True) self._progress = ControlProgress() self._exportDurations = ControlButton('Export durations') self._exportTotals = ControlButton('Export totals') self._formset = [(' ', '_showEvtsCounts', '|', '_showTotalCounts', '|', '_nframes', '_videofsp', '_analyseButton', '_exportDurations', '_exportTotals'), '_bounds', { 'a:Graph': ['_graph'], 'c:Events selection': ['_events'] }, '_progress'] self._analyseButton.value = self.__generate_graph self._exportDurations.value = self.__export_durations self._exportTotals.value = self.__export_totals self._progress.hide() self.__load_events() self.set_margin(5) self.setMinimumWidth(800) self.setMinimumHeight(600)
class DatasetsDialog(BaseWidget): def __init__(self, parent_win=None): BaseWidget.__init__(self, 'Datasets', parent_win=parent_win) self._panel = ControlEmptyWidget(default=DatasetsSelectorDialog( parent_win=self)) self._interval = ControlBoundingSlider('Interval', horizontal=True) self._apply_btn = ControlButton('Apply') self.formset = [ '_panel', '_interval', '_apply_btn', ] self._intervals = {} self._panel.value.video_selection_changed_event = self.__video_selection_changed_event self._interval.changed_event = self.__update_intervals_event self._apply_btn.hide() ##################################################################### ### PRIVATE FUNCTIONS ############################################### ##################################################################### def __update_intervals_event(self): self._intervals[self.selected_video] = self._interval.value def __video_selection_changed_event(self): video = self.selected_video if video is not None and video.video_capture is not None: self._interval.max = video.video_capture.get(7) if video not in self._intervals.keys(): self._intervals[video] = 0, self._interval.max self._interval.value = self._intervals[video] self.video_selection_changed_event() ##################################################################### ### EVENTS ########################################################## ##################################################################### def video_selection_changed_event(self): pass def destroy(self, destroyWindow=True, destroySubWindows=True): self._panel.value.destroy(destroyWindow, destroySubWindows) super(DatasetsDialog, self).destroy(destroyWindow, destroySubWindows) ##################################################################### ### FUNCTIONS ####################################################### ##################################################################### def refresh(self): self._panel.value.refresh() def clear(self): self._panel.value.clear() def __add__(self, other): self._panel.value += other return self def __sub__(self, other): self._panel.value -= other return self ##################################################################### ### PROPERTIES ###################################################### ##################################################################### @property def videos(self): return self._panel.value.videos @property def datasets(self): return self._panel.value.datasets @property def datasets_changed_event(self): return self._panel.value.datasets_changed_event @datasets_changed_event.setter def datasets_changed_event(self, value): self._panel.value.datasets_changed_event = value @property def objects_changed_event(self): return self._panel.value.objects_changed_event @objects_changed_event.setter def objects_changed_event(self, value): self._panel.value.objects_changed_event = value @property def selected_video(self): return self._panel.value.selected_video @property def selected_video_range(self): return self._intervals.value @property def selected_data(self): for video, paths in self._panel.value.selected_data: begin, end = self._intervals.get(video, (0, video.video_capture.get(7))) yield video, (begin, end), paths @property def apply_event(self): return self._apply_btn.value @apply_event.setter def apply_event(self, value): if value is not None: self._apply_btn.show() self._apply_btn.value = value @property def interval_visible(self): return self._interval.visible @interval_visible.setter def interval_visible(self, value): if value: self._interval.show() else: self._interval.hide() @property def objects_filter(self): return self._panel.value.objects_filter @objects_filter.setter def objects_filter(self, value): self._panel.value.objects_filter = value @property def datasets_filter(self): return self._panel.value.datasets_filter @datasets_filter.setter def datasets_filter(self, value): self._panel.value.datasets_filter = value
def __init__(self, parent=None): super(ContoursImagesWindow, self).__init__('Contour images', parent_win=parent) self.mainwindow = parent self.set_margin(5) self.setMinimumHeight(400) self.setMinimumWidth(800) self._contourspanel = ControlEmptyWidget('Contours datasets') self._progress = ControlProgress('Progress', visible=False) self._apply = ControlButton('Apply', checkable=True) self._toolbox = ControlToolBox('Toolbox') self._exportdir = ControlDir('Export images to folder', default='images-from-contour') #### mask ###################################################### self._usemaskimg = ControlCheckBox('Apply a mask to the image') self._usemaskdilate = ControlCheckBox('Dilate the mask and apply it to the image') self._maskdilatesize = ControlSlider('Dilate size', default=0, minimum=0, maximum=100) self._usemaskellipse = ControlCheckBox('Apply the min. ellipse as a mask to the image') self._usemaskcircular = ControlCheckBox('Apply a circular mask to the image') self._maskcircularsize = ControlSlider('Circular radius', default=0, minimum=0, maximum=100) self._usemaskrect = ControlCheckBox('Apply the min. rect as a mask to the image') ################################################################ #### margin #################################################### self._margin = ControlSlider('Margin size', default=0, minimum=0, maximum=100) ################################################################ #### imagesize ################################################# self._imagesize = ControlSlider('Image size', default=0, minimum=0, maximum=400) ################################################################ #### cut ####################################################### self._usecut = ControlCheckBox('Cut image') self._cutx = ControlBoundingSlider('X cut', default=(10,30), minimum=0, maximum=1000) self._cuty = ControlBoundingSlider('Y cut', default=(10,30), minimum=0, maximum=1000) ################################################################ #### use stretch ############################################### self._usestretch = ControlCheckBox('Stretch image') ################################################################ #### filter per events ######################################### self._eventslst = ControlCheckBoxList('Events', enabled=True) self._reloadevts = ControlButton('Reload events', enabled=True, default=self.__reload_events_btn_evt) ################################################################ #### rotation ################################################## self._userotup = ControlCheckBox('Turn the contour always up') self._userotdown = ControlCheckBox('Turn the contour always down') self._usefixedangle = ControlCheckBox('Use a fixed orientation') self._fixedangle = ControlSlider('Rotate the images using a fixed angle', enabled=True, default=0, minimum=0, maximum=360) self._usedatasetangle = ControlCheckBox('Use the orientation of other contour') self._datasetanglepanel = ControlEmptyWidget('Datasets for the orientation', enabled=True) ################################################################ #### image position ############################################ self._useposdataset = ControlCheckBox('Use a dataset to center the image') self._datasetpospanel = ControlEmptyWidget('Datasets for the image position', enabled=True) ################################################################ self.formset = [ '_toolbox', '_exportdir', '_apply', '_progress' ] self.load_order = [ '_contourspanel','_userotup', '_userotdown', '_exportdir','_usemaskimg','_usemaskdilate','_usemaskellipse','_usemaskellipse', '_usemaskcircular', '_maskcircularsize', '_usemaskrect', '_margin', '_imagesize', '_usestretch', '_eventslst', '_usefixedangle', '_fixedangle', '_usedatasetangle', '_datasetanglepanel', '_useposdataset', '_datasetpospanel', '_usecut', '_cuty', '_cutx' ] #datasets painel self.datasets_dialog = DatasetsDialog(self) self.datasets_dialog.datasets_filter = lambda x: isinstance(x, Contours ) self._contourspanel.value = self.datasets_dialog self.posdatasets_dialog = DatasetsDialog(self) self.posdatasets_dialog.datasets_filter = lambda x: isinstance(x, (Contours,Path) ) self._datasetpospanel.value = self.posdatasets_dialog self.orientdatasets_dialog = DatasetsDialog(self) self.orientdatasets_dialog.datasets_filter = lambda x: isinstance(x, Contours ) self.orientdatasets_dialog.interval_visible = False self._datasetanglepanel.value = self.orientdatasets_dialog self._apply.value = self.__apply_event self._apply.icon = conf.ANNOTATOR_ICON_PATH self._imagesize.changed_event = self.__image_size_changed_evt self._toolbox.value = [ ('Extract from contours',( self.datasets_dialog, )), ('Mask',( self._usemaskimg, (self._usemaskdilate,self._maskdilatesize), (self._usemaskcircular,self._maskcircularsize), (self._usemaskellipse,self._usemaskrect), )), ('Margin, image size and stretch image',( self._usestretch, self._margin, self._imagesize, self._usecut, self._cutx, self._cuty )), ('Rotate images',( (self._userotup, self._userotdown), (self._usefixedangle, self._fixedangle), self._usedatasetangle, self._datasetanglepanel )), ('Center images',( self._useposdataset, self._datasetpospanel, )), ('Export images per events',( self._reloadevts, self._eventslst, )), ] self.__reload_events_btn_evt() self.__image_size_changed_evt()
def __init__(self, title='Heat map'): super(HeatMapApp, self).__init__(title) self._heatmapImg = None #Store a numpy array with the heatmap self._velocities = None #Store the velocities for each frame self._accelerations = None #Store the accelarations for each frame ##### CONTROLS ############################################################################## self._heatmap = ControlVisVisVolume("Volume") self._toggleSphereVisibility = ControlButton('Filter by a region', checkable=True) self._sphere = ControlText('Position filter (x,y,z,radius)') self._toggleHeatmapVars = ControlButton('Select variables', checkable=True) self._heatmapVarsBnds = ControlBoundingSlider('Variable bounds', horizontal=True) self._heatmapHigherVarsValues = ControlCheckBox( 'Most higher', helptext='Show only the higher values') self._heatmapColor = ControlCombo('Color map') self._apply2Heatmap = ControlButton('Apply to map') self._heatmapColorsBnds = ControlBoundingSlider('Colors', horizontal=False) self._heatmapVarsList = ControlCombo('Variables') self._heatmapVars = ControlCheckBox('Map variables') self._heatMapMinVar = ControlText('Min vel.') self._heatMapMaxVar = ControlText('Max vel.') ############################################################################################# self._modules_tabs.update({ 'Heat map': [('_heatmapColor', ' | ', 'Filters:', '_toggleHeatmapVars', '_toggleSphereVisibility', '_sphere', ' | ', '_apply2Heatmap', ' '), ('_heatmapVarsList', '_heatmapVars', '_heatmapHigherVarsValues', '_heatMapMinVar', '_heatmapVarsBnds', '_heatMapMaxVar'), { 'Map': ('_heatmap', '_heatmapColorsBnds') }] }) ############################################################################################# self._heatmapVarsList += 'Velocity' self._heatmapVarsList += 'Acceleration' self._heatmapColor.add_item('Bone', vv.CM_BONE) self._heatmapColor.add_item('Cool', vv.CM_COOL) self._heatmapColor.add_item('Copper', vv.CM_COPPER) self._heatmapColor.add_item('Gray', vv.CM_GRAY) self._heatmapColor.add_item('Hot', vv.CM_HOT) self._heatmapColor.add_item('HSV', vv.CM_HSV) self._heatmapColor.add_item('Jet', vv.CM_JET) self._heatmapColor.add_item('Pink', vv.CM_PINK) self._heatmapColor.add_item('Autumn', vv.CM_AUTUMN) self._heatmapColor.add_item('Spring', vv.CM_SPRING) self._heatmapColor.add_item('Summer', vv.CM_SUMMER) self._heatmapColor.add_item('Winter', vv.CM_WINTER) self._heatmapColor.value = vv.CM_HSV self._sphere.hide() self._heatmapVarsBnds.hide() self._heatmapVarsList.hide() self._heatMapMinVar.hide() self._heatMapMaxVar.hide() self._heatmapVars.hide() self._heatmapHigherVarsValues.hide() self._heatmapVarsBnds.convert_2_int = False self._heatmapColorsBnds.convert_2_int = False self._apply2Heatmap.value = self.calculate_heatmap_event self._heatmapColor.changed = self.changed_heatmap_color_event self._toggleSphereVisibility.value = self.__toggle_sphere_visiblity_event self._toggleHeatmapVars.value = self.__toggle_variables_visibility_event self._heatmapVarsList.changed = self.__changed_heatmap_variables_list_event self._heatMapMinVar.changed = self.__changed_heatmap_minVar_event self._heatMapMaxVar.changed = self.__changed_heatmap_maxVar_event self._heatmapColorsBnds.changed = self.changed_heatmap_colors_bounds_event self._heatmapVars.changed = self.__changed_heatmap_variables_event
class HeatMapApp(BaseApp): """Application form""" def __init__(self, title='Heat map'): super(HeatMapApp, self).__init__(title) self._heatmapImg = None #Store a numpy array with the heatmap self._velocities = None #Store the velocities for each frame self._accelerations = None #Store the accelarations for each frame ##### CONTROLS ############################################################################## self._heatmap = ControlVisVisVolume("Volume") self._toggleSphereVisibility = ControlButton('Filter by a region', checkable=True) self._sphere = ControlText('Position filter (x,y,z,radius)') self._toggleHeatmapVars = ControlButton('Select variables', checkable=True) self._heatmapVarsBnds = ControlBoundingSlider('Variable bounds', horizontal=True) self._heatmapHigherVarsValues = ControlCheckBox( 'Most higher', helptext='Show only the higher values') self._heatmapColor = ControlCombo('Color map') self._apply2Heatmap = ControlButton('Apply to map') self._heatmapColorsBnds = ControlBoundingSlider('Colors', horizontal=False) self._heatmapVarsList = ControlCombo('Variables') self._heatmapVars = ControlCheckBox('Map variables') self._heatMapMinVar = ControlText('Min vel.') self._heatMapMaxVar = ControlText('Max vel.') ############################################################################################# self._modules_tabs.update({ 'Heat map': [('_heatmapColor', ' | ', 'Filters:', '_toggleHeatmapVars', '_toggleSphereVisibility', '_sphere', ' | ', '_apply2Heatmap', ' '), ('_heatmapVarsList', '_heatmapVars', '_heatmapHigherVarsValues', '_heatMapMinVar', '_heatmapVarsBnds', '_heatMapMaxVar'), { 'Map': ('_heatmap', '_heatmapColorsBnds') }] }) ############################################################################################# self._heatmapVarsList += 'Velocity' self._heatmapVarsList += 'Acceleration' self._heatmapColor.add_item('Bone', vv.CM_BONE) self._heatmapColor.add_item('Cool', vv.CM_COOL) self._heatmapColor.add_item('Copper', vv.CM_COPPER) self._heatmapColor.add_item('Gray', vv.CM_GRAY) self._heatmapColor.add_item('Hot', vv.CM_HOT) self._heatmapColor.add_item('HSV', vv.CM_HSV) self._heatmapColor.add_item('Jet', vv.CM_JET) self._heatmapColor.add_item('Pink', vv.CM_PINK) self._heatmapColor.add_item('Autumn', vv.CM_AUTUMN) self._heatmapColor.add_item('Spring', vv.CM_SPRING) self._heatmapColor.add_item('Summer', vv.CM_SUMMER) self._heatmapColor.add_item('Winter', vv.CM_WINTER) self._heatmapColor.value = vv.CM_HSV self._sphere.hide() self._heatmapVarsBnds.hide() self._heatmapVarsList.hide() self._heatMapMinVar.hide() self._heatMapMaxVar.hide() self._heatmapVars.hide() self._heatmapHigherVarsValues.hide() self._heatmapVarsBnds.convert_2_int = False self._heatmapColorsBnds.convert_2_int = False self._apply2Heatmap.value = self.calculate_heatmap_event self._heatmapColor.changed = self.changed_heatmap_color_event self._toggleSphereVisibility.value = self.__toggle_sphere_visiblity_event self._toggleHeatmapVars.value = self.__toggle_variables_visibility_event self._heatmapVarsList.changed = self.__changed_heatmap_variables_list_event self._heatMapMinVar.changed = self.__changed_heatmap_minVar_event self._heatMapMaxVar.changed = self.__changed_heatmap_maxVar_event self._heatmapColorsBnds.changed = self.changed_heatmap_colors_bounds_event self._heatmapVars.changed = self.__changed_heatmap_variables_event ############################################################################################ ### AUXILIAR FUNCTIONS ##################################################################### ############################################################################################ def __calc_heatmap_size(self, x_diff, y_diff, z_diff, scale=None): """ Calculate the heatmap size """ if scale == None: scale = self.fit_scale(x_size, y_size, z_size) x_scaled_size = int(round((x_diff + 1) * scale)) y_scaled_size = int(round((y_diff + 1) * scale)) z_scaled_size = int(round((z_diff + 1) * scale)) return x_scaled_size, y_scaled_size, z_scaled_size def fit_scale(self, x_diff, y_diff, z_diff): """ Calculate the scale value that should be applied to each position, so they can fit in an numpy array """ scale = 1.0 new_scale = 1.0 x_size, y_size, z_size = 0, 0, 0 #The maximum allowed size for the heatmap is (2000,2000,2000) while x_size <= 2000.0 and y_size <= 2000.0 and z_size <= 2000.0: scale = new_scale new_scale = scale * 10.0 x_size, y_size, z_size = self.__calc_heatmap_size( x_diff, y_diff, z_diff, new_scale) return scale ############################################################################################ ### EVENTS ################################################################################# ############################################################################################ def __changed_heatmap_variables_event(self): if self._heatmapVars.value: self._heatmapHigherVarsValues.show() else: self._heatmapHigherVarsValues.hide() def __toggle_sphere_visiblity_event(self): if self._toggleSphereVisibility.checked: self._sphere.show() else: self._sphere.hide() def __toggle_variables_visibility_event(self): if self._toggleHeatmapVars.checked: self._heatmapVarsList.show() self._heatmapVarsBnds.show() self._heatMapMinVar.show() self._heatMapMaxVar.show() self._heatmapVars.show() else: self._heatmapVarsList.hide() self._heatmapVarsBnds.hide() self._heatMapMinVar.hide() self._heatMapMaxVar.hide() self._heatmapVars.hide() def changed_heatmap_colors_bounds_event(self): if self._heatmapImg is None or not self._heatmapImg.any(): return self._heatmap.colors_limits = self._heatmapColorsBnds.value def __changed_heatmap_minVar_event(self): if self._heatMapMinVar.value == '': return v = eval(self._heatMapMinVar.value) self._heatmapVarsBnds.min = v values = list(self._heatmapVarsBnds.value) if values[0] < v: values[0] = v self._heatmapVarsBnds.value = values def __changed_heatmap_maxVar_event(self): if self._heatMapMaxVar.value == '': return v = eval(self._heatMapMaxVar.value) self._heatmapVarsBnds.max = v values = list(self._heatmapVarsBnds.value) if values[1] > v: values[1] = v self._heatmapVarsBnds.value = values def __changed_heatmap_variables_list_event(self): if self._heatmapVarsList.value == 'Velocity' and self._velocities: lower = int(0 if self._boundings.value[0] < 0 else self._boundings. value[0]) higher = int( len(self._velocities) if self._boundings.value[1] >= len( self._velocities) else self._boundings.value[1]) max_val = max(self._velocities[lower:higher]) min_val = min(self._velocities[lower:higher]) self._heatmapVarsBnds.value = round(min_val, 2), round(max_val, 2) self._heatMapMinVar.value = str( round(min_val - (max_val - min_val) * 0.1, 2)) self._heatMapMaxVar.value = str( round(max_val + (max_val - min_val) * 0.1, 2)) if self._heatmapVarsList.value == 'Acceleration' and self._accelerations: lower = int(0 if self._boundings.value[0] < 0 else self._boundings. value[0]) higher = int( len(self._accelerations) if self._boundings.value[1] > (len(self._accelerations) + 1) else self._boundings.value[1]) max_val = max(self._accelerations[lower:higher]) min_val = min(self._accelerations[lower:higher]) self._heatmapVarsBnds.value = round(min_val, 2), round(max_val, 2) self._heatMapMinVar.value = str( round(min_val - (max_val - min_val) * 0.1, 2)) self._heatMapMaxVar.value = str( round(max_val + (max_val - min_val) * 0.1, 2)) def changed_heatmap_color_event(self): self._heatmap.colorMap = self._heatmapColor.value ############################################################################################ ### Map generation ######################################################################### ############################################################################################ def calculate_heatmap_event(self): #Filter for the data from a lower and upper frame if self._data is None: return self._progress.min = lower = 0 if self._boundings.value[0] < 0 else int( self._boundings.value[0]) self._progress.max = higher = len( self._data) if self._boundings.value[1] > ( len(self._data) + 1) else int(self._boundings.value[1]) #Calculate the size of the map x_diff = self._data.xRange[1] - self._data.xRange[0] y_diff = self._data.yRange[1] - self._data.yRange[0] z_diff = self._data.zRange[1] - self._data.zRange[0] scale = self.fit_scale(x_diff, y_diff, z_diff) #Fit the best scale value x_size, y_size, z_size = self.__calc_heatmap_size( x_diff, y_diff, z_diff, scale) #Return the best size for the map image try: sphere = sphere_x, sphere_y, sphere_z, sphere_r = eval( self._sphere.value) except: sphere = None min_var, max_var = self._heatmapVarsBnds.value which_var = 0 if self._heatmapVarsList.value == 'Velocity' else 1 #Create the map image img = np.zeros((z_size, x_size, y_size), dtype=np.float32) for i in range(lower, higher): if (i % 3000) == 0: self._progress.value = i if self._data[i] != None: position = self._data[i].position #shift and scale the coordenates, to avoid negative and decimal values #is only possible to map in the image positive and integer coordenates x, y, z = position x += abs(self._data.xRange[0]) y += abs(self._data.yRange[0]) z += abs(self._data.zRange[0]) x = int(round(x * scale)) y = int(round(y * scale)) z = int(round(z * scale)) #Filter position by a defined sphere if sphere != None and lin_dist3d( (x, y, z), (sphere_x, sphere_y, sphere_z)) > sphere_r: continue #Use variables to construct the map, or positions if self._toggleHeatmapVars.checked: #velocities array has less 1 element than positions array if which_var == 0 and len(self._velocities) <= i: continue #accelarations array has less 2 element than positions array if which_var == 1 and len(self._accelerations) <= i: continue var = self._velocities[ i] if which_var == 0 else self._accelerations[i] #Filter by variable boundaries if not (min_var <= var <= max_var): continue if self._heatmapVars.value: #Map the variables if self._heatmapHigherVarsValues.value: tmp = img[z - 1:z + 1, x - 1:x + 1, y - 1:y + 1] tmp[tmp < var] = var else: img[z - 1:z + 1, x - 1:x + 1, y - 1:y + 1] += var else: #Map positions img[z - 1:z + 1, x - 1:x + 1, y - 1:y + 1] += 1.0 else: #Map positions img[z - 1:z + 1, x - 1:x + 1, y - 1:y + 1] += 1.0 self._progress.value = higher color_min = np.min(img) color_max = np.max(img) self._heatmapColorsBnds.min = color_min - (color_max - color_min) * 0.1 self._heatmapColorsBnds.max = color_max + (color_max - color_min) * 0.1 self._heatmapColorsBnds.value = color_min, color_max self._heatmap.value = np.zeros((1, 1), dtype=np.float32) self._heatmap.colors_limits = None self._heatmap.value = img self._heatmapImg = img ############################################################################################ ### CLASS OVERRIDE FUNCTIONS ############################################################### ############################################################################################ def frames_boundings_changed(self): super(HeatMapApp, self).frames_boundings_changed() self.__changed_heatmap_variables_list_event() def load_tracking_file(self): super(HeatMapApp, self).load_tracking_file() self.__changed_heatmap_variables_list_event() def export_tracking_file(self): filename, _ = QFileDialog.getSaveFileName(self, 'Select a file', selectedFilter='*.csv') if not filename: return filename = str(filename) if not filename.lower().endswith('.csv'): filename += '.csv' #Export only the selected bounds lower = 0 if self._boundings.value[0] < 0 else self._boundings.value[0] higher = len(self._data) if self._boundings.value[1] > ( len(self._data) + 1) else self._boundings.value[1] self._progress.min = lower self._progress.max = higher which_var = 0 if self._heatmapVarsList.value == 'Velocity' else 1 try: sphere = sphere_x, sphere_y, sphere_z, sphere_r = eval( self._sphere.value) except: sphere = None min_var, max_var = self._heatmapVarsBnds.value #Calculate the size of the map x_diff = self._data.xRange[1] - self._data.xRange[0] y_diff = self._data.yRange[1] - self._data.yRange[0] z_diff = self._data.zRange[1] - self._data.zRange[0] scale = self.fit_scale(x_diff, y_diff, z_diff) #Fit the best scale value with open(filename, 'wb') as csvfile: spamwriter = csv.writer(csvfile, delimiter=',') for i in range(int(lower), int(higher)): self._progress.value = i position = self._data[i].position x, y, z = position x += abs(self._data.xRange[0]) y += abs(self._data.yRange[0]) z += abs(self._data.zRange[0]) x = int(round(x * scale)) y = int(round(y * scale)) z = int(round(z * scale)) if sphere != None and lin_dist3d( (x, y, z), (sphere_x, sphere_y, sphere_z)) > sphere_r: continue if self._toggleHeatmapVars.checked: var = self._velocities[ i] if which_var == 0 else self._accelerations[i] if not (min_var <= var <= max_var): continue if self._data[i] == None: continue row2save = self._data[i].row if i > lower: row2save = row2save + [self._velocities[i]] if (i + 1) > lower: row2save = row2save + [self._accelerations[i]] spamwriter.writerow(row2save)