wip [ui] display global stats from sfm: residuals,landmarks per view

This commit is contained in:
Theo 2020-03-31 17:51:10 +02:00
parent f07b959a2b
commit 150e142f92
5 changed files with 213 additions and 5 deletions

View file

@ -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
}
}

View file

@ -19,6 +19,7 @@ FloatingPane {
clip: true
padding: 4
anchors.rightMargin: 0
/**
* Convert GPS metadata to degree coordinates.

View 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);
}
}
}

View file

@ -98,7 +98,6 @@ FloatingPane {
id: residualLegend
chartView: residualChart
}
}
}

View file

@ -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
}
}
}
}
}