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.
- StructuralGT/__init__.py +31 -0
- StructuralGT/apps/__init__.py +0 -0
- StructuralGT/apps/cli_main.py +258 -0
- StructuralGT/apps/gui_main.py +69 -0
- StructuralGT/apps/gui_mcw/__init__.py +0 -0
- StructuralGT/apps/gui_mcw/checkbox_model.py +91 -0
- StructuralGT/apps/gui_mcw/controller.py +1073 -0
- StructuralGT/apps/gui_mcw/image_provider.py +74 -0
- StructuralGT/apps/gui_mcw/imagegrid_model.py +75 -0
- StructuralGT/apps/gui_mcw/qthread_worker.py +102 -0
- StructuralGT/apps/gui_mcw/table_model.py +79 -0
- StructuralGT/apps/gui_mcw/tree_model.py +154 -0
- StructuralGT/apps/sgt_qml/CenterMainContent.qml +19 -0
- StructuralGT/apps/sgt_qml/LeftContent.qml +48 -0
- StructuralGT/apps/sgt_qml/MainWindow.qml +762 -0
- StructuralGT/apps/sgt_qml/RightLoggingPanel.qml +125 -0
- StructuralGT/apps/sgt_qml/assets/icons/.DS_Store +0 -0
- StructuralGT/apps/sgt_qml/assets/icons/back_icon.png +0 -0
- StructuralGT/apps/sgt_qml/assets/icons/brightness_icon.png +0 -0
- StructuralGT/apps/sgt_qml/assets/icons/cancel_icon.png +0 -0
- StructuralGT/apps/sgt_qml/assets/icons/crop_icon.png +0 -0
- StructuralGT/apps/sgt_qml/assets/icons/edit_icon.png +0 -0
- StructuralGT/apps/sgt_qml/assets/icons/graph_icon.png +0 -0
- StructuralGT/apps/sgt_qml/assets/icons/hide_panel.png +0 -0
- StructuralGT/apps/sgt_qml/assets/icons/next_icon.png +0 -0
- StructuralGT/apps/sgt_qml/assets/icons/notify_icon.png +0 -0
- StructuralGT/apps/sgt_qml/assets/icons/rescale_icon.png +0 -0
- StructuralGT/apps/sgt_qml/assets/icons/show_panel.png +0 -0
- StructuralGT/apps/sgt_qml/assets/icons/square_icon.png +0 -0
- StructuralGT/apps/sgt_qml/assets/icons/undo_icon.png +0 -0
- StructuralGT/apps/sgt_qml/components/ImageFilters.qml +82 -0
- StructuralGT/apps/sgt_qml/components/ImageProperties.qml +112 -0
- StructuralGT/apps/sgt_qml/components/ProjectNav.qml +127 -0
- StructuralGT/apps/sgt_qml/widgets/BinaryFilterWidget.qml +151 -0
- StructuralGT/apps/sgt_qml/widgets/BrightnessControlWidget.qml +103 -0
- StructuralGT/apps/sgt_qml/widgets/CreateProjectWidget.qml +112 -0
- StructuralGT/apps/sgt_qml/widgets/GTWidget.qml +94 -0
- StructuralGT/apps/sgt_qml/widgets/GraphComputeWidget.qml +77 -0
- StructuralGT/apps/sgt_qml/widgets/GraphExtractWidget.qml +175 -0
- StructuralGT/apps/sgt_qml/widgets/GraphPropertyWidget.qml +77 -0
- StructuralGT/apps/sgt_qml/widgets/ImageFilterWidget.qml +137 -0
- StructuralGT/apps/sgt_qml/widgets/ImagePropertyWidget.qml +78 -0
- StructuralGT/apps/sgt_qml/widgets/ImageViewWidget.qml +585 -0
- StructuralGT/apps/sgt_qml/widgets/MenuBarWidget.qml +137 -0
- StructuralGT/apps/sgt_qml/widgets/MicroscopyPropertyWidget.qml +80 -0
- StructuralGT/apps/sgt_qml/widgets/ProjectWidget.qml +141 -0
- StructuralGT/apps/sgt_qml/widgets/RescaleControlWidget.qml +83 -0
- StructuralGT/apps/sgt_qml/widgets/RibbonWidget.qml +406 -0
- StructuralGT/apps/sgt_qml/widgets/StatusBarWidget.qml +173 -0
- StructuralGT/compute/__init__.py +0 -0
- StructuralGT/compute/c_lang/include/sgt_base.h +21 -0
- StructuralGT/compute/graph_analyzer.py +1499 -0
- StructuralGT/entrypoints.py +49 -0
- StructuralGT/imaging/__init__.py +0 -0
- StructuralGT/imaging/base_image.py +403 -0
- StructuralGT/imaging/image_processor.py +780 -0
- StructuralGT/modules.py +29 -0
- StructuralGT/networks/__init__.py +0 -0
- StructuralGT/networks/fiber_network.py +490 -0
- StructuralGT/networks/graph_skeleton.py +425 -0
- StructuralGT/networks/sknw_mod.py +199 -0
- StructuralGT/utils/__init__.py +0 -0
- StructuralGT/utils/config_loader.py +244 -0
- StructuralGT/utils/configs.ini +97 -0
- StructuralGT/utils/progress_update.py +67 -0
- StructuralGT/utils/sgt_utils.py +291 -0
- sgtlib-3.3.9.dist-info/METADATA +789 -0
- sgtlib-3.3.9.dist-info/RECORD +72 -0
- sgtlib-3.3.9.dist-info/WHEEL +5 -0
- sgtlib-3.3.9.dist-info/entry_points.txt +3 -0
- sgtlib-3.3.9.dist-info/licenses/LICENSE +674 -0
- 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
|
+
}
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -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
|
+
}
|