kopia lustrzana https://github.com/OpenDroneMap/ODM
GRASS commands POC for cutlines generation
rodzic
3dfa632d0e
commit
15045d542a
|
@ -2,7 +2,7 @@
|
||||||
# max_concurrency: maximum number of parallel processes to use
|
# max_concurrency: maximum number of parallel processes to use
|
||||||
# memory: maximum MB of memory to use
|
# memory: maximum MB of memory to use
|
||||||
# ------
|
# ------
|
||||||
# output: If successful, prints the full path to the contours file. Otherwise it prints "error"
|
# output: If successful, prints the full path to the cutlines file. Otherwise it prints "error"
|
||||||
|
|
||||||
# Split string using ',' separator
|
# Split string using ',' separator
|
||||||
IFS=',' read -ra DST <<< "${orthophoto_files}"
|
IFS=',' read -ra DST <<< "${orthophoto_files}"
|
||||||
|
@ -10,13 +10,39 @@ ORTHOPHOTO_FILES=("$${DST[@]}")
|
||||||
|
|
||||||
i=0
|
i=0
|
||||||
existing_cutlines=""
|
existing_cutlines=""
|
||||||
|
current_rasters=""
|
||||||
|
|
||||||
for orthophoto_file in "$${ORTHOPHOTO_FILES[@]}"; do
|
for orthophoto_file in "$${ORTHOPHOTO_FILES[@]}"; do
|
||||||
|
|
||||||
# Import orthophoto
|
# Import orthophoto (green band only)
|
||||||
r.external input=$$orthophoto_file output=ortho$$i --overwrite
|
r.external band=2 input="$$orthophoto_file" output=ortho$$i --overwrite
|
||||||
|
|
||||||
|
# Generate polygon area
|
||||||
|
gdal_polygonize.py -b 4 -f GeoPKG
|
||||||
|
|
||||||
|
# Set nodata
|
||||||
|
r.null map=ortho$$i setnull=0
|
||||||
|
|
||||||
|
current_rasters="ortho$$i,$$current_rasters"
|
||||||
|
g.region raster="$$current_rasters"
|
||||||
|
|
||||||
# Generate cutlines
|
# Generate cutlines
|
||||||
i.cutlines --overwrite input=ortho$$i output=cutline$$i number_lines=4 edge_detection=zc processes=${max_concurrency} memory=${memory}
|
i.cutlines.py --overwrite input=ortho$$i output=cutline$$i number_lines=4 edge_detection=zc existing_cutlines=$$existing_cutlines processes=${max_concurrency} memory=${memory}
|
||||||
|
|
||||||
|
# TODO: use below for values (canny, etc.)
|
||||||
|
#i.cutlines.py --overwrite input=ortho2.blue@PERMANENT output=cutline number_lines=16 edge_detection=canny no_edge_friction=10 lane_border_multiplier=100 processes=1 memory=300
|
||||||
|
|
||||||
|
|
||||||
|
# TODO select only polygons within safe area
|
||||||
|
#v.select ainput=cutline -binput=area -output=result operator=within
|
||||||
|
|
||||||
|
# TODO add these too
|
||||||
|
# GRASS commands for dissolve don't seem to work as expected
|
||||||
|
#ogr2ogr -f GPKG -overwrite -explodecollections -dialect SQLite -sql "SELECT ST_Union(geom) FROM result" -nln dissolved dissolved.gpkg result.gpkg
|
||||||
|
#ogr2ogr -f GPKG -overwrite -dialect SQLITE -sql "SELECT * FROM dissolved ORDER BY ST_AREA(geom) DESC LIMIT 1" -nln cutline cutline.gpkg dissolved.gpkg
|
||||||
|
|
||||||
|
# Export
|
||||||
|
v.out.ogr input="cutline$$i" output="cutline$$i.gpkg" format=GPKG
|
||||||
|
|
||||||
# Prepend cutline to list of cutlines
|
# Prepend cutline to list of cutlines
|
||||||
existing_cutlines="cutline$$i,$$existing_cutlines"
|
existing_cutlines="cutline$$i,$$existing_cutlines"
|
||||||
|
@ -25,13 +51,8 @@ for orthophoto_file in "$${ORTHOPHOTO_FILES[@]}"; do
|
||||||
i=$$[i+1]
|
i=$$[i+1]
|
||||||
done
|
done
|
||||||
|
|
||||||
last_cutline="cutline$$[i-1]"
|
if [ -e "cutline0.gpkg" ]; then
|
||||||
|
echo "$$(pwd)/cutline0.gpkg"
|
||||||
# Export
|
|
||||||
v.out.ogr input="$$last_cutline" output="cutline.gpkg" format=GPKG
|
|
||||||
|
|
||||||
if [ -e "cutline.gpkg" ]; then
|
|
||||||
echo "$$(pwd)/cutline.gpkg"
|
|
||||||
else
|
else
|
||||||
echo "error"
|
echo "error"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -2,6 +2,8 @@ import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
from opendm import log
|
from opendm import log
|
||||||
from opendm import system
|
from opendm import system
|
||||||
|
|
||||||
|
@ -88,20 +90,29 @@ class GrassContext:
|
||||||
f.write(tmpl.substitute(self.template_args))
|
f.write(tmpl.substitute(self.template_args))
|
||||||
|
|
||||||
# Execute it
|
# Execute it
|
||||||
log.ODM_INFO("Executing grass script from {}: {} -c {} location --exec sh script.sh".format(self.get_cwd(), self.grass_binary, self.location))
|
log.ODM_INFO("Executing grass script from {}: {} --tmp-location {} --exec bash script.sh".format(self.get_cwd(), self.grass_binary, self.location))
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
env["GRASS_ADDON_PATH"] = env.get("GRASS_ADDON_PATH", "") + ":" + os.path.abspath(os.path.join("scripts/grass_addons"))
|
env["GRASS_ADDON_PATH"] = env.get("GRASS_ADDON_PATH", "") + os.path.abspath(os.path.join("scripts/grass_addons"))
|
||||||
p = subprocess.Popen([self.grass_binary, '-c', self.location, 'location', '--exec', 'sh', 'script.sh'],
|
|
||||||
cwd=self.get_cwd(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
|
|
||||||
out, err = p.communicate()
|
|
||||||
|
|
||||||
out = out.decode('utf-8').strip()
|
filename = os.path.join(self.get_cwd(), 'output.log')
|
||||||
err = err.decode('utf-8').strip()
|
with open(filename, 'wb') as writer, open(filename, 'rb', 1) as reader:
|
||||||
|
p = subprocess.Popen([self.grass_binary, '--tmp-location', self.location, '--exec', 'bash', 'script.sh'],
|
||||||
|
cwd=self.get_cwd(), stdout=subprocess.PIPE, stderr=writer, env=env)
|
||||||
|
|
||||||
if p.returncode == 0:
|
while p.poll() is None:
|
||||||
return out
|
sys.stdout.write(reader.read())
|
||||||
else:
|
time.sleep(0.5)
|
||||||
raise GrassEngineException("Could not execute GRASS script {} from {}: {}".format(script, self.get_cwd(), err))
|
|
||||||
|
# Read the remaining
|
||||||
|
sys.stdout.write(reader.read())
|
||||||
|
|
||||||
|
out, err = p.communicate()
|
||||||
|
out = out.decode('utf-8').strip()
|
||||||
|
|
||||||
|
if p.returncode == 0:
|
||||||
|
return out
|
||||||
|
else:
|
||||||
|
raise GrassEngineException("Could not execute GRASS script {} from {}: {}".format(script, self.get_cwd(), err))
|
||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
return {
|
return {
|
||||||
|
|
2
run.py
2
run.py
|
@ -43,7 +43,7 @@ if __name__ == '__main__':
|
||||||
app.execute()
|
app.execute()
|
||||||
|
|
||||||
# Do not show ASCII art for local submodels runs
|
# Do not show ASCII art for local submodels runs
|
||||||
if not "submodels/submodel_" in args.project_path:
|
if False and not "submodels/submodel_" in args.project_path:
|
||||||
log.ODM_INFO('MMMMMMMMMMMNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNMMMMMMMMMMM')
|
log.ODM_INFO('MMMMMMMMMMMNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNMMMMMMMMMMM')
|
||||||
log.ODM_INFO('MMMMMMdo:..---../sNMMMMMMMMMMMMMMMMMMMMMMMMMMNs/..---..:odMMMMMM')
|
log.ODM_INFO('MMMMMMdo:..---../sNMMMMMMMMMMMMMMMMMMMMMMMMMMNs/..---..:odMMMMMM')
|
||||||
log.ODM_INFO('MMMMy-.odNMMMMMNy/`/mMMMMMMMMMMMMMMMMMMMMMMm/`/hNMMMMMNdo.-yMMMM')
|
log.ODM_INFO('MMMMy-.odNMMMMMNy/`/mMMMMMMMMMMMMMMMMMMMMMMm/`/hNMMMMMNdo.-yMMMM')
|
||||||
|
|
|
@ -136,13 +136,17 @@ class ODMMergeStage(types.ODM_Stage):
|
||||||
if len(all_orthophotos) > 1:
|
if len(all_orthophotos) > 1:
|
||||||
gctx = grass.create_context({'auto_cleanup' : False})
|
gctx = grass.create_context({'auto_cleanup' : False})
|
||||||
|
|
||||||
gctx.add_param('orthophoto_files', ",".join(map(quote, all_orthophotos)))
|
gctx.add_param('orthophoto_files', ",".join(all_orthophotos))
|
||||||
gctx.add_param('max_concurrency', args.max_concurrency)
|
gctx.add_param('max_concurrency', args.max_concurrency)
|
||||||
gctx.add_param('memory', concurrency.get_max_memory_mb(300))
|
gctx.add_param('memory', int(concurrency.get_max_memory_mb(300)))
|
||||||
gctx.set_location(all_orthophotos[0])
|
gctx.set_location(all_orthophotos[0])
|
||||||
|
|
||||||
cutline_file = gctx.execute(os.path.join("opendm", "grass", "generate_cutlines.grass"))
|
cutline_file = gctx.execute(os.path.join("opendm", "grass", "generate_cutlines.grass"))
|
||||||
|
if cutline_file != 'error':
|
||||||
|
log.ODM_INFO("YAY")
|
||||||
|
log.ODM_INFO(cutline_file)
|
||||||
|
else:
|
||||||
|
log.ODM_WARNING("Could not generate orthophoto cutlines. An error occured when running GRASS. No orthophoto will be generated.")
|
||||||
elif len(all_orthophotos) == 1:
|
elif len(all_orthophotos) == 1:
|
||||||
# Simply copy
|
# Simply copy
|
||||||
log.ODM_WARNING("A single orthophoto was found between all submodels.")
|
log.ODM_WARNING("A single orthophoto was found between all submodels.")
|
||||||
|
|
Ładowanie…
Reference in New Issue