mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-05-31 09:56:32 +02:00
[ui] ImageGallery: introduce IntrinsicsIndicator
New IntrinsicsIndicator component that displays the initialization mode of each Viewpoint's intrinsic with explanatory tooltip.
This commit is contained in:
parent
7db38abdf0
commit
663a5d679d
5 changed files with 144 additions and 24 deletions
|
@ -26,7 +26,7 @@ Item {
|
||||||
id: _viewpoint
|
id: _viewpoint
|
||||||
property url source: viewpoint ? Filepath.stringToUrl(viewpoint.get("path").value) : ''
|
property url source: viewpoint ? Filepath.stringToUrl(viewpoint.get("path").value) : ''
|
||||||
property string metadataStr: viewpoint ? viewpoint.get("metadata").value : ''
|
property string metadataStr: viewpoint ? viewpoint.get("metadata").value : ''
|
||||||
property var metadata: metadataStr ? JSON.parse(viewpoint.get("metadata").value) : null
|
property var metadata: metadataStr ? JSON.parse(viewpoint.get("metadata").value) : {}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
|
@ -80,6 +80,7 @@ Panel {
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: ImageDelegate {
|
delegate: ImageDelegate {
|
||||||
|
id: imageDelegate
|
||||||
|
|
||||||
viewpoint: object.value
|
viewpoint: object.value
|
||||||
width: grid.cellWidth
|
width: grid.cellWidth
|
||||||
|
@ -108,37 +109,29 @@ Panel {
|
||||||
onRemoveRequest: sendRemoveRequest()
|
onRemoveRequest: sendRemoveRequest()
|
||||||
Keys.onDeletePressed: sendRemoveRequest()
|
Keys.onDeletePressed: sendRemoveRequest()
|
||||||
|
|
||||||
Row {
|
RowLayout {
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: 4
|
anchors.margins: 2
|
||||||
spacing: 2
|
spacing: 2
|
||||||
|
|
||||||
property bool valid: Qt.isQtObject(object) // object can be evaluated to null at some point during creation/deletion
|
property bool valid: Qt.isQtObject(object) // object can be evaluated to null at some point during creation/deletion
|
||||||
property bool noMetadata: valid && !_reconstruction.hasMetadata(model.object)
|
property string intrinsicInitMode: valid ? _reconstruction.getIntrinsicInitMode(object) : ""
|
||||||
property bool noIntrinsic: valid && !_reconstruction.hasValidIntrinsic(model.object)
|
|
||||||
property bool inViews: valid && _reconstruction.sfmReport && _reconstruction.isInViews(object)
|
property bool inViews: valid && _reconstruction.sfmReport && _reconstruction.isInViews(object)
|
||||||
|
|
||||||
// Missing metadata indicator
|
|
||||||
Loader {
|
// Camera Initialization indicator
|
||||||
active: parent.noMetadata
|
IntrinsicsIndicator {
|
||||||
visible: active
|
intrinsicInitMode: parent.intrinsicInitMode
|
||||||
sourceComponent: MaterialLabel {
|
metadata: imageDelegate.metadata
|
||||||
text: MaterialIcons.info_outline
|
font.pointSize: 10
|
||||||
color: "#FF9800"
|
padding: 2
|
||||||
ToolTip.text: "No Metadata"
|
background: Rectangle { color: Colors.sysPalette.window; opacity: 0.6 }
|
||||||
}
|
|
||||||
}
|
|
||||||
// Unknown camera instrinsics indicator
|
|
||||||
Loader {
|
|
||||||
active: parent.noIntrinsic
|
|
||||||
visible: active
|
|
||||||
sourceComponent: MaterialLabel {
|
|
||||||
text: MaterialIcons.camera
|
|
||||||
color: "#FF9800"
|
|
||||||
ToolTip.text: "No Camera Instrinsic Parameters (missing Metadata?)"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item { Layout.fillWidth: true }
|
||||||
|
|
||||||
// Reconstruction status indicator
|
// Reconstruction status indicator
|
||||||
Loader {
|
Loader {
|
||||||
active: parent.inViews
|
active: parent.inViews
|
||||||
|
|
94
meshroom/ui/qml/ImageGallery/IntrinsicsIndicator.qml
Normal file
94
meshroom/ui/qml/ImageGallery/IntrinsicsIndicator.qml
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
import QtQuick 2.9
|
||||||
|
import QtQuick.Controls 2.4
|
||||||
|
import MaterialIcons 2.2
|
||||||
|
import Utils 1.0
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display camera initialization status and the value of metadata
|
||||||
|
* that take part in this process.
|
||||||
|
*/
|
||||||
|
MaterialLabel {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string intrinsicInitMode
|
||||||
|
property var metadata: ({})
|
||||||
|
|
||||||
|
// access useful metadata
|
||||||
|
readonly property string make: metadata["Make"]
|
||||||
|
readonly property string model: metadata["Model"]
|
||||||
|
readonly property string focalLength: metadata["Exif:FocalLength"]
|
||||||
|
readonly property string focalLength35: metadata["Exif:FocalLengthIn35mmFilm"]
|
||||||
|
readonly property string bodySerialNumber: metadata["Exif:BodySerialNumber"]
|
||||||
|
readonly property string lensSerialNumber: metadata["Exif:LensSerialNumber"]
|
||||||
|
readonly property string sensorWidth: metadata["AliceVision:SensorWidth"]
|
||||||
|
readonly property string sensorWidthEstimation: metadata["AliceVision:SensorWidthEstimation"]
|
||||||
|
|
||||||
|
property string statusText: ""
|
||||||
|
property string detailsText: ""
|
||||||
|
property string helperText: ""
|
||||||
|
|
||||||
|
text: MaterialIcons.camera
|
||||||
|
|
||||||
|
function metaStr(value) {
|
||||||
|
return value || "<i>undefined</i>"
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolTip.text: "<b>Camera Intrinsics: " + statusText + "</b><br>"
|
||||||
|
+ (detailsText ? detailsText + "<br>" : "")
|
||||||
|
+ (helperText ? helperText + "<br>" : "")
|
||||||
|
+ "<br>"
|
||||||
|
+ "[Metadata]<br>"
|
||||||
|
+ " - Make: " + metaStr(make) + "<br>"
|
||||||
|
+ " - Model: " + metaStr(model) + "<br>"
|
||||||
|
+ " - FocalLength: " + metaStr(focalLength) + "<br>"
|
||||||
|
+ ((focalLength && sensorWidth) ? "" : " - FocalLengthIn35mmFilm: " + metaStr(focalLength35) + "<br>")
|
||||||
|
+ " - SensorWidth: " + metaStr(sensorWidth) + (sensorWidthEstimation ? " (estimation: "+ sensorWidthEstimation + ")" : "")
|
||||||
|
+ ((bodySerialNumber || lensSerialNumber) ? "" : "<br><br>Warning: SerialNumber metadata is missing.<br> Images from different devices might incorrectly share the same camera internal settings.")
|
||||||
|
|
||||||
|
|
||||||
|
state: intrinsicInitMode ? intrinsicInitMode : "unknown"
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "calibrated"
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
color: Colors.green
|
||||||
|
statusText: "Calibrated"
|
||||||
|
detailsText: "Focal Length has been initialized externally."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "estimated"
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
statusText: sensorWidth ? "Estimated" : "Approximated"
|
||||||
|
color: sensorWidth ? Colors.green : Colors.yellow
|
||||||
|
detailsText: "Focal Length was estimated from Metadata" + (sensorWidth ? " and Sensor Database." : " only.")
|
||||||
|
helperText: !sensorWidth ? "Add your Camera Model to the Sensor Database for more accurate results." : ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "unknown"
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
color: focalLength ? Colors.orange : Colors.red
|
||||||
|
statusText: "Unknown"
|
||||||
|
detailsText: "Focal Length could not be determined from metadata. <br>"
|
||||||
|
+ "The default Field of View value was used as a fallback, which may lead to inaccurate result or failure."
|
||||||
|
helperText: "Check for missing Image metadata"
|
||||||
|
+ (make && model && !sensorWidth ? " and/or add your Camera Model to the Sensor Database." : ".")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
// fallback status when initialization mode is unset
|
||||||
|
name: "none"
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ QtObject {
|
||||||
|
|
||||||
readonly property color green: "#4CAF50"
|
readonly property color green: "#4CAF50"
|
||||||
readonly property color orange: "#FF9800"
|
readonly property color orange: "#FF9800"
|
||||||
|
readonly property color yellow: "#FFEB3B"
|
||||||
readonly property color red: "#F44336"
|
readonly property color red: "#F44336"
|
||||||
readonly property color blue: "#03A9F4"
|
readonly property color blue: "#03A9F4"
|
||||||
}
|
}
|
||||||
|
|
|
@ -514,6 +514,38 @@ class Reconstruction(UIGraph):
|
||||||
allIntrinsicIds = [i.intrinsicId.value for i in self._cameraInit.intrinsics.value]
|
allIntrinsicIds = [i.intrinsicId.value for i in self._cameraInit.intrinsics.value]
|
||||||
return viewpoint.intrinsicId.value in allIntrinsicIds
|
return viewpoint.intrinsicId.value in allIntrinsicIds
|
||||||
|
|
||||||
|
@Slot(QObject, result=QObject)
|
||||||
|
def getIntrinsic(self, viewpoint):
|
||||||
|
"""
|
||||||
|
Get the intrinsic attribute associated to 'viewpoint' based on its intrinsicId.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
viewpoint (Attribute): the Viewpoint to consider.
|
||||||
|
Returns:
|
||||||
|
Attribute: the Viewpoint's corresponding intrinsic or None if not found.
|
||||||
|
"""
|
||||||
|
return next((i for i in self._cameraInit.intrinsics.value if i.intrinsicId.value == viewpoint.intrinsicId.value)
|
||||||
|
, None)
|
||||||
|
|
||||||
|
@Slot(QObject, result=str)
|
||||||
|
def getIntrinsicInitMode(self, viewpoint):
|
||||||
|
"""
|
||||||
|
Get the initialization mode for the intrinsic associated to 'viewpoint'.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
viewpoint (Attribute): the Viewpoint to consider.
|
||||||
|
Returns:
|
||||||
|
str: the initialization mode of the Viewpoint's intrinsic or an empty string if none.
|
||||||
|
"""
|
||||||
|
intrinsic = self.getIntrinsic(viewpoint)
|
||||||
|
if not intrinsic:
|
||||||
|
return ""
|
||||||
|
try:
|
||||||
|
return intrinsic.initializationMode.value
|
||||||
|
except AttributeError:
|
||||||
|
# handle older versions that did not have this attribute
|
||||||
|
return ""
|
||||||
|
|
||||||
@Slot(QObject, result=bool)
|
@Slot(QObject, result=bool)
|
||||||
def hasMetadata(self, viewpoint):
|
def hasMetadata(self, viewpoint):
|
||||||
# Should be greater than 2 to avoid the particular case of ""
|
# Should be greater than 2 to avoid the particular case of ""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue