Merge remote-tracking branch 'origin/master' into odm_output_improvements

pull/889/head
Piero Toffanin 2018-07-02 10:18:27 -04:00
commit d1ff9e0f2f
12 zmienionych plików z 98 dodań i 30 usunięć

Wyświetl plik

@ -21,7 +21,7 @@ libexiv2-dev liblas-bin python-matplotlib libatlas-base-dev swig2.0 python-wheel
RUN apt-get remove libdc1394-22-dev RUN apt-get remove libdc1394-22-dev
RUN pip install --upgrade pip RUN pip install --upgrade pip
RUN pip install setuptools RUN pip install setuptools
RUN pip install -U PyYAML exifread gpxpy xmltodict catkin-pkg appsettings gippy loky shapely numpy pyproj psutil && pip install -U scipy --ignore-installed RUN pip install -U PyYAML exifread gpxpy xmltodict catkin-pkg appsettings https://github.com/gipit/gippy/archive/v1.0.0.zip loky shapely numpy pyproj psutil && pip install -U scipy --ignore-installed
ENV PYTHONPATH="$PYTHONPATH:/code/SuperBuild/install/lib/python2.7/dist-packages" ENV PYTHONPATH="$PYTHONPATH:/code/SuperBuild/install/lib/python2.7/dist-packages"
ENV PYTHONPATH="$PYTHONPATH:/code/SuperBuild/src/opensfm" ENV PYTHONPATH="$PYTHONPATH:/code/SuperBuild/src/opensfm"

Wyświetl plik

