kopia lustrzana https://github.com/OpenDroneMap/ODM
Merge pull request #1623 from pierotofy/class
Automated point classification and other improvementspull/1631/head
commit
6a7ab131ca
|
@ -177,6 +177,7 @@ set(custom_libs OpenSfM
|
|||
FPCFilter
|
||||
PyPopsift
|
||||
Obj2Tiles
|
||||
OpenPointClass
|
||||
)
|
||||
|
||||
externalproject_add(mve
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
set(_proj_name openpointclass)
|
||||
set(_SB_BINARY_DIR "${SB_BINARY_DIR}/${_proj_name}")
|
||||
|
||||
ExternalProject_Add(${_proj_name}
|
||||
DEPENDS pdal eigen34
|
||||
PREFIX ${_SB_BINARY_DIR}
|
||||
TMP_DIR ${_SB_BINARY_DIR}/tmp
|
||||
STAMP_DIR ${_SB_BINARY_DIR}/stamp
|
||||
#--Download step--------------
|
||||
DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}
|
||||
GIT_REPOSITORY https://github.com/uav4geo/OpenPointClass
|
||||
GIT_TAG v1.1.3
|
||||
#--Update/Patch step----------
|
||||
UPDATE_COMMAND ""
|
||||
#--Configure step-------------
|
||||
SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name}
|
||||
CMAKE_ARGS
|
||||
-DPDAL_DIR=${SB_INSTALL_DIR}/lib/cmake/PDAL
|
||||
-DWITH_GBT=ON
|
||||
-DBUILD_PCTRAIN=OFF
|
||||
-DEIGEN3_INCLUDE_DIR=${SB_SOURCE_DIR}/eigen34/
|
||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR}
|
||||
${WIN32_CMAKE_ARGS}
|
||||
#--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
|
||||
)
|
|
@ -1,55 +0,0 @@
|
|||
set(_proj_name pcl)
|
||||
set(_SB_BINARY_DIR "${SB_BINARY_DIR}/${_proj_name}")
|
||||
|
||||
ExternalProject_Add(${_proj_name}
|
||||
PREFIX ${_SB_BINARY_DIR}
|
||||
TMP_DIR ${_SB_BINARY_DIR}/tmp
|
||||
STAMP_DIR ${_SB_BINARY_DIR}/stamp
|
||||
#--Download step--------------
|
||||
DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}
|
||||
URL https://github.com/PointCloudLibrary/pcl/archive/refs/tags/pcl-1.11.1.zip
|
||||
#--Update/Patch step----------
|
||||
UPDATE_COMMAND ""
|
||||
#--Configure step-------------
|
||||
SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name}
|
||||
CMAKE_ARGS
|
||||
-DBUILD_features=OFF
|
||||
-DBUILD_filters=OFF
|
||||
-DBUILD_geometry=OFF
|
||||
-DBUILD_keypoints=OFF
|
||||
-DBUILD_outofcore=OFF
|
||||
-DBUILD_people=OFF
|
||||
-DBUILD_recognition=OFF
|
||||
-DBUILD_registration=OFF
|
||||
-DBUILD_sample_consensus=OFF
|
||||
-DBUILD_segmentation=OFF
|
||||
-DBUILD_features=OFF
|
||||
-DBUILD_surface_on_nurbs=OFF
|
||||
-DBUILD_tools=OFF
|
||||
-DBUILD_tracking=OFF
|
||||
-DBUILD_visualization=OFF
|
||||
-DWITH_OPENGL=OFF
|
||||
-DWITH_VTK=OFF
|
||||
-DWITH_QT=OFF
|
||||
-DBUILD_OPENNI=OFF
|
||||
-DBUILD_OPENNI2=OFF
|
||||
-DWITH_OPENNI=OFF
|
||||
-DWITH_OPENNI2=OFF
|
||||
-DWITH_FZAPI=OFF
|
||||
-DWITH_LIBUSB=OFF
|
||||
-DWITH_PCAP=OFF
|
||||
-DWITH_PXCAPI=OFF
|
||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
-DPCL_VERBOSITY_LEVEL=Error
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR}
|
||||
-DPCL_BUILD_WITH_FLANN_DYNAMIC_LINKING_WIN32=ON
|
||||
${WIN32_CMAKE_ARGS}
|
||||
#--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
|
||||
)
|
|
@ -344,7 +344,7 @@ def config(argv=None, parser=None):
|
|||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Classify the point cloud outputs using a Simple Morphological Filter. '
|
||||
help='Classify the point cloud outputs. '
|
||||
'You can control the behavior of this option by tweaking the --dem-* parameters. '
|
||||
'Default: '
|
||||
'%(default)s')
|
||||
|
|
|
@ -16,18 +16,15 @@ def has_popsift_and_can_handle_texsize(width, height):
|
|||
compute_major, compute_minor = get_cuda_compute_version(0)
|
||||
if compute_major < 3 or (compute_major == 3 and compute_minor < 5):
|
||||
# Not supported
|
||||
log.ODM_WARNING("CUDA compute platform is not supported (detected: %s.%s but we need at least 3.5)" % (compute_major, compute_minor))
|
||||
log.ODM_INFO("CUDA compute platform is not supported (detected: %s.%s but we need at least 3.5)" % (compute_major, compute_minor))
|
||||
return False
|
||||
except Exception as e:
|
||||
log.ODM_WARNING("Cannot use GPU for feature extraction: %s" % str(e))
|
||||
log.ODM_INFO("Using CPU for feature extraction: %s" % str(e))
|
||||
return False
|
||||
|
||||
try:
|
||||
from opensfm import pypopsift
|
||||
fits = pypopsift.fits_texture(int(width * 1.02), int(height * 1.02))
|
||||
if not fits:
|
||||
log.ODM_WARNING("Image size (%sx%spx) would not fit in GPU memory, try lowering --feature-quality. Falling back to CPU" % (width, height))
|
||||
return fits
|
||||
return pypopsift.fits_texture(int(width * 1.02), int(height * 1.02))
|
||||
except (ModuleNotFoundError, ImportError):
|
||||
return False
|
||||
except Exception as e:
|
||||
|
@ -91,5 +88,4 @@ def has_gpu(args):
|
|||
log.ODM_INFO("nvidia-smi detected")
|
||||
return True
|
||||
else:
|
||||
log.ODM_INFO("nvidia-smi not found in PATH, using CPU")
|
||||
return False
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import os
|
||||
from opendm.ai import get_model
|
||||
from opendm import log
|
||||
from opendm.system import run
|
||||
from opendm import io
|
||||
|
||||
def classify(point_cloud):
|
||||
tmp_output = io.related_file_path(point_cloud, postfix=".classified")
|
||||
if os.path.isfile(tmp_output):
|
||||
os.remove(tmp_output)
|
||||
|
||||
try:
|
||||
model = get_model("openpointclass",
|
||||
"https://github.com/uav4geo/OpenPointClass/releases/download/v1.1.3/vehicles-vegetation-buildings.zip",
|
||||
"v1.0.0",
|
||||
name="model.bin")
|
||||
|
||||
if model is not None:
|
||||
run('pcclassify "%s" "%s" "%s" -u -s 2,64' % (point_cloud, tmp_output, model))
|
||||
|
||||
if os.path.isfile(tmp_output):
|
||||
os.remove(point_cloud)
|
||||
os.rename(tmp_output, point_cloud)
|
||||
else:
|
||||
log.ODM_WARNING("Cannot classify using OpenPointClass (no output generated)")
|
||||
else:
|
||||
log.ODM_WARNING("Cannot download/access model from %s" % (model_url))
|
||||
|
||||
except Exception as e:
|
||||
log.ODM_WARNING("Cannot classify using OpenPointClass: %s" % str(e))
|
||||
|
|
@ -330,3 +330,8 @@ class ODMLoadDatasetStage(types.ODM_Stage):
|
|||
log.ODM_WARNING("No omega/phi/kappa angles found in input photos (%s), switching sfm-algorithm to incremental" % p.filename)
|
||||
args.sfm_algorithm = 'incremental'
|
||||
break
|
||||
|
||||
# Rolling shutter cannot be done in non-georeferenced datasets
|
||||
if args.rolling_shutter and not reconstruction.is_georeferenced():
|
||||
log.ODM_WARNING("Reconstruction is not georeferenced, disabling rolling shutter correction")
|
||||
args.rolling_shutter = False
|
||||
|
|
|
@ -12,7 +12,7 @@ from opendm.cropper import Cropper
|
|||
from opendm import pseudogeo
|
||||
from opendm.tiles.tiler import generate_dem_tiles
|
||||
from opendm.cogeo import convert_to_cogeo
|
||||
|
||||
from opendm.opc import classify
|
||||
|
||||
class ODMDEMStage(types.ODM_Stage):
|
||||
def process(self, args, outputs):
|
||||
|
@ -49,7 +49,7 @@ class ODMDEMStage(types.ODM_Stage):
|
|||
pc_classify_marker = os.path.join(odm_dem_root, 'pc_classify_done.txt')
|
||||
|
||||
if not io.file_exists(pc_classify_marker) or self.rerun():
|
||||
log.ODM_INFO("Classifying {} using Simple Morphological Filter".format(dem_input))
|
||||
log.ODM_INFO("Classifying {} using Simple Morphological Filter (1/2)".format(dem_input))
|
||||
commands.classify(dem_input,
|
||||
args.smrf_scalar,
|
||||
args.smrf_slope,
|
||||
|
@ -57,6 +57,9 @@ class ODMDEMStage(types.ODM_Stage):
|
|||
args.smrf_window
|
||||
)
|
||||
|
||||
log.ODM_INFO("Classifying {} using OpenPointClass (2/2)".format(dem_input))
|
||||
classify(dem_input)
|
||||
|
||||
with open(pc_classify_marker, 'w') as f:
|
||||
f.write('Classify: smrf\n')
|
||||
f.write('Scalar: {}\n'.format(args.smrf_scalar))
|
||||
|
|
Ładowanie…
Reference in New Issue