sgtlib 3.3.9__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.
Files changed (72) hide show
  1. StructuralGT/__init__.py +31 -0
  2. StructuralGT/apps/__init__.py +0 -0
  3. StructuralGT/apps/cli_main.py +258 -0
  4. StructuralGT/apps/gui_main.py +69 -0
  5. StructuralGT/apps/gui_mcw/__init__.py +0 -0
  6. StructuralGT/apps/gui_mcw/checkbox_model.py +91 -0
  7. StructuralGT/apps/gui_mcw/controller.py +1073 -0
  8. StructuralGT/apps/gui_mcw/image_provider.py +74 -0
  9. StructuralGT/apps/gui_mcw/imagegrid_model.py +75 -0
  10. StructuralGT/apps/gui_mcw/qthread_worker.py +102 -0
  11. StructuralGT/apps/gui_mcw/table_model.py +79 -0
  12. StructuralGT/apps/gui_mcw/tree_model.py +154 -0
  13. StructuralGT/apps/sgt_qml/CenterMainContent.qml +19 -0
  14. StructuralGT/apps/sgt_qml/LeftContent.qml +48 -0
  15. StructuralGT/apps/sgt_qml/MainWindow.qml +762 -0
  16. StructuralGT/apps/sgt_qml/RightLoggingPanel.qml +125 -0
  17. StructuralGT/apps/sgt_qml/assets/icons/.DS_Store +0 -0
  18. StructuralGT/apps/sgt_qml/assets/icons/back_icon.png +0 -0
  19. StructuralGT/apps/sgt_qml/assets/icons/brightness_icon.png +0 -0
  20. StructuralGT/apps/sgt_qml/assets/icons/cancel_icon.png +0 -0
  21. StructuralGT/apps/sgt_qml/assets/icons/crop_icon.png +0 -0
  22. StructuralGT/apps/sgt_qml/assets/icons/edit_icon.png +0 -0
  23. StructuralGT/apps/sgt_qml/assets/icons/graph_icon.png +0 -0
  24. StructuralGT/apps/sgt_qml/assets/icons/hide_panel.png +0 -0
  25. StructuralGT/apps/sgt_qml/assets/icons/next_icon.png +0 -0
  26. StructuralGT/apps/sgt_qml/assets/icons/notify_icon.png +0 -0
  27. StructuralGT/apps/sgt_qml/assets/icons/rescale_icon.png +0 -0
  28. StructuralGT/apps/sgt_qml/assets/icons/show_panel.png +0 -0
  29. StructuralGT/apps/sgt_qml/assets/icons/square_icon.png +0 -0
  30. StructuralGT/apps/sgt_qml/assets/icons/undo_icon.png +0 -0
  31. StructuralGT/apps/sgt_qml/components/ImageFilters.qml +82 -0
  32. StructuralGT/apps/sgt_qml/components/ImageProperties.qml +112 -0
  33. StructuralGT/apps/sgt_qml/components/ProjectNav.qml +127 -0
  34. StructuralGT/apps/sgt_qml/widgets/BinaryFilterWidget.qml +151 -0
  35. StructuralGT/apps/sgt_qml/widgets/BrightnessControlWidget.qml +103 -0
  36. StructuralGT/apps/sgt_qml/widgets/CreateProjectWidget.qml +112 -0
  37. StructuralGT/apps/sgt_qml/widgets/GTWidget.qml +94 -0
  38. StructuralGT/apps/sgt_qml/widgets/GraphComputeWidget.qml +77 -0
  39. StructuralGT/apps/sgt_qml/widgets/GraphExtractWidget.qml +175 -0
  40. StructuralGT/apps/sgt_qml/widgets/GraphPropertyWidget.qml +77 -0
  41. StructuralGT/apps/sgt_qml/widgets/ImageFilterWidget.qml +137 -0
  42. StructuralGT/apps/sgt_qml/widgets/ImagePropertyWidget.qml +78 -0
  43. StructuralGT/apps/sgt_qml/widgets/ImageViewWidget.qml +585 -0
  44. StructuralGT/apps/sgt_qml/widgets/MenuBarWidget.qml +137 -0
  45. StructuralGT/apps/sgt_qml/widgets/MicroscopyPropertyWidget.qml +80 -0
  46. StructuralGT/apps/sgt_qml/widgets/ProjectWidget.qml +141 -0
  47. StructuralGT/apps/sgt_qml/widgets/RescaleControlWidget.qml +83 -0
  48. StructuralGT/apps/sgt_qml/widgets/RibbonWidget.qml +406 -0
  49. StructuralGT/apps/sgt_qml/widgets/StatusBarWidget.qml +173 -0
  50. StructuralGT/compute/__init__.py +0 -0
  51. StructuralGT/compute/c_lang/include/sgt_base.h +21 -0
  52. StructuralGT/compute/graph_analyzer.py +1499 -0
  53. StructuralGT/entrypoints.py +49 -0
  54. StructuralGT/imaging/__init__.py +0 -0
  55. StructuralGT/imaging/base_image.py +403 -0
  56. StructuralGT/imaging/image_processor.py +780 -0
  57. StructuralGT/modules.py +29 -0
  58. StructuralGT/networks/__init__.py +0 -0
  59. StructuralGT/networks/fiber_network.py +490 -0
  60. StructuralGT/networks/graph_skeleton.py +425 -0
  61. StructuralGT/networks/sknw_mod.py +199 -0
  62. StructuralGT/utils/__init__.py +0 -0
  63. StructuralGT/utils/config_loader.py +244 -0
  64. StructuralGT/utils/configs.ini +97 -0
  65. StructuralGT/utils/progress_update.py +67 -0
  66. StructuralGT/utils/sgt_utils.py +291 -0
  67. sgtlib-3.3.9.dist-info/METADATA +789 -0
  68. sgtlib-3.3.9.dist-info/RECORD +72 -0
  69. sgtlib-3.3.9.dist-info/WHEEL +5 -0
  70. sgtlib-3.3.9.dist-info/entry_points.txt +3 -0
  71. sgtlib-3.3.9.dist-info/licenses/LICENSE +674 -0
  72. sgtlib-3.3.9.dist-info/top_level.txt +1 -0
@@ -0,0 +1,125 @@
1
+ import QtQuick
2
+ import QtQuick.Controls
3
+ import QtQuick.Controls.Basic as Basic
4
+ import QtQuick.Layouts
5
+ import QtQuick.Window
6
+
7
+ Window {
8
+ id: loggingWindowPanel
9
+ width: 400
10
+ height: 764
11
+ x: 1024 // Exactly starts where your app ends
12
+ y: 40
13
+ //flags: Qt.Window | Qt.FramelessWindowHint
14
+ visible: false // Only show when needed
15
+ title: "SGT Logs"
16
+
17
+ property string currentFilter: "All"
18
+ property var logEntries: []
19
+
20
+ function currentTimestamp() {
21
+ let now = new Date()
22
+ return now.toLocaleTimeString(Qt.locale(), "hh:mm:ss")
23
+ }
24
+
25
+ function appendLog(type, message, color = "black") {
26
+ let timestamp = currentTimestamp()
27
+ let html = "<font color='" + color + "'>[" + timestamp + "] " + message + "</font>"
28
+ logEntries.push({type: type, html: html})
29
+ refreshLogDisplay()
30
+ }
31
+
32
+ function refreshLogDisplay() {
33
+ lblTextLogs.text = ""
34
+ for (let i = 0; i < logEntries.length; ++i) {
35
+ let entry = logEntries[i]
36
+ if (currentFilter === "All" || entry.type === currentFilter)
37
+ lblTextLogs.append(entry.html)
38
+ }
39
+ lblTextLogs.cursorPosition = lblTextLogs.length
40
+ }
41
+
42
+ Rectangle {
43
+ id: loggingDataContainer
44
+ width: parent.width
45
+ height: parent.height
46
+ color: "transparent"
47
+
48
+ ColumnLayout {
49
+ anchors.fill: parent
50
+ spacing: 5
51
+
52
+ RowLayout {
53
+ Layout.fillWidth: true
54
+ Layout.topMargin: 10
55
+ Layout.alignment: Qt.AlignHCenter
56
+ spacing: 10
57
+
58
+ ComboBox {
59
+ id: logFilter
60
+ Layout.preferredWidth: 150
61
+ model: ["All", "Info", "Error", "Success"]
62
+ onCurrentTextChanged: {
63
+ currentFilter = currentText
64
+ refreshLogDisplay()
65
+ }
66
+ }
67
+
68
+ Button {
69
+ text: "Clear Logs"
70
+ onClicked: {
71
+ logEntries = []
72
+ refreshLogDisplay()
73
+ }
74
+ }
75
+ }
76
+
77
+ ScrollView {
78
+ Layout.fillWidth: true
79
+ Layout.fillHeight: true
80
+ Layout.topMargin: 5
81
+ Layout.bottomMargin: 10
82
+
83
+ Basic.TextArea {
84
+ id: lblTextLogs
85
+ wrapMode: Text.Wrap
86
+ readOnly: true
87
+ selectByMouse: true
88
+ textFormat: TextEdit.RichText
89
+ font.pixelSize: 10
90
+ background: Rectangle {
91
+ color: "white"
92
+ radius: 4
93
+ }
94
+ }
95
+ }
96
+ }
97
+
98
+ }
99
+
100
+ Connections {
101
+ target: mainController
102
+
103
+ function onUpdateProgressSignal(val, msg) {
104
+ let fullMsg = (val <= 100) ? val + "%: " + msg : msg
105
+ appendLog("Info", fullMsg, "blue")
106
+ }
107
+
108
+ function onErrorSignal(msg) {
109
+ appendLog("Error", msg, "red")
110
+ }
111
+
112
+ function onTaskTerminatedSignal(success_val, msg_data) {
113
+ if (success_val) {
114
+ appendLog("Success", "Task completed successfully!", "#2222bc")
115
+ } else {
116
+ appendLog("Error", "Task terminated due to an error. Try again.", "#bc2222")
117
+ }
118
+
119
+ if (msg_data.length >= 2) {
120
+ appendLog("Info", msg_data[0] + "<br>" + msg_data[1], "gray")
121
+ }
122
+ }
123
+ }
124
+
125
+ }
@@ -0,0 +1,82 @@
1
+ import QtQuick
2
+ import QtQuick.Controls
3
+ import QtQuick.Layouts
4
+ import "../widgets"
5
+
6
+ Rectangle {
7
+ color: "#f0f0f0"
8
+ border.color: "#c0c0c0"
9
+ Layout.fillWidth: true
10
+ Layout.fillHeight: true
11
+
12
+ property int lblWidthSize: 280
13
+
14
+ ScrollView {
15
+ id: scrollViewImgFilters
16
+ anchors.fill: parent
17
+ clip: true
18
+
19
+ ScrollBar.horizontal.policy: ScrollBar.AlwaysOff // Disable horizontal scrolling
20
+ ScrollBar.vertical.policy: ScrollBar.AsNeeded // Enable vertical scrolling only when needed
21
+
22
+ contentHeight: colImgFiltersLayout.implicitHeight
23
+
24
+ ColumnLayout {
25
+ id: colImgFiltersLayout
26
+ width: scrollViewImgFilters.width // Ensures it never exceeds parent width
27
+ Layout.preferredWidth: parent.width // Fills the available width
28
+
29
+ Text {
30
+ text: "Binary Filters"
31
+ font.pixelSize: 12
32
+ font.bold: true
33
+ Layout.topMargin: 10
34
+ Layout.bottomMargin: 5
35
+ Layout.alignment: Qt.AlignHCenter
36
+ }
37
+
38
+ Label {
39
+ id: lblNoImgFilters
40
+ Layout.alignment: Qt.AlignHCenter
41
+ Layout.topMargin: 20
42
+ text: "No image filters to show!\nCreate project/add image."
43
+ color: "#808080"
44
+ visible: !mainController.display_image();
45
+ }
46
+ BinaryFilterWidget{}
47
+
48
+ Rectangle {
49
+ height: 1
50
+ color: "#d0d0d0"
51
+ Layout.fillWidth: true
52
+ Layout.alignment: Qt.AlignHCenter
53
+ Layout.topMargin: 20
54
+ Layout.leftMargin: 20
55
+ Layout.rightMargin: 20
56
+ }
57
+
58
+ Text {
59
+ text: "Image Filters"
60
+ font.pixelSize: 12
61
+ font.bold: true
62
+ Layout.topMargin: 10
63
+ Layout.bottomMargin: 5
64
+ Layout.alignment: Qt.AlignHCenter
65
+ }
66
+
67
+
68
+ ImageFilterWidget{}
69
+
70
+ }
71
+ }
72
+
73
+ Connections {
74
+ target: mainController
75
+
76
+ function onImageChangedSignal() {
77
+ // Force refresh
78
+ lblNoImgFilters.visible = !mainController.display_image();
79
+ }
80
+
81
+ }
82
+ }
@@ -0,0 +1,112 @@
1
+ import QtQuick
2
+ import QtQuick.Controls
3
+ import QtQuick.Layouts
4
+ import "../widgets"
5
+
6
+ Rectangle {
7
+ color: "#f0f0f0"
8
+ border.color: "#c0c0c0"
9
+ Layout.fillWidth: true
10
+ Layout.fillHeight: true
11
+
12
+ ScrollView {
13
+ id: scrollViewImgProps
14
+ anchors.fill: parent
15
+ clip: true
16
+
17
+ ScrollBar.horizontal.policy: ScrollBar.AlwaysOff // Disable horizontal scrolling
18
+ ScrollBar.vertical.policy: ScrollBar.AsNeeded // Enable vertical scrolling only when needed
19
+ //contentHeight: colImgPropsLayout.implicitHeight
20
+
21
+ ColumnLayout {
22
+ id: colImgPropsLayout
23
+ width: scrollViewImgProps.width // Ensures it never exceeds parent width
24
+ Layout.preferredWidth: parent.width // Fills the available width
25
+ implicitHeight: colImgPropsLayout.implicitHeight
26
+
27
+ Text {
28
+ text: "Image Properties"
29
+ font.pixelSize: 12
30
+ font.bold: true
31
+ Layout.topMargin: 10
32
+ Layout.bottomMargin: 5
33
+ Layout.alignment: Qt.AlignHCenter
34
+ }
35
+
36
+ ImagePropertyWidget{}
37
+
38
+ Rectangle {
39
+ height: 1
40
+ color: "#d0d0d0"
41
+ Layout.fillWidth: true
42
+ Layout.alignment: Qt.AlignHCenter
43
+ Layout.topMargin: 20
44
+ Layout.leftMargin: 20
45
+ Layout.rightMargin: 20
46
+ }
47
+ Text {
48
+ text: "Graph Properties"
49
+ font.pixelSize: 12
50
+ font.bold: true
51
+ Layout.topMargin: 10
52
+ Layout.bottomMargin: 5
53
+ Layout.alignment: Qt.AlignHCenter
54
+ }
55
+
56
+ Label {
57
+ id: lblNoGraphProps
58
+ Layout.alignment: Qt.AlignHCenter
59
+ Layout.topMargin: 20
60
+ text: "No properties to show!"
61
+ color: "#808080"
62
+ visible: graphPropsModel.rowCount() > 0 ? false : true
63
+ }
64
+ GraphPropertyWidget{}
65
+
66
+
67
+ Rectangle {
68
+ height: 1
69
+ color: "#d0d0d0"
70
+ Layout.fillWidth: true
71
+ Layout.alignment: Qt.AlignHCenter
72
+ Layout.topMargin: 20
73
+ Layout.leftMargin: 20
74
+ Layout.rightMargin: 20
75
+ }
76
+ Text {
77
+ text: "Computation Metrics"
78
+ font.pixelSize: 12
79
+ font.bold: true
80
+ Layout.topMargin: 10
81
+ Layout.bottomMargin: 5
82
+ Layout.alignment: Qt.AlignHCenter
83
+ }
84
+
85
+ Label {
86
+ id: lblNoGraphParams
87
+ Layout.alignment: Qt.AlignHCenter
88
+ Layout.topMargin: 20
89
+ text: "No metrics to show!"
90
+ color: "#808080"
91
+ visible: graphComputeModel.rowCount() > 0 ? false : true
92
+ }
93
+ GraphComputeWidget{}
94
+ }
95
+ }
96
+
97
+ Connections {
98
+ target: mainController
99
+
100
+ function onImageChangedSignal() {
101
+ lblNoGraphProps.visible = graphPropsModel.rowCount() > 0 ? false : true;
102
+ lblNoGraphParams.visible = graphComputeModel.rowCount() > 0 ? false : true;
103
+ }
104
+
105
+ function onTaskTerminatedSignal(success_val, msg_data){
106
+ lblNoGraphProps.visible = graphPropsModel.rowCount() > 0 ? false : true;
107
+ lblNoGraphParams.visible = graphComputeModel.rowCount() > 0 ? false : true;
108
+ }
109
+
110
+ }
111
+
112
+ }
@@ -0,0 +1,127 @@
1
+ import QtQuick
2
+ import QtQuick.Controls
3
+ import QtQuick.Controls.Basic as Basic
4
+ import QtQuick.Layouts
5
+ //import QtQuick.Dialogs as QuickDialogs
6
+ //import Qt.labs.platform as Platform
7
+ import "../widgets"
8
+
9
+ Rectangle {
10
+ color: "#f0f0f0"
11
+ border.color: "#c0c0c0"
12
+ Layout.fillWidth: true
13
+ Layout.fillHeight: true
14
+
15
+ ScrollView {
16
+ id: scrollViewProjNav
17
+ anchors.fill: parent
18
+ clip: true
19
+
20
+ ScrollBar.horizontal.policy: ScrollBar.AlwaysOff // Disable horizontal scrolling
21
+ ScrollBar.vertical.policy: ScrollBar.AsNeeded // Enable vertical scrolling only when needed
22
+
23
+ contentHeight: colImgProjNavLayout.implicitHeight
24
+
25
+ ColumnLayout {
26
+ id: colImgProjNavLayout
27
+ width: scrollViewProjNav.width // Ensures it never exceeds parent width
28
+ Layout.preferredWidth: parent.width // Fills the available width
29
+
30
+ RowLayout {
31
+ id: rowLayoutProject
32
+ Layout.topMargin: 10
33
+ Layout.leftMargin: 10
34
+ Layout.bottomMargin: 5
35
+ visible: mainController.is_project_open()
36
+
37
+ Label {
38
+ text: "Project Name:"
39
+ font.bold: true
40
+ }
41
+
42
+ Label {
43
+ id: lblProjectName
44
+ Layout.minimumWidth: 175
45
+ Layout.fillWidth: true
46
+ text: ""
47
+ }
48
+ }
49
+
50
+ RowLayout {
51
+ Layout.leftMargin: 10
52
+ Layout.bottomMargin: 5
53
+
54
+ Label {
55
+ text: "Output Dir:"
56
+ font.bold: true
57
+ }
58
+
59
+ TextField {
60
+ id: txtOutputDir
61
+ Layout.minimumWidth: 175
62
+ Layout.fillWidth: true
63
+ text: ""
64
+ }
65
+
66
+ Basic.Button {
67
+ id: btnChangeOutDir
68
+ //text: "Change"
69
+ icon.source: "../assets/icons/edit_icon.png"
70
+ icon.width: 21
71
+ icon.height: 21
72
+ background: Rectangle { color: "transparent"}
73
+ enabled: mainController.display_image();
74
+ onClicked: outFolderDialog.open()
75
+ }
76
+ }
77
+
78
+ Button {
79
+ id: btnImportImages
80
+ Layout.alignment: Qt.AlignHCenter
81
+ text: "Import image(s)"
82
+ enabled: mainController.display_image();
83
+ onClicked: imageFileDialog.open()
84
+ }
85
+
86
+ Rectangle {
87
+ height: 1
88
+ color: "#d0d0d0"
89
+ Layout.fillWidth: true
90
+ Layout.alignment: Qt.AlignHCenter
91
+ Layout.topMargin: 5
92
+ Layout.leftMargin: 20
93
+ Layout.rightMargin: 20
94
+ }
95
+ Text {
96
+ text: "Image List"
97
+ font.pixelSize: 12
98
+ font.bold: true
99
+ Layout.topMargin: 5
100
+ Layout.bottomMargin: 5
101
+ Layout.alignment: Qt.AlignHCenter
102
+ visible: true
103
+ }
104
+
105
+ ProjectWidget {}
106
+ }
107
+ }
108
+
109
+
110
+ Connections {
111
+ target: mainController
112
+
113
+ function onImageChangedSignal() {
114
+ // Force refresh
115
+ txtOutputDir.text = mainController.get_output_dir();
116
+ btnChangeOutDir.enabled = mainController.display_image();
117
+ btnImportImages.enabled = mainController.display_image() || mainController.is_project_open();
118
+ }
119
+
120
+ function onProjectOpenedSignal(name) {
121
+ lblProjectName.text = name;
122
+ rowLayoutProject.visible = mainController.is_project_open();
123
+ btnImportImages.enabled = mainController.display_image() || mainController.is_project_open();
124
+ }
125
+ }
126
+
127
+ }
@@ -0,0 +1,151 @@
1
+ import QtQuick
2
+ import QtQuick.Controls
3
+ import QtQuick.Layouts
4
+
5
+ ColumnLayout {
6
+ id:imgBinControls
7
+ Layout.preferredHeight: 120
8
+ Layout.preferredWidth: parent.width
9
+ Layout.fillWidth: true
10
+ Layout.leftMargin: 10
11
+ Layout.alignment: Qt.AlignLeft
12
+ visible: mainController.display_image();
13
+
14
+ property int idRole: Qt.UserRole + 1
15
+ property int valueRole: Qt.UserRole + 4
16
+ property int btnWidthSize: 100
17
+ property int spbWidthSize: 170
18
+ property int sldWidthSize: 140
19
+ property int lblWidthSize: 50
20
+
21
+ ButtonGroup {
22
+ id: btnGrpBinary
23
+ exclusive: true
24
+ //checkedButton: rdoGlobal
25
+ onCheckedButtonChanged: {
26
+ var val = checkedButton === rdoGlobal ? 0 : checkedButton === rdoAdaptive ? 1 : 2;
27
+ var index = imgBinFilterModel.index(0, 0);
28
+ imgBinFilterModel.setData(index, val, valueRole);
29
+ mainController.apply_img_bin_changes();
30
+ }
31
+ }
32
+
33
+
34
+ RowLayout {
35
+
36
+ RadioButton {
37
+ id:rdoAdaptive
38
+ text: "Adaptive"
39
+ Layout.preferredWidth: btnWidthSize
40
+ ButtonGroup.group: btnGrpBinary
41
+ onClicked: btnGrpBinary.checkedButton = this
42
+ }
43
+
44
+ SpinBox {
45
+ // ONLY ODD NUMBERS
46
+ id: spbAdaptive
47
+ Layout.minimumWidth: spbWidthSize
48
+ //Layout.fillWidth: true
49
+ from: 1
50
+ to: 999
51
+ stepSize: 2
52
+ value: 11 // "adaptive_local_threshold_value"
53
+ editable: true // Allow user input
54
+ enabled: rdoAdaptive.checked
55
+ onValueChanged: {
56
+ if (value % 2 === 0) {
57
+ value = value - 1; // Convert even input to nearest odd
58
+ }
59
+
60
+ var index = imgBinFilterModel.index(2, 0);
61
+ imgBinFilterModel.setData(index, value, valueRole);
62
+ mainController.apply_img_bin_changes();
63
+ }
64
+ validator: IntValidator { bottom: spbAdaptive.from; top: spbAdaptive.to }
65
+ }
66
+ }
67
+
68
+ RowLayout {
69
+
70
+ RadioButton {
71
+ id: rdoGlobal
72
+ text: "Global"
73
+ Layout.preferredWidth: btnWidthSize
74
+ ButtonGroup.group: btnGrpBinary
75
+ onClicked: btnGrpBinary.checkedButton = this
76
+ }
77
+
78
+ Slider {
79
+ id: sldGlobal
80
+ Layout.minimumWidth: sldWidthSize
81
+ Layout.fillWidth: true
82
+ from: 1
83
+ to: 255
84
+ stepSize: 1
85
+ value: 127 //"global_threshold_value"
86
+ enabled: rdoGlobal.checked
87
+ onValueChanged: {
88
+ var index = imgBinFilterModel.index(1, 0);
89
+ imgBinFilterModel.setData(index, value, valueRole);
90
+ mainController.apply_img_bin_changes();
91
+ }
92
+ }
93
+
94
+ Label {
95
+ id: lblGlobal
96
+ Layout.preferredWidth: lblWidthSize
97
+ text: Number(sldGlobal.value).toFixed(0) // Display one decimal place
98
+ enabled: rdoGlobal.checked
99
+ }
100
+
101
+ }
102
+
103
+ RadioButton {
104
+ id: rdoOtsu
105
+ text: "OTSU"
106
+ Layout.preferredWidth: btnWidthSize
107
+ ButtonGroup.group: btnGrpBinary
108
+ onClicked: btnGrpBinary.checkedButton = this
109
+ }
110
+
111
+ CheckBox {
112
+ id: cbxDarkFg
113
+ text: "Apply Dark Foreground"
114
+ checked: false
115
+ onCheckedChanged: {
116
+ var val = checked === true ? 1 : 0;
117
+ var index = imgBinFilterModel.index(4, 0);
118
+ imgBinFilterModel.setData(index, val, valueRole);
119
+ mainController.apply_img_bin_changes();
120
+ }
121
+ }
122
+
123
+ function initializeSelections() {
124
+ for (let row = 0; row < imgBinFilterModel.rowCount(); row ++) {
125
+ var index = imgBinFilterModel.index(row, 0);
126
+ let item_id = imgBinFilterModel.data(index, idRole); // IdRole
127
+ let item_val = imgBinFilterModel.data(index, valueRole); // ValueRole
128
+
129
+ if (item_id === "threshold_type") {
130
+ btnGrpBinary.checkedButton = item_val === 2 ? rdoOtsu : item_val === 1 ? rdoAdaptive : rdoGlobal;
131
+ } else if (item_id === "global_threshold_value") {
132
+ sldGlobal.value = item_val;
133
+ } else if (item_id === "adaptive_local_threshold_value") {
134
+ spbAdaptive.value = item_val;
135
+ } else if (item_id === "apply_dark_foreground") {
136
+ cbxDarkFg.checked = item_val === 1 ? true : false;
137
+ }
138
+ }
139
+ }
140
+
141
+ Connections {
142
+ target: mainController
143
+
144
+ function onImageChangedSignal() {
145
+ // Force refresh
146
+ imgBinControls.visible = mainController.display_image();
147
+ initializeSelections();
148
+ }
149
+
150
+ }
151
+ }