mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-06-05 20:31:56 +02:00
[ui] Add visualisation for automatically detected fisheye circle
This commit is contained in:
parent
b7b1f49bc5
commit
bb60c9b78d
4 changed files with 72 additions and 12 deletions
|
@ -45,6 +45,13 @@ class PanoramaInit(desc.CommandLineNode):
|
|||
value=False,
|
||||
uid=[0],
|
||||
),
|
||||
desc.BoolParam(
|
||||
name='estimateFisheyeCircle',
|
||||
label='Estimate Fisheye Circle',
|
||||
description='Automatically estimate the Fisheye Circle center and radius instead of using user values.',
|
||||
value=True,
|
||||
uid=[0],
|
||||
),
|
||||
desc.GroupAttribute(
|
||||
name="fisheyeCenterOffset",
|
||||
label="Fisheye Center",
|
||||
|
|
|
@ -3,6 +3,8 @@ import QtQuick 2.11
|
|||
Rectangle {
|
||||
id: root
|
||||
|
||||
property bool readOnly: false
|
||||
|
||||
signal moved()
|
||||
signal incrementRadius(real radiusOffset)
|
||||
|
||||
|
@ -10,7 +12,20 @@ Rectangle {
|
|||
height: width
|
||||
color: "transparent"
|
||||
border.width: 5
|
||||
border.color: "yellow"
|
||||
border.color: readOnly ? "green" : "yellow"
|
||||
|
||||
Rectangle {
|
||||
color: parent.color
|
||||
anchors.centerIn: parent
|
||||
width: 20
|
||||
height: 2
|
||||
}
|
||||
Rectangle {
|
||||
color: parent.color
|
||||
anchors.centerIn: parent
|
||||
width: 2
|
||||
height: 20
|
||||
}
|
||||
|
||||
Behavior on x {
|
||||
NumberAnimation {
|
||||
|
@ -32,11 +47,15 @@ Rectangle {
|
|||
|
||||
MouseArea {
|
||||
id: mArea
|
||||
enabled: !root.readOnly
|
||||
anchors.fill: parent
|
||||
cursorShape: controlModifierEnabled ? Qt.SizeBDiagCursor : (pressed ? Qt.ClosedHandCursor : Qt.OpenHandCursor)
|
||||
cursorShape: root.readOnly ? Qt.ArrowCursor : (controlModifierEnabled ? Qt.SizeBDiagCursor : (pressed ? Qt.ClosedHandCursor : Qt.OpenHandCursor))
|
||||
propagateComposedEvents: true
|
||||
|
||||
property bool controlModifierEnabled: false
|
||||
onPositionChanged: {
|
||||
mArea.controlModifierEnabled = (mouse.modifiers & Qt.ControlModifier)
|
||||
mouse.accepted = false;
|
||||
}
|
||||
acceptedButtons: Qt.LeftButton
|
||||
hoverEnabled: true
|
||||
|
|
|
@ -249,20 +249,31 @@ FocusScope {
|
|||
// note: use a Loader to evaluate if a PanoramaInit node exist and displayFisheyeCircle checked at runtime
|
||||
Loader {
|
||||
anchors.centerIn: parent
|
||||
active: (_reconstruction.panoramaInit && displayFisheyeCircleLoader.checked)
|
||||
active: (displayFisheyeCircleLoader.checked && _reconstruction.panoramaInit)
|
||||
sourceComponent: CircleGizmo {
|
||||
x: _reconstruction.panoramaInit.attribute("fisheyeCenterOffset.fisheyeCenterOffset_x").value
|
||||
y: _reconstruction.panoramaInit.attribute("fisheyeCenterOffset.fisheyeCenterOffset_y").value
|
||||
property real fisheyeRadius: _reconstruction.panoramaInit.attribute("fisheyeRadius").value
|
||||
radius: (imgContainer.image ? Math.min(imgContainer.image.width, imgContainer.image.height) : 1.0) * 0.5 * (fisheyeRadius * 0.01)
|
||||
border.width: Math.max(1, (3.0 / imgContainer.scale))
|
||||
property bool useAuto: _reconstruction.panoramaInit.attribute("estimateFisheyeCircle").value
|
||||
readOnly: useAuto
|
||||
visible: (!useAuto) || _reconstruction.panoramaInit.isComputed
|
||||
property real userFisheyeRadius: _reconstruction.panoramaInit.attribute("fisheyeRadius").value
|
||||
property variant fisheyeAutoParams: _reconstruction.getAutoFisheyeCircle(_reconstruction.panoramaInit)
|
||||
|
||||
x: useAuto ? (fisheyeAutoParams.x - imgContainer.image.width * 0.5) : _reconstruction.panoramaInit.attribute("fisheyeCenterOffset.fisheyeCenterOffset_x").value
|
||||
y: useAuto ? (fisheyeAutoParams.y - imgContainer.image.height * 0.5) : _reconstruction.panoramaInit.attribute("fisheyeCenterOffset.fisheyeCenterOffset_y").value
|
||||
radius: useAuto ? fisheyeAutoParams.z : ((imgContainer.image ? Math.min(imgContainer.image.width, imgContainer.image.height) : 1.0) * 0.5 * (userFisheyeRadius * 0.01))
|
||||
|
||||
border.width: Math.max(1, (3.0 / imgContainer.scale))
|
||||
onMoved: {
|
||||
_reconstruction.setAttribute(_reconstruction.panoramaInit.attribute("fisheyeCenterOffset.fisheyeCenterOffset_x"), x)
|
||||
_reconstruction.setAttribute(_reconstruction.panoramaInit.attribute("fisheyeCenterOffset.fisheyeCenterOffset_y"), y)
|
||||
if(!useAuto)
|
||||
{
|
||||
_reconstruction.setAttribute(_reconstruction.panoramaInit.attribute("fisheyeCenterOffset.fisheyeCenterOffset_x"), x)
|
||||
_reconstruction.setAttribute(_reconstruction.panoramaInit.attribute("fisheyeCenterOffset.fisheyeCenterOffset_y"), y)
|
||||
}
|
||||
}
|
||||
onIncrementRadius: {
|
||||
_reconstruction.setAttribute(_reconstruction.panoramaInit.attribute("fisheyeRadius"), _reconstruction.panoramaInit.attribute("fisheyeRadius").value + radiusOffset)
|
||||
if(!useAuto)
|
||||
{
|
||||
_reconstruction.setAttribute(_reconstruction.panoramaInit.attribute("fisheyeRadius"), _reconstruction.panoramaInit.attribute("fisheyeRadius").value + radiusOffset)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -406,7 +417,7 @@ FocusScope {
|
|||
}
|
||||
MaterialToolButton {
|
||||
id: displayFisheyeCircleLoader
|
||||
ToolTip.text: "Display Fisheye Circle"
|
||||
ToolTip.text: "Display Fisheye Circle: " + (_reconstruction.panoramaInit ? _reconstruction.panoramaInit.label : "No Node")
|
||||
text: MaterialIcons.panorama_fish_eye
|
||||
font.pointSize: 11
|
||||
Layout.minimumWidth: 0
|
||||
|
|
|
@ -559,6 +559,29 @@ class Reconstruction(UIGraph):
|
|||
tmpCameraInit = Node("CameraInit", viewpoints=views, intrinsics=intrinsics)
|
||||
self.hdrCameraInit = tmpCameraInit
|
||||
|
||||
@Slot(QObject, result=QVector3D)
|
||||
def getAutoFisheyeCircle(self, panoramaInit):
|
||||
if not panoramaInit or not panoramaInit.isComputed:
|
||||
return QVector3D(0.0, 0.0, 0.0)
|
||||
if not panoramaInit.attribute("estimateFisheyeCircle").value:
|
||||
return QVector3D(0.0, 0.0, 0.0)
|
||||
|
||||
sfmFile = panoramaInit.attribute('outSfMDataFilename').value
|
||||
if not os.path.exists(sfmFile):
|
||||
return QVector3D(0.0, 0.0, 0.0)
|
||||
import io # use io.open for Python2/3 compatibility (allow to specify encoding + errors handling)
|
||||
# skip decoding errors to avoid potential exceptions due to non utf-8 characters in images metadata
|
||||
with io.open(sfmFile, 'r', encoding='utf-8', errors='ignore') as f:
|
||||
data = json.load(f)
|
||||
|
||||
intrinsics = data.get('intrinsics', [])
|
||||
if len(intrinsics) == 0:
|
||||
return QVector3D(0.0, 0.0, 0.0)
|
||||
intrinsic = intrinsics[0]
|
||||
|
||||
res = QVector3D(float(intrinsic.get("fisheyeCenterX", 0.0)), float(intrinsic.get("fisheyeCenterY", 0.0)), float(intrinsic.get("fisheyeRadius", 0.0)))
|
||||
return res
|
||||
|
||||
def updatePanoramaInitNode(self):
|
||||
""" Set the current FeatureExtraction node based on the current CameraInit node. """
|
||||
self.panoramaInit = self.lastNodeOfType('PanoramaInit', self.cameraInit) if self.cameraInit else None
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue