[reconstruction] retrieve and expose solved intrinsics

* [nodes] SfM: make more generic method to get SfM results and return solved intrinsics in addition to views and poses
* [reconstruction] store and expose solved intrinsics by viewpoints
This commit is contained in:
Yann Lanthony 2019-09-10 18:23:35 +02:00
parent bf912cd353
commit c7a55e56b7
No known key found for this signature in database
GPG key ID: 519FAE6DF7A70642
2 changed files with 27 additions and 11 deletions

View file

@ -267,19 +267,20 @@ class StructureFromMotion(desc.CommandLineNode):
]
@staticmethod
def getViewsAndPoses(node):
def getResults(node):
"""
Parse SfM result and return views and poses as two dict with viewId and poseId as keys.
Parse SfM result and return views, poses and intrinsics as three dicts with viewId, poseId and intrinsicId as keys.
"""
reportFile = node.outputViewsAndPoses.value
if not os.path.exists(reportFile):
return {}, {}
return {}, {}, {}
with open(reportFile) as jsonFile:
report = json.load(jsonFile)
views = dict()
poses = dict()
intrinsics = dict()
for view in report['views']:
views[view['viewId']] = view
@ -287,4 +288,7 @@ class StructureFromMotion(desc.CommandLineNode):
for pose in report['poses']:
poses[pose['poseId']] = pose['pose']
return views, poses
for intrinsic in report['intrinsics']:
intrinsics[intrinsic['intrinsicId']] = intrinsic
return views, poses, intrinsics

View file

@ -178,6 +178,7 @@ class Reconstruction(UIGraph):
self._sfm = None
self._views = None
self._poses = None
self._solvedIntrinsics = None
self._selectedViewId = None
self._liveSfmManager = LiveSfmManager(self)
@ -465,15 +466,16 @@ class Reconstruction(UIGraph):
buildingIntrinsics = Property(bool, lambda self: self._buildingIntrinsics, notify=buildingIntrinsicsChanged)
liveSfmManager = Property(QObject, lambda self: self._liveSfmManager, constant=True)
def updateViewsAndPoses(self):
def updateSfMResults(self):
"""
Update internal views and poses based on the current SfM node.
Update internal views, poses and solved intrinsics based on the current SfM node.
"""
if not self._sfm:
self._views = dict()
self._poses = dict()
self._solvedIntrinsics = dict()
else:
self._views, self._poses = self._sfm.nodeDesc.getViewsAndPoses(self._sfm)
self._views, self._poses, self._solvedIntrinsics = self._sfm.nodeDesc.getResults(self._sfm)
self.sfmReportChanged.emit()
def getSfm(self):
@ -490,15 +492,15 @@ class Reconstruction(UIGraph):
See Also: setSfm
"""
self._sfm = node
# Update views and poses and do so each time
# Update sfm results and do so each time
# the status of the SfM node's only chunk changes
self.updateViewsAndPoses()
self.updateSfMResults()
if self._sfm:
# when destroyed, directly use '_setSfm' to bypass
# disconnection step in 'setSfm' (at this point, 'self._sfm' underlying object
# has been destroyed and can't be evaluated anymore)
self._sfm.destroyed.connect(self._unsetSfm)
self._sfm.chunks[0].statusChanged.connect(self.updateViewsAndPoses)
self._sfm.chunks[0].statusChanged.connect(self.updateSfMResults)
self.sfmChanged.emit()
def setSfm(self, node):
@ -507,7 +509,7 @@ class Reconstruction(UIGraph):
"""
# disconnect from previous SfM node if any
if self._sfm:
self._sfm.chunks[0].statusChanged.disconnect(self.updateViewsAndPoses)
self._sfm.chunks[0].statusChanged.disconnect(self.updateSfMResults)
self._sfm.destroyed.disconnect(self._unsetSfm)
self._setSfm(node)
@ -564,6 +566,16 @@ class Reconstruction(UIGraph):
""" Get the number of reconstructed cameras in the current context. """
return len([v for v in self.getViewpoints() if self.isReconstructed(v)])
@Slot(QObject, result="QVariant")
def getSolvedIntrinsics(self, viewpoint):
""" Return viewpoint's solved intrinsics if it has been reconstructed, None otherwise.
Args:
viewpoint: the viewpoint object to instrinsics for.
"""
if not viewpoint:
return None
return self._solvedIntrinsics.get(str(viewpoint.intrinsicId.value), None)
selectedViewIdChanged = Signal()
selectedViewId = Property(str, lambda self: self._selectedViewId, setSelectedViewId, notify=selectedViewIdChanged)