boris-behav-obs 8.16.5__py3-none-any.whl → 9.7.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- boris/__init__.py +1 -1
- boris/__main__.py +1 -1
- boris/about.py +24 -36
- boris/add_modifier.py +88 -80
- boris/add_modifier_ui.py +235 -131
- boris/advanced_event_filtering.py +23 -29
- boris/analysis_plugins/__init__.py +0 -0
- boris/analysis_plugins/_latency.py +59 -0
- boris/analysis_plugins/irr_cohen_kappa.py +109 -0
- boris/analysis_plugins/irr_cohen_kappa_with_modifiers.py +112 -0
- boris/analysis_plugins/irr_weighted_cohen_kappa.py +157 -0
- boris/analysis_plugins/irr_weighted_cohen_kappa_with_modifiers.py +162 -0
- boris/analysis_plugins/list_of_dataframe_columns.py +22 -0
- boris/analysis_plugins/number_of_occurences.py +22 -0
- boris/analysis_plugins/number_of_occurences_by_independent_variable.py +54 -0
- boris/analysis_plugins/time_budget.py +61 -0
- boris/behav_coding_map_creator.py +228 -229
- boris/behavior_binary_table.py +33 -50
- boris/behaviors_coding_map.py +17 -18
- boris/boris_cli.py +6 -25
- boris/cmd_arguments.py +12 -1
- boris/coding_pad.py +16 -34
- boris/config.py +102 -50
- boris/config_file.py +55 -64
- boris/connections.py +105 -58
- boris/converters.py +13 -37
- boris/converters_ui.py +187 -110
- boris/cooccurence.py +250 -0
- boris/core.py +2108 -1275
- boris/core_qrc.py +15892 -10829
- boris/core_ui.py +941 -806
- boris/db_functions.py +17 -42
- boris/dev.py +27 -7
- boris/dialog.py +461 -242
- boris/duration_widget.py +9 -14
- boris/edit_event.py +61 -31
- boris/edit_event_ui.py +208 -97
- boris/event_operations.py +405 -281
- boris/events_cursor.py +25 -17
- boris/events_snapshots.py +36 -82
- boris/exclusion_matrix.py +4 -9
- boris/export_events.py +180 -203
- boris/export_observation.py +60 -73
- boris/external_processes.py +123 -98
- boris/geometric_measurement.py +427 -218
- boris/gui_utilities.py +91 -14
- boris/image_overlay.py +4 -4
- boris/import_observations.py +190 -98
- boris/ipc_mpv.py +304 -0
- boris/irr.py +20 -57
- boris/latency.py +31 -24
- boris/measurement_widget.py +14 -18
- boris/media_file.py +17 -19
- boris/menu_options.py +16 -6
- boris/modifier_coding_map_creator.py +1013 -0
- boris/modifiers_coding_map.py +7 -9
- boris/mpv2.py +128 -35
- boris/observation.py +493 -210
- boris/observation_operations.py +1010 -391
- boris/observation_ui.py +573 -363
- boris/observations_list.py +51 -58
- boris/otx_parser.py +74 -68
- boris/param_panel.py +45 -59
- boris/param_panel_ui.py +254 -138
- boris/player_dock_widget.py +91 -56
- boris/plot_data_module.py +18 -53
- boris/plot_events.py +56 -153
- boris/plot_events_rt.py +16 -30
- boris/plot_spectrogram_rt.py +80 -56
- boris/plot_waveform_rt.py +23 -48
- boris/plugins.py +431 -0
- boris/portion/__init__.py +18 -8
- boris/portion/const.py +35 -18
- boris/portion/dict.py +5 -5
- boris/portion/func.py +2 -2
- boris/portion/interval.py +21 -41
- boris/portion/io.py +41 -32
- boris/preferences.py +298 -123
- boris/preferences_ui.py +664 -225
- boris/project.py +293 -270
- boris/project_functions.py +610 -537
- boris/project_import_export.py +204 -213
- boris/project_ui.py +673 -441
- boris/qrc_boris.py +6 -3
- boris/qrc_boris5.py +6 -3
- boris/select_modifiers.py +62 -90
- boris/select_observations.py +19 -197
- boris/select_subj_behav.py +67 -39
- boris/state_events.py +51 -33
- boris/subjects_pad.py +6 -8
- boris/synthetic_time_budget.py +42 -26
- boris/time_budget_functions.py +169 -169
- boris/time_budget_widget.py +77 -89
- boris/transitions.py +41 -41
- boris/utilities.py +562 -222
- boris/version.py +3 -3
- boris/video_equalizer.py +16 -14
- boris/video_equalizer_ui.py +199 -130
- boris/video_operations.py +78 -28
- boris/view_df.py +104 -0
- boris/view_df_ui.py +75 -0
- boris/write_event.py +240 -136
- boris_behav_obs-9.7.1.dist-info/METADATA +140 -0
- boris_behav_obs-9.7.1.dist-info/RECORD +109 -0
- {boris_behav_obs-8.16.5.dist-info → boris_behav_obs-9.7.1.dist-info}/WHEEL +1 -1
- boris_behav_obs-9.7.1.dist-info/entry_points.txt +2 -0
- boris/README.TXT +0 -22
- boris/add_modifier.ui +0 -323
- boris/converters.ui +0 -289
- boris/core.qrc +0 -37
- boris/core.ui +0 -1571
- boris/edit_event.ui +0 -233
- boris/icons/logo_eye.ico +0 -0
- boris/map_creator.py +0 -982
- boris/observation.ui +0 -814
- boris/param_panel.ui +0 -379
- boris/preferences.ui +0 -537
- boris/project.ui +0 -1074
- boris/vlc_local.py +0 -90
- boris_behav_obs-8.16.5.dist-info/LICENSE.TXT +0 -674
- boris_behav_obs-8.16.5.dist-info/METADATA +0 -134
- boris_behav_obs-8.16.5.dist-info/RECORD +0 -107
- boris_behav_obs-8.16.5.dist-info/entry_points.txt +0 -2
- {boris → boris_behav_obs-9.7.1.dist-info/licenses}/LICENSE.TXT +0 -0
- {boris_behav_obs-8.16.5.dist-info → boris_behav_obs-9.7.1.dist-info}/top_level.txt +0 -0
boris/version.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2025 Olivier Friard
|
|
5
5
|
|
|
6
6
|
This file is part of BORIS.
|
|
7
7
|
|
|
@@ -20,5 +20,5 @@ This file is part of BORIS.
|
|
|
20
20
|
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
|
-
__version__ = "
|
|
24
|
-
__version_date__ = "
|
|
23
|
+
__version__ = "9.7.1"
|
|
24
|
+
__version_date__ = "2025-10-22"
|
boris/video_equalizer.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2025 Olivier Friard
|
|
5
5
|
|
|
6
6
|
This file is part of BORIS.
|
|
7
7
|
|
|
@@ -20,8 +20,8 @@ This file is part of BORIS.
|
|
|
20
20
|
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
|
-
from
|
|
24
|
-
from
|
|
23
|
+
from PySide6.QtWidgets import QDialog
|
|
24
|
+
from PySide6.QtCore import Signal, QEvent
|
|
25
25
|
from .video_equalizer_ui import Ui_Equalizer
|
|
26
26
|
|
|
27
27
|
|
|
@@ -30,8 +30,8 @@ class Video_equalizer(QDialog, Ui_Equalizer):
|
|
|
30
30
|
management of video equalizer: brightness, saturation, contrast, gamma and hue
|
|
31
31
|
"""
|
|
32
32
|
|
|
33
|
-
sendEventSignal =
|
|
34
|
-
sendKeyPressSignal =
|
|
33
|
+
sendEventSignal = Signal(int, str, int)
|
|
34
|
+
sendKeyPressSignal = Signal(QEvent)
|
|
35
35
|
|
|
36
36
|
def __init__(self, equalizer, parent=None):
|
|
37
37
|
super().__init__(parent)
|
|
@@ -56,7 +56,7 @@ class Video_equalizer(QDialog, Ui_Equalizer):
|
|
|
56
56
|
|
|
57
57
|
self.initialize(0)
|
|
58
58
|
|
|
59
|
-
def initialize(self, n_player):
|
|
59
|
+
def initialize(self, n_player: int) -> None:
|
|
60
60
|
if n_player not in self.equalizer:
|
|
61
61
|
return
|
|
62
62
|
|
|
@@ -76,7 +76,6 @@ class Video_equalizer(QDialog, Ui_Equalizer):
|
|
|
76
76
|
self.lb_hue.setText(str(self.equalizer[n_player]["hs_hue"]))
|
|
77
77
|
|
|
78
78
|
def player_changed(self, index):
|
|
79
|
-
|
|
80
79
|
self.initialize(index)
|
|
81
80
|
|
|
82
81
|
def reset(self):
|
|
@@ -102,8 +101,11 @@ class Video_equalizer(QDialog, Ui_Equalizer):
|
|
|
102
101
|
"""
|
|
103
102
|
if self.cb_player.currentIndex() not in self.equalizer:
|
|
104
103
|
return
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
|
|
105
|
+
print(type(self.sender().value()))
|
|
106
|
+
|
|
107
|
+
self.equalizer[self.cb_player.currentIndex()][self.sender().objectName()] = round(self.sender().value())
|
|
108
|
+
self.sendEventSignal.emit(self.cb_player.currentIndex(), self.sender().objectName(), round(self.sender().value()))
|
|
107
109
|
|
|
108
110
|
self.initialize(self.cb_player.currentIndex())
|
|
109
111
|
|
|
@@ -142,11 +144,11 @@ def video_equalizer_show(self):
|
|
|
142
144
|
equalizer = {}
|
|
143
145
|
for n_player, _ in enumerate(self.dw_player):
|
|
144
146
|
equalizer[n_player] = {
|
|
145
|
-
"hs_brightness": self.dw_player[n_player].player.brightness,
|
|
146
|
-
"hs_contrast": self.dw_player[n_player].player.contrast,
|
|
147
|
-
"hs_saturation": self.dw_player[n_player].player.saturation,
|
|
148
|
-
"hs_gamma": self.dw_player[n_player].player.gamma,
|
|
149
|
-
"hs_hue": self.dw_player[n_player].player.hue,
|
|
147
|
+
"hs_brightness": round(self.dw_player[n_player].player.brightness),
|
|
148
|
+
"hs_contrast": round(self.dw_player[n_player].player.contrast),
|
|
149
|
+
"hs_saturation": round(self.dw_player[n_player].player.saturation),
|
|
150
|
+
"hs_gamma": round(self.dw_player[n_player].player.gamma),
|
|
151
|
+
"hs_hue": round(self.dw_player[n_player].player.hue),
|
|
150
152
|
}
|
|
151
153
|
|
|
152
154
|
self.video_equalizer_wgt = Video_equalizer(equalizer)
|
boris/video_equalizer_ui.py
CHANGED
|
@@ -1,179 +1,248 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
from PyQt5 import QtCore, QtGui, QtWidgets
|
|
3
|
+
################################################################################
|
|
4
|
+
## Form generated from reading UI file 'video_equalizer.ui'
|
|
5
|
+
##
|
|
6
|
+
## Created by: Qt User Interface Compiler version 6.8.0
|
|
7
|
+
##
|
|
8
|
+
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
|
9
|
+
################################################################################
|
|
12
10
|
|
|
11
|
+
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
|
12
|
+
QMetaObject, QObject, QPoint, QRect,
|
|
13
|
+
QSize, QTime, QUrl, Qt)
|
|
14
|
+
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
|
15
|
+
QFont, QFontDatabase, QGradient, QIcon,
|
|
16
|
+
QImage, QKeySequence, QLinearGradient, QPainter,
|
|
17
|
+
QPalette, QPixmap, QRadialGradient, QTransform)
|
|
18
|
+
from PySide6.QtWidgets import (QApplication, QComboBox, QHBoxLayout, QLabel,
|
|
19
|
+
QPushButton, QSizePolicy, QSlider, QSpacerItem,
|
|
20
|
+
QVBoxLayout, QWidget)
|
|
13
21
|
|
|
14
22
|
class Ui_Equalizer(object):
|
|
15
23
|
def setupUi(self, Equalizer):
|
|
16
|
-
Equalizer.
|
|
24
|
+
if not Equalizer.objectName():
|
|
25
|
+
Equalizer.setObjectName(u"Equalizer")
|
|
17
26
|
Equalizer.resize(388, 284)
|
|
18
|
-
self.verticalLayout =
|
|
19
|
-
self.verticalLayout.setObjectName("verticalLayout")
|
|
20
|
-
self.label_6 =
|
|
21
|
-
|
|
27
|
+
self.verticalLayout = QVBoxLayout(Equalizer)
|
|
28
|
+
self.verticalLayout.setObjectName(u"verticalLayout")
|
|
29
|
+
self.label_6 = QLabel(Equalizer)
|
|
30
|
+
self.label_6.setObjectName(u"label_6")
|
|
31
|
+
sizePolicy = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
|
|
22
32
|
sizePolicy.setHorizontalStretch(0)
|
|
23
33
|
sizePolicy.setVerticalStretch(0)
|
|
24
34
|
sizePolicy.setHeightForWidth(self.label_6.sizePolicy().hasHeightForWidth())
|
|
25
35
|
self.label_6.setSizePolicy(sizePolicy)
|
|
26
|
-
font =
|
|
36
|
+
font = QFont()
|
|
27
37
|
font.setBold(True)
|
|
28
|
-
font.setWeight(75)
|
|
29
38
|
self.label_6.setFont(font)
|
|
30
|
-
|
|
39
|
+
|
|
31
40
|
self.verticalLayout.addWidget(self.label_6)
|
|
32
|
-
|
|
33
|
-
self.cb_player
|
|
41
|
+
|
|
42
|
+
self.cb_player = QComboBox(Equalizer)
|
|
43
|
+
self.cb_player.setObjectName(u"cb_player")
|
|
44
|
+
|
|
34
45
|
self.verticalLayout.addWidget(self.cb_player)
|
|
35
|
-
|
|
36
|
-
self.horizontalLayout
|
|
37
|
-
self.
|
|
38
|
-
self.label
|
|
39
|
-
self.label.
|
|
40
|
-
self.label.
|
|
46
|
+
|
|
47
|
+
self.horizontalLayout = QHBoxLayout()
|
|
48
|
+
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
|
49
|
+
self.label = QLabel(Equalizer)
|
|
50
|
+
self.label.setObjectName(u"label")
|
|
51
|
+
self.label.setMinimumSize(QSize(70, 0))
|
|
52
|
+
self.label.setMaximumSize(QSize(70, 16777215))
|
|
53
|
+
|
|
41
54
|
self.horizontalLayout.addWidget(self.label)
|
|
42
|
-
|
|
43
|
-
self.hs_brightness
|
|
44
|
-
self.hs_brightness.
|
|
55
|
+
|
|
56
|
+
self.hs_brightness = QSlider(Equalizer)
|
|
57
|
+
self.hs_brightness.setObjectName(u"hs_brightness")
|
|
58
|
+
self.hs_brightness.setMinimumSize(QSize(200, 0))
|
|
59
|
+
self.hs_brightness.setMaximumSize(QSize(200, 16777215))
|
|
45
60
|
self.hs_brightness.setMinimum(-100)
|
|
46
|
-
self.hs_brightness.
|
|
47
|
-
self.hs_brightness.setOrientation(
|
|
48
|
-
|
|
61
|
+
self.hs_brightness.setValue(0)
|
|
62
|
+
self.hs_brightness.setOrientation(Qt.Horizontal)
|
|
63
|
+
|
|
49
64
|
self.horizontalLayout.addWidget(self.hs_brightness)
|
|
50
|
-
|
|
51
|
-
self.lb_brightness
|
|
52
|
-
self.lb_brightness.
|
|
53
|
-
self.lb_brightness.
|
|
65
|
+
|
|
66
|
+
self.lb_brightness = QLabel(Equalizer)
|
|
67
|
+
self.lb_brightness.setObjectName(u"lb_brightness")
|
|
68
|
+
self.lb_brightness.setMinimumSize(QSize(25, 0))
|
|
69
|
+
self.lb_brightness.setMaximumSize(QSize(25, 16777215))
|
|
70
|
+
|
|
54
71
|
self.horizontalLayout.addWidget(self.lb_brightness)
|
|
72
|
+
|
|
73
|
+
|
|
55
74
|
self.verticalLayout.addLayout(self.horizontalLayout)
|
|
56
|
-
|
|
57
|
-
self.horizontalLayout_2
|
|
58
|
-
self.
|
|
59
|
-
self.label_2
|
|
60
|
-
self.label_2.
|
|
61
|
-
self.label_2.
|
|
75
|
+
|
|
76
|
+
self.horizontalLayout_2 = QHBoxLayout()
|
|
77
|
+
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
|
|
78
|
+
self.label_2 = QLabel(Equalizer)
|
|
79
|
+
self.label_2.setObjectName(u"label_2")
|
|
80
|
+
self.label_2.setMinimumSize(QSize(70, 0))
|
|
81
|
+
self.label_2.setMaximumSize(QSize(70, 16777215))
|
|
82
|
+
|
|
62
83
|
self.horizontalLayout_2.addWidget(self.label_2)
|
|
63
|
-
|
|
64
|
-
self.hs_contrast
|
|
65
|
-
self.hs_contrast.
|
|
84
|
+
|
|
85
|
+
self.hs_contrast = QSlider(Equalizer)
|
|
86
|
+
self.hs_contrast.setObjectName(u"hs_contrast")
|
|
87
|
+
self.hs_contrast.setMinimumSize(QSize(200, 0))
|
|
88
|
+
self.hs_contrast.setMaximumSize(QSize(200, 16777215))
|
|
66
89
|
self.hs_contrast.setMinimum(-100)
|
|
67
|
-
self.hs_contrast.
|
|
68
|
-
self.hs_contrast.setOrientation(
|
|
69
|
-
|
|
90
|
+
self.hs_contrast.setValue(0)
|
|
91
|
+
self.hs_contrast.setOrientation(Qt.Horizontal)
|
|
92
|
+
|
|
70
93
|
self.horizontalLayout_2.addWidget(self.hs_contrast)
|
|
71
|
-
|
|
72
|
-
self.lb_contrast
|
|
73
|
-
self.lb_contrast.
|
|
74
|
-
self.lb_contrast.
|
|
94
|
+
|
|
95
|
+
self.lb_contrast = QLabel(Equalizer)
|
|
96
|
+
self.lb_contrast.setObjectName(u"lb_contrast")
|
|
97
|
+
self.lb_contrast.setMinimumSize(QSize(25, 0))
|
|
98
|
+
self.lb_contrast.setMaximumSize(QSize(25, 16777215))
|
|
99
|
+
|
|
75
100
|
self.horizontalLayout_2.addWidget(self.lb_contrast)
|
|
101
|
+
|
|
102
|
+
|
|
76
103
|
self.verticalLayout.addLayout(self.horizontalLayout_2)
|
|
77
|
-
|
|
78
|
-
self.horizontalLayout_3
|
|
79
|
-
self.
|
|
80
|
-
self.label_3
|
|
81
|
-
self.label_3.
|
|
82
|
-
self.label_3.
|
|
104
|
+
|
|
105
|
+
self.horizontalLayout_3 = QHBoxLayout()
|
|
106
|
+
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
|
107
|
+
self.label_3 = QLabel(Equalizer)
|
|
108
|
+
self.label_3.setObjectName(u"label_3")
|
|
109
|
+
self.label_3.setMinimumSize(QSize(70, 0))
|
|
110
|
+
self.label_3.setMaximumSize(QSize(70, 16777215))
|
|
111
|
+
|
|
83
112
|
self.horizontalLayout_3.addWidget(self.label_3)
|
|
84
|
-
|
|
85
|
-
self.hs_saturation
|
|
86
|
-
self.hs_saturation.
|
|
113
|
+
|
|
114
|
+
self.hs_saturation = QSlider(Equalizer)
|
|
115
|
+
self.hs_saturation.setObjectName(u"hs_saturation")
|
|
116
|
+
self.hs_saturation.setMinimumSize(QSize(200, 0))
|
|
117
|
+
self.hs_saturation.setMaximumSize(QSize(200, 16777215))
|
|
87
118
|
self.hs_saturation.setMinimum(-100)
|
|
88
|
-
self.hs_saturation.
|
|
89
|
-
self.hs_saturation.setOrientation(
|
|
90
|
-
|
|
119
|
+
self.hs_saturation.setValue(0)
|
|
120
|
+
self.hs_saturation.setOrientation(Qt.Horizontal)
|
|
121
|
+
|
|
91
122
|
self.horizontalLayout_3.addWidget(self.hs_saturation)
|
|
92
|
-
|
|
93
|
-
self.lb_saturation
|
|
94
|
-
self.lb_saturation.
|
|
95
|
-
self.lb_saturation.
|
|
123
|
+
|
|
124
|
+
self.lb_saturation = QLabel(Equalizer)
|
|
125
|
+
self.lb_saturation.setObjectName(u"lb_saturation")
|
|
126
|
+
self.lb_saturation.setMinimumSize(QSize(25, 0))
|
|
127
|
+
self.lb_saturation.setMaximumSize(QSize(25, 16777215))
|
|
128
|
+
|
|
96
129
|
self.horizontalLayout_3.addWidget(self.lb_saturation)
|
|
130
|
+
|
|
131
|
+
|
|
97
132
|
self.verticalLayout.addLayout(self.horizontalLayout_3)
|
|
98
|
-
|
|
99
|
-
self.horizontalLayout_4
|
|
100
|
-
self.
|
|
101
|
-
self.label_4
|
|
102
|
-
self.label_4.
|
|
103
|
-
self.label_4.
|
|
133
|
+
|
|
134
|
+
self.horizontalLayout_4 = QHBoxLayout()
|
|
135
|
+
self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
|
|
136
|
+
self.label_4 = QLabel(Equalizer)
|
|
137
|
+
self.label_4.setObjectName(u"label_4")
|
|
138
|
+
self.label_4.setMinimumSize(QSize(70, 0))
|
|
139
|
+
self.label_4.setMaximumSize(QSize(70, 16777215))
|
|
140
|
+
|
|
104
141
|
self.horizontalLayout_4.addWidget(self.label_4)
|
|
105
|
-
|
|
106
|
-
self.hs_gamma
|
|
107
|
-
self.hs_gamma.
|
|
142
|
+
|
|
143
|
+
self.hs_gamma = QSlider(Equalizer)
|
|
144
|
+
self.hs_gamma.setObjectName(u"hs_gamma")
|
|
145
|
+
self.hs_gamma.setMinimumSize(QSize(200, 0))
|
|
146
|
+
self.hs_gamma.setMaximumSize(QSize(200, 16777215))
|
|
108
147
|
self.hs_gamma.setMinimum(-100)
|
|
109
|
-
self.hs_gamma.
|
|
110
|
-
self.hs_gamma.setOrientation(
|
|
111
|
-
|
|
148
|
+
self.hs_gamma.setValue(0)
|
|
149
|
+
self.hs_gamma.setOrientation(Qt.Horizontal)
|
|
150
|
+
|
|
112
151
|
self.horizontalLayout_4.addWidget(self.hs_gamma)
|
|
113
|
-
|
|
114
|
-
self.lb_gamma
|
|
115
|
-
self.lb_gamma.
|
|
116
|
-
self.lb_gamma.
|
|
152
|
+
|
|
153
|
+
self.lb_gamma = QLabel(Equalizer)
|
|
154
|
+
self.lb_gamma.setObjectName(u"lb_gamma")
|
|
155
|
+
self.lb_gamma.setMinimumSize(QSize(25, 0))
|
|
156
|
+
self.lb_gamma.setMaximumSize(QSize(25, 16777215))
|
|
157
|
+
|
|
117
158
|
self.horizontalLayout_4.addWidget(self.lb_gamma)
|
|
159
|
+
|
|
160
|
+
|
|
118
161
|
self.verticalLayout.addLayout(self.horizontalLayout_4)
|
|
119
|
-
|
|
120
|
-
self.horizontalLayout_5
|
|
121
|
-
self.
|
|
122
|
-
self.label_5
|
|
123
|
-
self.label_5.
|
|
124
|
-
self.label_5.
|
|
162
|
+
|
|
163
|
+
self.horizontalLayout_5 = QHBoxLayout()
|
|
164
|
+
self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
|
|
165
|
+
self.label_5 = QLabel(Equalizer)
|
|
166
|
+
self.label_5.setObjectName(u"label_5")
|
|
167
|
+
self.label_5.setMinimumSize(QSize(70, 0))
|
|
168
|
+
self.label_5.setMaximumSize(QSize(70, 16777215))
|
|
169
|
+
|
|
125
170
|
self.horizontalLayout_5.addWidget(self.label_5)
|
|
126
|
-
|
|
127
|
-
self.hs_hue
|
|
128
|
-
self.hs_hue.
|
|
171
|
+
|
|
172
|
+
self.hs_hue = QSlider(Equalizer)
|
|
173
|
+
self.hs_hue.setObjectName(u"hs_hue")
|
|
174
|
+
self.hs_hue.setMinimumSize(QSize(200, 0))
|
|
175
|
+
self.hs_hue.setMaximumSize(QSize(200, 16777215))
|
|
129
176
|
self.hs_hue.setMinimum(-100)
|
|
130
|
-
self.hs_hue.
|
|
131
|
-
self.hs_hue.setOrientation(
|
|
132
|
-
|
|
177
|
+
self.hs_hue.setValue(0)
|
|
178
|
+
self.hs_hue.setOrientation(Qt.Horizontal)
|
|
179
|
+
|
|
133
180
|
self.horizontalLayout_5.addWidget(self.hs_hue)
|
|
134
|
-
|
|
135
|
-
self.lb_hue
|
|
136
|
-
self.lb_hue.
|
|
137
|
-
self.lb_hue.
|
|
181
|
+
|
|
182
|
+
self.lb_hue = QLabel(Equalizer)
|
|
183
|
+
self.lb_hue.setObjectName(u"lb_hue")
|
|
184
|
+
self.lb_hue.setMinimumSize(QSize(25, 0))
|
|
185
|
+
self.lb_hue.setMaximumSize(QSize(25, 16777215))
|
|
186
|
+
|
|
138
187
|
self.horizontalLayout_5.addWidget(self.lb_hue)
|
|
188
|
+
|
|
189
|
+
|
|
139
190
|
self.verticalLayout.addLayout(self.horizontalLayout_5)
|
|
140
|
-
|
|
141
|
-
self.horizontalLayout_6
|
|
142
|
-
self.
|
|
143
|
-
self.pb_reset_all
|
|
191
|
+
|
|
192
|
+
self.horizontalLayout_6 = QHBoxLayout()
|
|
193
|
+
self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
|
|
194
|
+
self.pb_reset_all = QPushButton(Equalizer)
|
|
195
|
+
self.pb_reset_all.setObjectName(u"pb_reset_all")
|
|
196
|
+
|
|
144
197
|
self.horizontalLayout_6.addWidget(self.pb_reset_all)
|
|
145
|
-
|
|
146
|
-
self.pb_reset
|
|
198
|
+
|
|
199
|
+
self.pb_reset = QPushButton(Equalizer)
|
|
200
|
+
self.pb_reset.setObjectName(u"pb_reset")
|
|
201
|
+
|
|
147
202
|
self.horizontalLayout_6.addWidget(self.pb_reset)
|
|
203
|
+
|
|
204
|
+
|
|
148
205
|
self.verticalLayout.addLayout(self.horizontalLayout_6)
|
|
149
|
-
|
|
150
|
-
self.
|
|
151
|
-
|
|
152
|
-
self.
|
|
153
|
-
|
|
154
|
-
self.horizontalLayout_7
|
|
155
|
-
self.
|
|
156
|
-
self.
|
|
206
|
+
|
|
207
|
+
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
|
|
208
|
+
|
|
209
|
+
self.verticalLayout.addItem(self.verticalSpacer)
|
|
210
|
+
|
|
211
|
+
self.horizontalLayout_7 = QHBoxLayout()
|
|
212
|
+
self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
|
|
213
|
+
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
214
|
+
|
|
215
|
+
self.horizontalLayout_7.addItem(self.horizontalSpacer)
|
|
216
|
+
|
|
217
|
+
self.pb_close = QPushButton(Equalizer)
|
|
218
|
+
self.pb_close.setObjectName(u"pb_close")
|
|
219
|
+
|
|
157
220
|
self.horizontalLayout_7.addWidget(self.pb_close)
|
|
221
|
+
|
|
222
|
+
|
|
158
223
|
self.verticalLayout.addLayout(self.horizontalLayout_7)
|
|
159
224
|
|
|
225
|
+
|
|
160
226
|
self.retranslateUi(Equalizer)
|
|
161
|
-
|
|
227
|
+
|
|
228
|
+
QMetaObject.connectSlotsByName(Equalizer)
|
|
229
|
+
# setupUi
|
|
162
230
|
|
|
163
231
|
def retranslateUi(self, Equalizer):
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
self.
|
|
167
|
-
self.
|
|
168
|
-
self.
|
|
169
|
-
self.
|
|
170
|
-
self.
|
|
171
|
-
self.
|
|
172
|
-
self.
|
|
173
|
-
self.
|
|
174
|
-
self.
|
|
175
|
-
self.
|
|
176
|
-
self.
|
|
177
|
-
self.
|
|
178
|
-
self.
|
|
179
|
-
|
|
232
|
+
Equalizer.setWindowTitle(QCoreApplication.translate("Equalizer", u"Video equalizer", None))
|
|
233
|
+
self.label_6.setText(QCoreApplication.translate("Equalizer", u"Video equalizer", None))
|
|
234
|
+
self.label.setText(QCoreApplication.translate("Equalizer", u"Brightness", None))
|
|
235
|
+
self.lb_brightness.setText(QCoreApplication.translate("Equalizer", u"0", None))
|
|
236
|
+
self.label_2.setText(QCoreApplication.translate("Equalizer", u"Contrast", None))
|
|
237
|
+
self.lb_contrast.setText(QCoreApplication.translate("Equalizer", u"0", None))
|
|
238
|
+
self.label_3.setText(QCoreApplication.translate("Equalizer", u"Saturation", None))
|
|
239
|
+
self.lb_saturation.setText(QCoreApplication.translate("Equalizer", u"0", None))
|
|
240
|
+
self.label_4.setText(QCoreApplication.translate("Equalizer", u"Gamma", None))
|
|
241
|
+
self.lb_gamma.setText(QCoreApplication.translate("Equalizer", u"0", None))
|
|
242
|
+
self.label_5.setText(QCoreApplication.translate("Equalizer", u"Hue", None))
|
|
243
|
+
self.lb_hue.setText(QCoreApplication.translate("Equalizer", u"0", None))
|
|
244
|
+
self.pb_reset_all.setText(QCoreApplication.translate("Equalizer", u"Reset all players", None))
|
|
245
|
+
self.pb_reset.setText(QCoreApplication.translate("Equalizer", u"Reset current player", None))
|
|
246
|
+
self.pb_close.setText(QCoreApplication.translate("Equalizer", u"Close", None))
|
|
247
|
+
# retranslateUi
|
|
248
|
+
|
boris/video_operations.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2025 Olivier Friard
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
This program is free software; you can redistribute it and/or modify
|
|
@@ -26,7 +26,7 @@ import pathlib as pl
|
|
|
26
26
|
import shutil
|
|
27
27
|
from math import log2
|
|
28
28
|
|
|
29
|
-
from
|
|
29
|
+
from PySide6.QtWidgets import QFileDialog
|
|
30
30
|
|
|
31
31
|
from . import config as cfg
|
|
32
32
|
from . import dialog
|
|
@@ -79,20 +79,15 @@ def snapshot(self):
|
|
|
79
79
|
|
|
80
80
|
def zoom_level(self):
|
|
81
81
|
"""
|
|
82
|
-
display dialog for zoom level
|
|
82
|
+
display dialog box for setting the zoom level
|
|
83
83
|
"""
|
|
84
84
|
logging.info("change zoom level of player")
|
|
85
85
|
|
|
86
86
|
players_list: list = []
|
|
87
87
|
for idx, dw in enumerate(self.dw_player):
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
players_list.append(("il", f"Player #{idx + 1}", zoom_levels))
|
|
92
|
-
|
|
93
|
-
zl = dialog.Input_dialog(
|
|
94
|
-
label_caption="Select the zoom level", elements_list=players_list, title="Video zoom level"
|
|
95
|
-
)
|
|
88
|
+
players_list.append(("dsb", f"Player #{idx + 1}", 0.1, 12, 0.1, 2**dw.player.video_zoom, 1))
|
|
89
|
+
|
|
90
|
+
zl = dialog.Input_dialog(label_caption="Select the zoom level", elements_list=players_list, title="Video zoom level")
|
|
96
91
|
if not zl.exec_():
|
|
97
92
|
return
|
|
98
93
|
|
|
@@ -100,21 +95,64 @@ def zoom_level(self):
|
|
|
100
95
|
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.ZOOM_LEVEL] = {}
|
|
101
96
|
|
|
102
97
|
for idx, dw in enumerate(self.dw_player):
|
|
103
|
-
if
|
|
104
|
-
str(idx + 1), dw.player.video_zoom
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
"""
|
|
109
|
-
dw.player.video_pan_x = 0.25
|
|
110
|
-
dw.player.video_pan_x = 0.25
|
|
111
|
-
"""
|
|
98
|
+
if (
|
|
99
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.ZOOM_LEVEL].get(str(idx + 1), dw.player.video_zoom)
|
|
100
|
+
!= zl.elements[f"Player #{idx + 1}"].value()
|
|
101
|
+
):
|
|
102
|
+
dw.player.video_zoom = log2(float(zl.elements[f"Player #{idx + 1}"].value()))
|
|
112
103
|
|
|
113
104
|
logging.debug(f"video zoom changed in {dw.player.video_zoom} for player {idx + 1}")
|
|
114
105
|
|
|
115
106
|
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.ZOOM_LEVEL][str(idx + 1)] = float(
|
|
116
|
-
zl.elements[f"Player #{idx + 1}"].
|
|
107
|
+
zl.elements[f"Player #{idx + 1}"].value()
|
|
117
108
|
)
|
|
109
|
+
display_zoom_level(self)
|
|
110
|
+
self.project_changed()
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def change_player_offset(self):
|
|
114
|
+
"""
|
|
115
|
+
display dialog box for setting the player time offset
|
|
116
|
+
"""
|
|
117
|
+
logging.info("change the player time offset")
|
|
118
|
+
|
|
119
|
+
if cfg.OFFSET not in self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO]:
|
|
120
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.OFFSET] = {}
|
|
121
|
+
|
|
122
|
+
players_list: list = []
|
|
123
|
+
|
|
124
|
+
for idx, dw in enumerate(self.dw_player):
|
|
125
|
+
players_list.append(
|
|
126
|
+
(
|
|
127
|
+
"dsb",
|
|
128
|
+
f"Player #{idx + 1}",
|
|
129
|
+
-100000,
|
|
130
|
+
100000,
|
|
131
|
+
0.001,
|
|
132
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.OFFSET][str(idx + 1)],
|
|
133
|
+
3,
|
|
134
|
+
)
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
zl = dialog.Input_dialog(label_caption="Select the time offset", elements_list=players_list, title="Time offset")
|
|
138
|
+
if not zl.exec_():
|
|
139
|
+
return
|
|
140
|
+
|
|
141
|
+
for idx, dw in enumerate(self.dw_player):
|
|
142
|
+
if (
|
|
143
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.OFFSET].get(str(idx + 1), 0)
|
|
144
|
+
!= zl.elements[f"Player #{idx + 1}"].value()
|
|
145
|
+
):
|
|
146
|
+
logging.debug(f"time offset of player changed in {zl.elements[f'Player #{idx + 1}'].value()} for player {idx + 1}")
|
|
147
|
+
|
|
148
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.OFFSET][str(idx + 1)] = float(
|
|
149
|
+
zl.elements[f"Player #{idx + 1}"].value()
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
if self.dw_player[0].player.time_pos is not None:
|
|
153
|
+
cumulative_time_pos = self.getLaps() # for player 1
|
|
154
|
+
self.sync_time(idx, cumulative_time_pos)
|
|
155
|
+
|
|
118
156
|
self.project_changed()
|
|
119
157
|
|
|
120
158
|
|
|
@@ -129,9 +167,7 @@ def rotate_displayed_video(self):
|
|
|
129
167
|
rotation_angles.append((str(choice), "selected" if choice == dw.player.video_rotate else ""))
|
|
130
168
|
players_list.append(("il", f"Player #{idx + 1}", rotation_angles))
|
|
131
169
|
|
|
132
|
-
w = dialog.Input_dialog(
|
|
133
|
-
label_caption="Select the rotation angle", elements_list=players_list, title="Video rotation angle"
|
|
134
|
-
)
|
|
170
|
+
w = dialog.Input_dialog(label_caption="Select the rotation angle", elements_list=players_list, title="Video rotation angle")
|
|
135
171
|
if not w.exec_():
|
|
136
172
|
return
|
|
137
173
|
if cfg.ROTATION_ANGLE not in self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO]:
|
|
@@ -183,17 +219,30 @@ def display_subtitles(self):
|
|
|
183
219
|
|
|
184
220
|
logging.debug(f"subtitle visibility for player {idx + 1}: {dw.player.sub_visibility}")
|
|
185
221
|
|
|
186
|
-
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.DISPLAY_MEDIA_SUBTITLES][
|
|
187
|
-
|
|
188
|
-
]
|
|
222
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.DISPLAY_MEDIA_SUBTITLES][str(idx + 1)] = st.elements[
|
|
223
|
+
f"Player #{idx + 1}"
|
|
224
|
+
].isChecked()
|
|
189
225
|
self.project_changed()
|
|
190
226
|
|
|
191
227
|
|
|
228
|
+
def display_zoom_level(self) -> None:
|
|
229
|
+
"""
|
|
230
|
+
display the zoom level
|
|
231
|
+
"""
|
|
232
|
+
msg: str = "Zoom level: <b>"
|
|
233
|
+
for player in self.dw_player:
|
|
234
|
+
msg += f"{2**player.player.video_zoom:.1f} "
|
|
235
|
+
msg += "</b>"
|
|
236
|
+
self.lb_zoom_level.setText(msg)
|
|
237
|
+
|
|
238
|
+
|
|
192
239
|
def display_play_rate(self) -> None:
|
|
193
240
|
"""
|
|
194
241
|
display current play rate in status bar widget
|
|
195
242
|
"""
|
|
196
|
-
|
|
243
|
+
|
|
244
|
+
self.lb_video_info.setText(f"Play rate: <b>x{self.play_rate:.3f}</b>")
|
|
245
|
+
|
|
197
246
|
logging.debug(f"play rate: {self.play_rate:.3f}")
|
|
198
247
|
|
|
199
248
|
|
|
@@ -232,6 +281,7 @@ def video_faster_activated(self):
|
|
|
232
281
|
and self.pj[cfg.OBSERVATIONS][self.observationId][cfg.FILE][str(i + 1)]
|
|
233
282
|
):
|
|
234
283
|
player.player.speed = self.play_rate
|
|
284
|
+
print("speed")
|
|
235
285
|
|
|
236
286
|
display_play_rate(self)
|
|
237
287
|
|