@ -30,7 +30,11 @@ instructions through "Create a Docker group". The Docker image workflow
has equivalent procedures for Mac OS X and Windows found at [docs.docker.com](docs.docker.com). Then run the following command which will build a pre-built image and run on images found in `$(pwd)/images` (you can change this if you need to, see the [wiki](https://github.com/OpenDroneMap/OpenDroneMap/wiki/Docker) for more detailed instructions. has equivalent procedures for Mac OS X and Windows found at [docs.docker.com](docs.docker.com). Then run the following command which will build a pre-built image and run on images found in `$(pwd)/images` (you can change this if you need to, see the [wiki](https://github.com/OpenDroneMap/OpenDroneMap/wiki/Docker) for more detailed instructions.
``` ```
docker run -it --rm -v $(pwd)/images:/code/images -v $(pwd)/odm_orthophoto:/code/odm_orthophoto -v $(pwd)/odm_texturing:/code/odm_texturing opendronemap/opendronemap docker run -it --rm \
-v "$(pwd)/images:/code/images" \
-v "$(pwd)/odm_orthophoto:/code/odm_orthophoto" \
-v "$(pwd)/odm_texturing:/code/odm_texturing" \
opendronemap/opendronemap
``` ```
### Native Install (Ubuntu 16.04) ### Native Install (Ubuntu 16.04)
@ -126,7 +130,7 @@ When the process finishes, the results will be organized as follows:
|-- texture_N.jpg # Associated textured images used by the model |-- texture_N.jpg # Associated textured images used by the model
|-- odm_georeferencing/ |-- odm_georeferencing/
|-- odm_georeferenced_model.ply # A georeferenced dense point cloud |-- odm_georeferenced_model.ply # A georeferenced dense point cloud
|-- odm_georeferenced_model.ply.laz # LAZ format point cloud |-- odm_georeferenced_model.laz # LAZ format point cloud
|-- odm_georeferenced_model.csv # XYZ format point cloud |-- odm_georeferenced_model.csv # XYZ format point cloud
|-- odm_georeferencing_log.txt # Georeferencing log |-- odm_georeferencing_log.txt # Georeferencing log
|-- odm_georeferencing_transform.txt# Transform used for georeferencing |-- odm_georeferencing_transform.txt# Transform used for georeferencing
@ -155,12 +159,20 @@ installed on your machine. Docker software is free to install and use in this co
see the [Docker Ubuntu installation tutorial](https://docs.docker.com/engine/installation/linux/ubuntulinux/) and follow the see the [Docker Ubuntu installation tutorial](https://docs.docker.com/engine/installation/linux/ubuntulinux/) and follow the
instructions through "Create a Docker group". Once Docker is installed, the fastest way to use OpenDroneMap is to run a pre-built image by typing: instructions through "Create a Docker group". Once Docker is installed, the fastest way to use OpenDroneMap is to run a pre-built image by typing:
docker run -it --rm -v $(pwd)/images:/code/images -v $(pwd)/odm_orthophoto:/code/odm_orthophoto -v $(pwd)/odm_texturing:/code/odm_texturing opendronemap/opendronemap docker run -it --rm \
-v "$(pwd)/images:/code/images" \
-v "$(pwd)/odm_orthophoto:/code/odm_orthophoto" \
-v "$(pwd)/odm_texturing:/code/odm_texturing" \
opendronemap/opendronemap
If you want to build your own Docker image from sources, type: If you want to build your own Docker image from sources, type:
docker build -t my_odm_image . docker build -t my_odm_image .
docker run -it --rm -v $(pwd)/images:/code/images -v $(pwd)/odm_orthophoto:/code/odm_orthophoto -v $(pwd)/odm_texturing:/code/odm_texturing my_odm_image docker run -it --rm \
-v "$(pwd)/images:/code/images" \
-v "$(pwd)/odm_orthophoto:/code/odm_orthophoto" \
-v "$(pwd)/odm_texturing:/code/odm_texturing" \
my_odm_image
Using this method, the containerized ODM will process the images in the OpenDroneMap/images directory and output results Using this method, the containerized ODM will process the images in the OpenDroneMap/images directory and output results
to the OpenDroneMap/odm_orthophoto and OpenDroneMap/odm_texturing directories as described in the [Viewing Results](https://github.com/OpenDroneMap/OpenDroneMap/wiki/Output-and-Results) section. to the OpenDroneMap/odm_orthophoto and OpenDroneMap/odm_texturing directories as described in the [Viewing Results](https://github.com/OpenDroneMap/OpenDroneMap/wiki/Output-and-Results) section.
@ -168,19 +180,40 @@ If you want to view other results outside the Docker image simply add which dire
established above. For example, if you're interested in the dense cloud results generated by PMVS and in the orthophoto, established above. For example, if you're interested in the dense cloud results generated by PMVS and in the orthophoto,
simply use the following `docker run` command after building the image: simply use the following `docker run` command after building the image:
docker run -it --rm -v $(pwd)/images:/code/images -v $(pwd)/odm_georeferencing:/code/odm_georeferencing -v $(pwd)/odm_orthophoto:/code/odm_orthophoto my_odm_image docker run -it --rm \
-v "$(pwd)/images:/code/images" \
-v "$(pwd)/odm_georeferencing:/code/odm_georeferencing" \
-v "$(pwd)/odm_orthophoto:/code/odm_orthophoto" \
my_odm_image
If you want to get all intermediate outputs, run the following command: If you want to get all intermediate outputs, run the following command:
docker run -it --rm -v $(pwd)/images:/code/images -v $(pwd)/odm_georeferencing:/code/odm_georeferencing -v $(pwd)/odm_meshing:/code/odm_meshing -v $(pwd)/odm_orthophoto:/code/odm_orthophoto -v $(pwd)/odm_texturing:/code/odm_texturing -v $(pwd)/opensfm:/code/opensfm -v $(pwd)/pmvs:/code/pmvs opendronemap/opendronemap docker run -it --rm \
-v "$(pwd)/images:/code/images" \
-v "$(pwd)/odm_georeferencing:/code/odm_georeferencing" \
-v "$(pwd)/odm_meshing:/code/odm_meshing" \
-v "$(pwd)/odm_orthophoto:/code/odm_orthophoto" \
-v "$(pwd)/odm_texturing:/code/odm_texturing" \
-v "$(pwd)/opensfm:/code/opensfm" \
-v "$(pwd)/pmvs:/code/pmvs" \
opendronemap/opendronemap
To pass in custom parameters to the run.py script, simply pass it as arguments to the `docker run` command. For example: To pass in custom parameters to the run.py script, simply pass it as arguments to the `docker run` command. For example:
docker run -it --rm -v $(pwd)/images:/code/images v $(pwd)/odm_orthophoto:/code/odm_orthophoto -v $(pwd)/odm_texturing:/code/odm_texturing opendronemap/opendronemap --resize-to 1800 --force-ccd 6.16 docker run -it --rm \
-v "$(pwd)/images:/code/images" \
-v "$(pwd)/odm_orthophoto:/code/odm_orthophoto" \
-v "$(pwd)/odm_texturing:/code/odm_texturing" \
opendronemap/opendronemap --resize-to 1800 --force-ccd 6.16
If you want to pass in custom parameters using the settings.yaml file, you can pass it as a -v volume binding: If you want to pass in custom parameters using the settings.yaml file, you can pass it as a -v volume binding:
docker run -it --rm -v $(pwd)/images:/code/images v $(pwd)/odm_orthophoto:/code/odm_orthophoto -v $(pwd)/odm_texturing:/code/odm_texturing -v $(pwd)/settings.yaml:/code/settings.yaml opendronemap/opendronemap docker run -it --rm \
-v "$(pwd)/images:/code/images" \
-v "$(pwd)/odm_orthophoto:/code/odm_orthophoto" \
-v "$(pwd)/odm_texturing:/code/odm_texturing" \
-v "$(pwd)/settings.yaml:/code/settings.yaml" \
opendronemap/opendronemap
When building your own Docker image, if image size is of importance to you, you should use the ```--squash``` flag, like so: When building your own Docker image, if image size is of importance to you, you should use the ```--squash``` flag, like so:
@ -203,7 +236,7 @@ A web interface and API to OpenDroneMap is currently under active development in
## Video Support ## Video Support
Currently we have an experimental feature that uses ORB_SLAM to render a textured mesh from video. It is only supported on Ubuntu 14.04 on machines with X11 support. See the [wiki](https://github.com/OpenDroneMap/OpenDroneMap/wiki/Reconstruction-from-Video)for details on installation and use. Currently we have an experimental feature that uses ORB_SLAM to render a textured mesh from video. It is only supported on Ubuntu 14.04 on machines with X11 support. See the [wiki](https://github.com/OpenDroneMap/OpenDroneMap/wiki/Reconstruction-from-Video) for details on installation and use.
## Examples ## Examples

Wyświetl plik

@ -124,6 +124,7 @@ set(custom_libs OpenGV
CMVS CMVS
Catkin Catkin
Ecto Ecto
LASzip
PDAL PDAL
MvsTexturing MvsTexturing
) )

Wyświetl plik

@ -0,0 +1,29 @@
set(_proj_name laszip)
set(_SB_BINARY_DIR "${SB_BINARY_DIR}/${_proj_name}")
ExternalProject_Add(${_proj_name}
DEPENDS
PREFIX ${_SB_BINARY_DIR}
TMP_DIR ${_SB_BINARY_DIR}/tmp
STAMP_DIR ${_SB_BINARY_DIR}/stamp
#--Download step--------------
DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}/${_proj_name}
URL https://github.com/LASzip/LASzip/archive/0069c42307183c49744f1eb170f7032a8cf6a9db.zip
#--Update/Patch step----------
UPDATE_COMMAND ""
#--Configure step-------------
SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name}
CMAKE_ARGS
-DBUILD_SHARED_LIBS=ON
-DBUILD_STATIC_LIBS=OFF
-DCMAKE_INSTALL_PREFIX=${SB_INSTALL_DIR}
-DCMAKE_INSTALL_LIBDIR=lib
#--Build step-----------------
BINARY_DIR ${_SB_BINARY_DIR}
#--Install step---------------
INSTALL_DIR ${SB_INSTALL_DIR}
#--Output logging-------------
LOG_DOWNLOAD OFF
LOG_CONFIGURE OFF
LOG_BUILD OFF
)

Wyświetl plik

@ -7,7 +7,7 @@ ExternalProject_Add(${_proj_name}
TMP_DIR ${_SB_BINARY_DIR}/tmp TMP_DIR ${_SB_BINARY_DIR}/tmp
STAMP_DIR ${_SB_BINARY_DIR}/stamp STAMP_DIR ${_SB_BINARY_DIR}/stamp
#--Download step-------------- #--Download step--------------
DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}/${_proj_name}
URL https://github.com/OpenDroneMap/mvs-texturing/archive/master.zip URL https://github.com/OpenDroneMap/mvs-texturing/archive/master.zip
#--Update/Patch step---------- #--Update/Patch step----------
UPDATE_COMMAND "" UPDATE_COMMAND ""

Wyświetl plik

@ -2,14 +2,13 @@ set(_proj_name pdal)
set(_SB_BINARY_DIR "${SB_BINARY_DIR}/${_proj_name}") set(_SB_BINARY_DIR "${SB_BINARY_DIR}/${_proj_name}")
ExternalProject_Add(${_proj_name} ExternalProject_Add(${_proj_name}
DEPENDS hexer DEPENDS hexer laszip
PREFIX ${_SB_BINARY_DIR} PREFIX ${_SB_BINARY_DIR}
TMP_DIR ${_SB_BINARY_DIR}/tmp TMP_DIR ${_SB_BINARY_DIR}/tmp
STAMP_DIR ${_SB_BINARY_DIR}/stamp STAMP_DIR ${_SB_BINARY_DIR}/stamp
#--Download step-------------- #--Download step--------------
DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}
URL https://github.com/PDAL/PDAL/archive/e881b581e3b91a928105d67db44c567f3b6d1afe.tar.gz URL https://github.com/PDAL/PDAL/archive/1.6.zip
URL_MD5 cadbadf1c83d69d6525cfffd41473323
#--Update/Patch step---------- #--Update/Patch step----------
UPDATE_COMMAND "" UPDATE_COMMAND ""
#--Configure step------------- #--Configure step-------------
@ -34,6 +33,11 @@ ExternalProject_Add(${_proj_name}
-DWITH_LAZPERF=OFF -DWITH_LAZPERF=OFF
-DWITH_GEOTIFF=ON -DWITH_GEOTIFF=ON
-DWITH_LASZIP=ON -DWITH_LASZIP=ON
-DLASZIP_FOUND=TRUE
-DLASZIP_LIBRARIES=${SB_INSTALL_DIR}/lib/liblaszip.so
-DLASZIP_VERSION=3.1.1
-DLASZIP_INCLUDE_DIR=${SB_INSTALL_DIR}/include
-DLASZIP_LIBRARY=${SB_INSTALL_DIR}/lib/liblaszip.so
-DWITH_TESTS=OFF -DWITH_TESTS=OFF
-DCMAKE_BUILD_TYPE=Release -DCMAKE_BUILD_TYPE=Release
-DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR} -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR}

Wyświetl plik

@ -100,7 +100,7 @@ install() {
echo "Installing split-merge Dependencies" echo "Installing split-merge Dependencies"
pip install -U scipy shapely numpy pyproj pip install -U scipy shapely numpy pyproj
pip install -U gippy psutil pip install -U https://github.com/gipit/gippy/archive/v1.0.0.zip psutil
echo "Compiling SuperBuild" echo "Compiling SuperBuild"
cd ${RUNPATH}/SuperBuild cd ${RUNPATH}/SuperBuild

Wyświetl plik

@ -19,7 +19,7 @@ libexiv2-dev liblas-bin python-matplotlib libatlas-base-dev swig2.0 python-wheel
RUN apt-get remove libdc1394-22-dev RUN apt-get remove libdc1394-22-dev
RUN pip install --upgrade pip RUN pip install --upgrade pip
RUN pip install setuptools RUN pip install setuptools
RUN pip install -U PyYAML exifread gpxpy xmltodict catkin-pkg appsettings gippy loky shapely numpy pyproj psutil && pip install -U scipy --ignore-installed RUN pip install -U PyYAML exifread gpxpy xmltodict catkin-pkg appsettings https://github.com/gipit/gippy/archive/v1.0.0.zip loky shapely numpy pyproj psutil && pip install -U scipy --ignore-installed
ENV PYTHONPATH="$PYTHONPATH:/code/SuperBuild/install/lib/python2.7/dist-packages" ENV PYTHONPATH="$PYTHONPATH:/code/SuperBuild/install/lib/python2.7/dist-packages"
ENV PYTHONPATH="$PYTHONPATH:/code/SuperBuild/src/opensfm" ENV PYTHONPATH="$PYTHONPATH:/code/SuperBuild/src/opensfm"

Wyświetl plik

@ -255,16 +255,18 @@ class ODM_GeoRef(object):
'srs': self.projection.srs, 'srs': self.projection.srs,
'json': json_file} 'json': json_file}
# create pipeline file transform.xml to enable transformation # create pipeline file las.json to write odm_georeferenced_model.laz point cloud
pipeline = '{{' \ pipeline = '{{' \
' "pipeline":[' \ ' "pipeline":[' \
' "untransformed.ply",' \ ' "untransformed.ply",' \
' {{' \ ' {{' \
' "type":"writers.las",' \
' "a_srs":"{srs}",' \ ' "a_srs":"{srs}",' \
' "offset_x":"{east}",' \ ' "offset_x":"{east}",' \
' "offset_y":"{north}",' \ ' "offset_y":"{north}",' \
' "offset_z":"0",' \ ' "offset_z":"0",' \
' "filename":"transformed.las"' \ ' "compression":"laszip",' \
' "filename":"{f_out}"' \
' }}' \ ' }}' \
' ]' \ ' ]' \
'}}'.format(**kwargs) '}}'.format(**kwargs)
@ -273,8 +275,7 @@ class ODM_GeoRef(object):
f.write(pipeline) f.write(pipeline)
# call pdal # call pdal
system.run('{bin}/pdal pipeline -i {json} --readers.ply.filename={f_in} ' system.run('{bin}/pdal pipeline -i {json} --readers.ply.filename={f_in}'.format(**kwargs))
'--writers.las.filename={f_out}'.format(**kwargs))
def utm_to_latlon(self, _file, _photo, idx): def utm_to_latlon(self, _file, _photo, idx):
@ -477,8 +478,8 @@ class ODM_Tree(object):
self.odm_georeferencing, 'odm_georeferenced_model.csv') self.odm_georeferencing, 'odm_georeferenced_model.csv')
self.odm_georeferencing_las_json = io.join_paths( self.odm_georeferencing_las_json = io.join_paths(
self.odm_georeferencing, 'las.json') self.odm_georeferencing, 'las.json')
self.odm_georeferencing_model_las = io.join_paths( self.odm_georeferencing_model_laz = io.join_paths(
self.odm_georeferencing, 'odm_georeferenced_model.las') self.odm_georeferencing, 'odm_georeferenced_model.laz')
self.odm_georeferencing_dem = io.join_paths( self.odm_georeferencing_dem = io.join_paths(
self.odm_georeferencing, 'odm_georeferencing_model_dem.tif') self.odm_georeferencing, 'odm_georeferencing_model_dem.tif')

Wyświetl plik

@ -28,7 +28,7 @@ class ODMDEMCell(ecto.Cell):
# get inputs # get inputs
args = self.inputs.args args = self.inputs.args
tree = self.inputs.tree tree = self.inputs.tree
las_model_found = io.file_exists(tree.odm_georeferencing_model_las) las_model_found = io.file_exists(tree.odm_georeferencing_model_laz)
# check if we rerun cell or not # check if we rerun cell or not
rerun_cell = (args.rerun is not None and rerun_cell = (args.rerun is not None and
@ -40,7 +40,7 @@ class ODMDEMCell(ecto.Cell):
log.ODM_INFO('Classify: ' + str(args.pc_classify != "none")) log.ODM_INFO('Classify: ' + str(args.pc_classify != "none"))
log.ODM_INFO('Create DSM: ' + str(args.dsm)) log.ODM_INFO('Create DSM: ' + str(args.dsm))
log.ODM_INFO('Create DTM: ' + str(args.dtm)) log.ODM_INFO('Create DTM: ' + str(args.dtm))
log.ODM_INFO('DEM input file {0} found: {1}'.format(tree.odm_georeferencing_model_las, str(las_model_found))) log.ODM_INFO('DEM input file {0} found: {1}'.format(tree.odm_georeferencing_model_laz, str(las_model_found)))
# Setup terrain parameters # Setup terrain parameters
terrain_params_map = { terrain_params_map = {
@ -61,8 +61,8 @@ class ODMDEMCell(ecto.Cell):
pc_classify_marker = os.path.join(odm_dem_root, 'pc_classify_done.txt') pc_classify_marker = os.path.join(odm_dem_root, 'pc_classify_done.txt')
if not io.file_exists(pc_classify_marker) or rerun_cell: if not io.file_exists(pc_classify_marker) or rerun_cell:
log.ODM_INFO("Classifying {} using {}".format(tree.odm_georeferencing_model_las, args.pc_classify)) log.ODM_INFO("Classifying {} using {}".format(tree.odm_georeferencing_model_laz, args.pc_classify))
commands.classify(tree.odm_georeferencing_model_las, commands.classify(tree.odm_georeferencing_model_laz,
args.pc_classify == "smrf", args.pc_classify == "smrf",
slope, slope,
cellsize, cellsize,
@ -96,7 +96,7 @@ class ODMDEMCell(ecto.Cell):
for product in products: for product in products:
commands.create_dems( commands.create_dems(
[tree.odm_georeferencing_model_las], [tree.odm_georeferencing_model_laz],
product, product,
radius=map(str, radius_steps), radius=map(str, radius_steps),
gapfill=True, gapfill=True,

Wyświetl plik

@ -138,7 +138,7 @@ class ODMGeoreferencingCell(ecto.Cell):
# convert ply model to LAS reference system # convert ply model to LAS reference system
geo_ref.convert_to_las(odm_georeferencing_model_ply_geo, geo_ref.convert_to_las(odm_georeferencing_model_ply_geo,
tree.odm_georeferencing_model_las, tree.odm_georeferencing_model_laz,
tree.odm_georeferencing_las_json) tree.odm_georeferencing_las_json)
reconstruction.georef = geo_ref reconstruction.georef = geo_ref
@ -171,7 +171,7 @@ class ODMGeoreferencingCell(ecto.Cell):
if args.crop > 0: if args.crop > 0:
log.ODM_INFO("Calculating cropping area and generating bounds shapefile from point cloud") log.ODM_INFO("Calculating cropping area and generating bounds shapefile from point cloud")
cropper = Cropper(tree.odm_georeferencing, 'odm_georeferenced_model') cropper = Cropper(tree.odm_georeferencing, 'odm_georeferenced_model')
cropper.create_bounds_shapefile(tree.odm_georeferencing_model_las, args.crop) cropper.create_bounds_shapefile(tree.odm_georeferencing_model_laz, args.crop)
# Do not execute a second time, since # Do not execute a second time, since
# We might be doing georeferencing for # We might be doing georeferencing for

Wyświetl plik

@ -136,7 +136,7 @@ class TestGeoreferencing(unittest.TestCase):
def test_las_out(self): def test_las_out(self):
self.assertTrue(os.path.isfile(os.path.join(self.app.georeferencing.inputs.tree.odm_georeferencing, self.assertTrue(os.path.isfile(os.path.join(self.app.georeferencing.inputs.tree.odm_georeferencing,
"odm_georeferenced_model.ply.las"))) "odm_georeferenced_model.laz")))
class TestOrthophoto(unittest.TestCase): class TestOrthophoto(unittest.TestCase):