mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-06-03 03:11:56 +02:00
wip [ui] display global stats from sfm: residuals,landmarks per view
This commit is contained in:
parent
f07b959a2b
commit
150e142f92
5 changed files with 213 additions and 5 deletions
|
@ -12,6 +12,8 @@ Repeater {
|
|||
|
||||
/// ViewID to display the features of
|
||||
property int viewId
|
||||
/// SfMData to display the data of SfM
|
||||
property var sfmData
|
||||
/// Folder containing the features files
|
||||
property string folder
|
||||
/// The list of describer types to load
|
||||
|
@ -35,6 +37,7 @@ Repeater {
|
|||
viewId: root.viewId
|
||||
color: root.colors[colorIndex]
|
||||
displayMode: root.displayMode
|
||||
msfmData: root.sfmData
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ FloatingPane {
|
|||
|
||||
clip: true
|
||||
padding: 4
|
||||
anchors.rightMargin: 0
|
||||
|
||||
/**
|
||||
* Convert GPS metadata to degree coordinates.
|
||||
|
|
162
meshroom/ui/qml/Viewer/SfmGlobalStats.qml
Normal file
162
meshroom/ui/qml/Viewer/SfmGlobalStats.qml
Normal file
|
@ -0,0 +1,162 @@
|
|||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.3
|
||||
import MaterialIcons 2.2
|
||||
import QtPositioning 5.8
|
||||
import QtLocation 5.9
|
||||
import QtCharts 2.13
|
||||
import Charts 1.0
|
||||
|
||||
import Controls 1.0
|
||||
import Utils 1.0
|
||||
|
||||
import AliceVision 1.0 as AliceVision
|
||||
|
||||
|
||||
FloatingPane {
|
||||
id: root
|
||||
|
||||
property var msfmData
|
||||
property color textColor: Colors.sysPalette.text
|
||||
|
||||
clip: true
|
||||
padding: 4
|
||||
|
||||
// To avoid interaction with components in background
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||
onPressed: {}
|
||||
onReleased: {}
|
||||
onWheel: {}
|
||||
}
|
||||
|
||||
InteractiveChartView {
|
||||
id: landmarksPerViewChart
|
||||
width: parent.width * 0.5
|
||||
height: parent.height * 0.5
|
||||
|
||||
title: "Landmarks Per View"
|
||||
legend.visible: false
|
||||
antialiasing: true
|
||||
|
||||
ValueAxis {
|
||||
id: landmarksPerViewValueAxisX
|
||||
titleText: "Ordered Views"
|
||||
min: 0.0
|
||||
max: sfmDataStat.landmarksPerViewMaxAxisX
|
||||
}
|
||||
ValueAxis {
|
||||
id: landmarksPerViewValueAxisY
|
||||
labelFormat: "%i"
|
||||
titleText: "Number of Landmarks"
|
||||
min: 0
|
||||
max: sfmDataStat.landmarksPerViewMaxAxisY
|
||||
}
|
||||
LineSeries {
|
||||
id: landmarksPerViewLineSerie
|
||||
axisX: landmarksPerViewValueAxisX
|
||||
axisY: landmarksPerViewValueAxisY
|
||||
}
|
||||
}
|
||||
|
||||
InteractiveChartView {
|
||||
id: residualsPerViewChart
|
||||
width: parent.width * 0.5
|
||||
height: parent.height * 0.5
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: (parent.height) * 0.5
|
||||
|
||||
title: "Residuals Per View"
|
||||
legend.visible: false
|
||||
antialiasing: true
|
||||
|
||||
ValueAxis {
|
||||
id: residualsPerViewValueAxisX
|
||||
labelFormat: "%i"
|
||||
titleText: "Ordered Views"
|
||||
min: 0
|
||||
max: sfmDataStat.residualsPerViewMaxAxisX
|
||||
}
|
||||
ValueAxis {
|
||||
id: residualsPerViewValueAxisY
|
||||
titleText: "Percentage of residuals"
|
||||
min: 0
|
||||
max: sfmDataStat.residualsPerViewMaxAxisY
|
||||
tickAnchor: 0
|
||||
tickInterval: 0.50
|
||||
tickCount: sfmDataStat.residualsPerViewMaxAxisY * 2
|
||||
}
|
||||
LineSeries {
|
||||
id: residualsMinPerViewLineSerie
|
||||
axisX: residualsPerViewValueAxisX
|
||||
axisY: residualsPerViewValueAxisY
|
||||
name: "Min"
|
||||
}
|
||||
LineSeries {
|
||||
id: residualsMaxPerViewLineSerie
|
||||
axisX: residualsPerViewValueAxisX
|
||||
axisY: residualsPerViewValueAxisY
|
||||
name: "Max"
|
||||
}
|
||||
LineSeries {
|
||||
id: residualsMeanPerViewLineSerie
|
||||
axisX: residualsPerViewValueAxisX
|
||||
axisY: residualsPerViewValueAxisY
|
||||
name: "Mean"
|
||||
}
|
||||
LineSeries {
|
||||
id: residualsMedianPerViewLineSerie
|
||||
axisX: residualsPerViewValueAxisX
|
||||
axisY: residualsPerViewValueAxisY
|
||||
name: "Median"
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: residualsPerViewBtnContainer
|
||||
|
||||
Layout.fillWidth: true
|
||||
anchors.bottom: residualsPerViewChart.bottom
|
||||
anchors.bottomMargin: 35
|
||||
anchors.left: residualsPerViewChart.left
|
||||
anchors.leftMargin: residualsPerViewChart.width * 0.25
|
||||
|
||||
RowLayout {
|
||||
|
||||
ChartViewCheckBox {
|
||||
id: allObservations
|
||||
text: "ALL"
|
||||
color: textColor
|
||||
checkState: residualsPerViewLegend.buttonGroup.checkState
|
||||
onClicked: {
|
||||
var _checked = checked;
|
||||
for(var i = 0; i < residualsPerViewChart.count; ++i)
|
||||
{
|
||||
residualsPerViewChart.series(i).visible = _checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ChartViewLegend {
|
||||
id: residualsPerViewLegend
|
||||
chartView: residualsPerViewChart
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Stats from the sfmData
|
||||
AliceVision.MSfMDataStats {
|
||||
id: sfmDataStat
|
||||
msfmData: (root.visible && root.msfmData && root.msfmData.status === AliceVision.MSfMData.Ready) ? root.msfmData : null
|
||||
onStatsChanged: {
|
||||
console.warn("QML AliceVision.MSfMDataStats statsChanged: " + sfmDataStat.msfmData);
|
||||
fillLandmarksPerViewSerie(landmarksPerViewLineSerie);
|
||||
fillResidualsMinPerViewSerie(residualsMinPerViewLineSerie);
|
||||
fillResidualsMaxPerViewSerie(residualsMaxPerViewLineSerie);
|
||||
fillResidualsMeanPerViewSerie(residualsMeanPerViewLineSerie);
|
||||
fillResidualsMedianPerViewSerie(residualsMedianPerViewLineSerie);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -98,7 +98,6 @@ FloatingPane {
|
|||
id: residualLegend
|
||||
chartView: residualChart
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -231,6 +231,7 @@ FocusScope {
|
|||
'viewId': Qt.binding(function() { return _reconstruction.selectedViewId; }),
|
||||
'model': Qt.binding(function() { return _reconstruction.featureExtraction.attribute("describerTypes").value; }),
|
||||
'folder': Qt.binding(function() { return Filepath.stringToUrl(_reconstruction.featureExtraction.attribute("output").value); }),
|
||||
'sfmData': Qt.binding(function() { return msfmDataLoader.status === Loader.Ready ? msfmDataLoader.item : null; }),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -297,8 +298,8 @@ FocusScope {
|
|||
}
|
||||
|
||||
Loader {
|
||||
id: msfmData
|
||||
active: displaySfmStatsView.checked
|
||||
id: msfmDataLoader
|
||||
active: displaySfmStatsView.checked || displayFeatures.checked || displaySfmDataGlobalStats.checked
|
||||
|
||||
Component.onCompleted: {
|
||||
// instantiate and initialize a SfmStatsView component dynamically using Loader.setSource
|
||||
|
@ -311,14 +312,27 @@ FocusScope {
|
|||
Loader {
|
||||
id: sfmStatsView
|
||||
anchors.fill: parent
|
||||
active: msfmData.status === Loader.Ready && displaySfmStatsView.checked
|
||||
active: msfmDataLoader.status === Loader.Ready && displaySfmStatsView.checked
|
||||
|
||||
Component.onCompleted: {
|
||||
// instantiate and initialize a SfmStatsView component dynamically using Loader.setSource
|
||||
// so it can fail safely if the c++ plugin is not available
|
||||
setSource("SfmStatsView.qml", {
|
||||
'msfmData': Qt.binding(function() { return msfmDataLoader.item; }),
|
||||
'viewId': Qt.binding(function() { return _reconstruction.selectedViewId; }),
|
||||
'msfmData': Qt.binding(function() { return msfmData.item; }),
|
||||
})
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
id: sfmGlobalStats
|
||||
anchors.fill: parent
|
||||
active: msfmDataLoader.status === Loader.Ready && displaySfmDataGlobalStats.checked
|
||||
|
||||
Component.onCompleted: {
|
||||
// instantiate and initialize a SfmStatsView component dynamically using Loader.setSource
|
||||
// so it can fail safely if the c++ plugin is not available
|
||||
setSource("SfmGlobalStats.qml", {
|
||||
'msfmData': Qt.binding(function() { return msfmDataLoader.item; }),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -457,9 +471,35 @@ FocusScope {
|
|||
enabled: _reconstruction.sfm && _reconstruction.sfm.isComputed() && _reconstruction.selectedViewId >= 0
|
||||
onCheckedChanged: {
|
||||
if(checked == true)
|
||||
{
|
||||
displaySfmDataGlobalStats.checked = false
|
||||
metadataCB.checked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
MaterialToolButton {
|
||||
id: displaySfmDataGlobalStats
|
||||
|
||||
font.family: MaterialIcons.fontFamily
|
||||
text: MaterialIcons.language
|
||||
|
||||
ToolTip.text: "StructureFromMotion Global Statistics"
|
||||
ToolTip.visible: hovered
|
||||
|
||||
font.pointSize: 14
|
||||
padding: 2
|
||||
smooth: false
|
||||
flat: true
|
||||
checkable: enabled
|
||||
enabled: _reconstruction.sfm && _reconstruction.sfm.isComputed()
|
||||
onCheckedChanged: {
|
||||
if(checked == true)
|
||||
{
|
||||
displaySfmStatsView.checked = false
|
||||
metadataCB.checked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
MaterialToolButton {
|
||||
id: metadataCB
|
||||
|
||||
|
@ -477,9 +517,12 @@ FocusScope {
|
|||
enabled: _reconstruction.selectedViewId >= 0
|
||||
onCheckedChanged: {
|
||||
if(checked == true)
|
||||
{
|
||||
displaySfmDataGlobalStats.checked = false
|
||||
displaySfmStatsView.checked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue