mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-07-30 23:08:25 +02:00
[Node] ExtractMetadata: Add option to update sfmData
This commit is contained in:
parent
3e854e7b38
commit
baa2e220ed
1 changed files with 51 additions and 44 deletions
|
@ -2,6 +2,9 @@ __version__ = "0.1"
|
||||||
|
|
||||||
from meshroom.core import desc
|
from meshroom.core import desc
|
||||||
from meshroom.core.utils import VERBOSE_LEVEL
|
from meshroom.core.utils import VERBOSE_LEVEL
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pyalicevision as av
|
||||||
|
|
||||||
import distutils.dir_util as du
|
import distutils.dir_util as du
|
||||||
import shutil
|
import shutil
|
||||||
|
@ -45,6 +48,12 @@ Using exifTool, this node extracts metadata of all images referenced in a sfmDat
|
||||||
description="ExifTool command arguments",
|
description="ExifTool command arguments",
|
||||||
value="",
|
value="",
|
||||||
),
|
),
|
||||||
|
desc.BoolParam(
|
||||||
|
name="insertInSfm",
|
||||||
|
label="Update sfmData",
|
||||||
|
description="Insert the extracted metadata in the sfmData file.",
|
||||||
|
value=False,
|
||||||
|
),
|
||||||
desc.ChoiceParam(
|
desc.ChoiceParam(
|
||||||
name="verboseLevel",
|
name="verboseLevel",
|
||||||
label="Verbose Level",
|
label="Verbose Level",
|
||||||
|
@ -58,64 +67,62 @@ Using exifTool, this node extracts metadata of all images referenced in a sfmDat
|
||||||
desc.File(
|
desc.File(
|
||||||
name="output",
|
name="output",
|
||||||
label="Result Folder",
|
label="Result Folder",
|
||||||
description="Output path for the resulting images.",
|
description="Output path for the resulting metadata files.",
|
||||||
value=desc.Node.internalFolder,
|
value=desc.Node.internalFolder,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
def resolvedPaths(self, inputSfm, outDir, keepFilename, extension):
|
|
||||||
import pyalicevision as av
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
paths = {}
|
|
||||||
dataAV = av.sfmData.SfMData()
|
|
||||||
if av.sfmDataIO.load(dataAV, inputSfm, av.sfmDataIO.ALL) and os.path.isdir(outDir):
|
|
||||||
views = dataAV.getViews()
|
|
||||||
for id, v in views.items():
|
|
||||||
inputFile = v.getImage().getImagePath()
|
|
||||||
if keepFilename:
|
|
||||||
outputMetadata = os.path.join(outDir, Path(inputFile).stem + "." + extension)
|
|
||||||
else:
|
|
||||||
outputMetadata = os.path.join(outDir, str(id) + "." + extension)
|
|
||||||
paths[inputFile] = outputMetadata
|
|
||||||
|
|
||||||
return paths
|
|
||||||
|
|
||||||
def processChunk(self, chunk):
|
def processChunk(self, chunk):
|
||||||
try:
|
try:
|
||||||
chunk.logManager.start(chunk.node.verboseLevel.value)
|
chunk.logManager.start(chunk.node.verboseLevel.value)
|
||||||
|
|
||||||
if not chunk.node.input:
|
if chunk.node.input.value == "" or chunk.node.input.value[-4:].lower() != '.sfm':
|
||||||
chunk.logger.warning('No image file to process')
|
error = 'This node need to have a sfmData connected as input.'
|
||||||
return
|
|
||||||
|
|
||||||
outFiles = self.resolvedPaths(chunk.node.input.value, chunk.node.output.value, chunk.node.keepFilename.value, chunk.node.extension.value)
|
|
||||||
|
|
||||||
if not outFiles:
|
|
||||||
error = 'ExtractMetadata: No input files! Check that a sfmData is connected as input.'
|
|
||||||
chunk.logger.error(error)
|
chunk.logger.error(error)
|
||||||
raise RuntimeError(error)
|
raise RuntimeError(error)
|
||||||
|
|
||||||
if not os.path.exists(chunk.node.output.value):
|
if not os.path.exists(chunk.node.output.value):
|
||||||
os.mkdir(chunk.node.output.value)
|
os.mkdir(chunk.node.output.value)
|
||||||
|
|
||||||
for iFile, oFile in outFiles.items():
|
dataAV = av.sfmData.SfMData()
|
||||||
if chunk.node.extension.value == 'txt':
|
if av.sfmDataIO.load(dataAV, chunk.node.input.value, av.sfmDataIO.ALL):
|
||||||
cmd = 'exiftool ' + chunk.node.arguments.value.strip() + ' ' + iFile + ' > ' + oFile
|
views = dataAV.getViews()
|
||||||
elif chunk.node.extension.value == 'xml':
|
for id, v in views.items():
|
||||||
cmd = 'exiftool -X ' + chunk.node.arguments.value.strip() + ' ' + iFile + ' > ' + oFile
|
inputFile = v.getImage().getImagePath()
|
||||||
else: #xmp
|
if chunk.node.keepFilename.value:
|
||||||
cmd = 'exiftool -tagsfromfile ' + iFile + ' ' + chunk.node.arguments.value.strip() + ' ' + oFile
|
outputMetadataFilename = os.path.join(chunk.node.output.value, Path(inputFile).stem + "." + chunk.node.extension.value)
|
||||||
chunk.logger.debug(cmd)
|
else:
|
||||||
error = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read().decode()
|
outputMetadataFilename = os.path.join(chunk.node.output.value, str(id) + "." + chunk.node.extension.value)
|
||||||
chunk.logger.debug(error)
|
|
||||||
if error != "":
|
if chunk.node.extension.value == 'txt':
|
||||||
chunk.logger.error(error)
|
cmd = 'exiftool ' + chunk.node.arguments.value.strip() + ' ' + inputFile + ' > ' + outputMetadataFilename
|
||||||
raise RuntimeError(error)
|
elif chunk.node.extension.value == 'xml':
|
||||||
if not os.path.exists(oFile):
|
cmd = 'exiftool -X ' + chunk.node.arguments.value.strip() + ' ' + inputFile + ' > ' + outputMetadataFilename
|
||||||
info = 'No metadata extracted for file ' + iFile
|
else: #xmp
|
||||||
chunk.logger.info(info)
|
cmd = 'exiftool -tagsfromfile ' + inputFile + ' ' + chunk.node.arguments.value.strip() + ' ' + outputMetadataFilename
|
||||||
chunk.logger.info('Metadata extraction end')
|
chunk.logger.debug(cmd)
|
||||||
|
error = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read().decode()
|
||||||
|
chunk.logger.debug(error)
|
||||||
|
if error != "":
|
||||||
|
chunk.logger.error(error)
|
||||||
|
raise RuntimeError(error)
|
||||||
|
if not os.path.exists(outputMetadataFilename):
|
||||||
|
info = 'No metadata extracted for file ' + inputFile
|
||||||
|
chunk.logger.info(info)
|
||||||
|
elif chunk.node.insertInSfm.value:
|
||||||
|
cmd = 'exiftool ' + chunk.node.arguments.value.strip() + ' ' + inputFile
|
||||||
|
metadata = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read().decode()
|
||||||
|
chunk.logger.debug(metadata)
|
||||||
|
lmeta = metadata.split('\n')
|
||||||
|
for i in range(1, len(lmeta)-1):
|
||||||
|
l = lmeta[i].split(':', 1)
|
||||||
|
v.getImageInfo().addMetadata('ExifTool:'+l[0].strip(), l[1].strip())
|
||||||
|
|
||||||
|
if chunk.node.insertInSfm.value:
|
||||||
|
outputSfm = os.path.join(chunk.node.output.value, Path(chunk.node.input.value).stem + ".sfm")
|
||||||
|
av.sfmDataIO.save(dataAV, outputSfm, av.sfmDataIO.ALL)
|
||||||
|
|
||||||
|
chunk.logger.info('Metadata extraction end')
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
chunk.logManager.end()
|
chunk.logManager.end()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue