kopia lustrzana https://github.com/OpenDroneMap/ODM
Blend outside borders of submodels orthophotos during merge
rodzic
1931cc18b3
commit
26c6748f77
|
@ -9,7 +9,7 @@ ExternalProject_Add(${_proj_name}
|
|||
#--Download step--------------
|
||||
DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}
|
||||
GIT_REPOSITORY https://github.com/OpenDroneMap/OpenSfM/
|
||||
GIT_TAG 092
|
||||
GIT_TAG 098
|
||||
#--Update/Patch step----------
|
||||
UPDATE_COMMAND git submodule update --init --recursive
|
||||
#--Configure step-------------
|
||||
|
|
11
index.html
11
index.html
|
@ -1,11 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Refresh" content="0; url=https://opendronemap.org" />
|
||||
<title>OpenDroneMap</title>
|
||||
</head>
|
||||
<body>
|
||||
The project has moved to <a href="https://opendronemap.org">https://opendronemap.org</a>!
|
||||
</body>
|
||||
</html>
|
|
@ -62,6 +62,8 @@ def compute_mask_raster(input_raster, vector_mask, output_raster, blend_distance
|
|||
log.ODM_WARNING("Cannot mask raster, %s does not exist" % vector_mask)
|
||||
return
|
||||
|
||||
log.ODM_INFO("Computing mask raster: %s" % output_raster)
|
||||
|
||||
with rasterio.open(input_raster, 'r') as rast:
|
||||
with fiona.open(vector_mask) as src:
|
||||
burn_features = src
|
||||
|
@ -98,6 +100,30 @@ def compute_mask_raster(input_raster, vector_mask, output_raster, blend_distance
|
|||
|
||||
return output_raster
|
||||
|
||||
def feather_raster(input_raster, output_raster, blend_distance=20):
|
||||
if not os.path.exists(input_raster):
|
||||
log.ODM_WARNING("Cannot feather raster, %s does not exist" % input_raster)
|
||||
return
|
||||
|
||||
log.ODM_INFO("Computing feather raster: %s" % output_raster)
|
||||
|
||||
with rasterio.open(input_raster, 'r') as rast:
|
||||
out_image = rast.read()
|
||||
if blend_distance > 0:
|
||||
if out_image.shape[0] >= 4:
|
||||
alpha_band = out_image[-1]
|
||||
dist_t = ndimage.distance_transform_edt(alpha_band)
|
||||
dist_t[dist_t <= blend_distance] /= blend_distance
|
||||
dist_t[dist_t > blend_distance] = 1
|
||||
np.multiply(alpha_band, dist_t, out=alpha_band, casting="unsafe")
|
||||
else:
|
||||
log.ODM_WARNING("%s does not have an alpha band, cannot blend cutline!" % input_raster)
|
||||
|
||||
with rasterio.open(output_raster, 'w', **rast.profile) as dst:
|
||||
dst.colorinterp = rast.colorinterp
|
||||
dst.write(out_image)
|
||||
|
||||
return output_raster
|
||||
|
||||
def merge(input_ortho_and_ortho_cuts, output_orthophoto, orthophoto_vars={}):
|
||||
"""
|
||||
|
@ -181,9 +207,9 @@ def merge(input_ortho_and_ortho_cuts, output_orthophoto, orthophoto_vars={}):
|
|||
dst_count = first.count
|
||||
dst_shape = (dst_count, dst_rows, dst_cols)
|
||||
|
||||
# First pass, write all rasters naively
|
||||
dstarr = np.zeros(dst_shape, dtype=dtype)
|
||||
|
||||
# First pass, write all rasters naively without blending
|
||||
for src, _ in sources:
|
||||
src_window = tuple(zip(rowcol(
|
||||
src.transform, left, top, op=round, precision=precision
|
||||
|
@ -206,7 +232,32 @@ def merge(input_ortho_and_ortho_cuts, output_orthophoto, orthophoto_vars={}):
|
|||
if np.count_nonzero(dstarr[-1]) == blocksize:
|
||||
break
|
||||
|
||||
# Second pass, write cut rasters
|
||||
# Second pass, write all feathered rasters
|
||||
# blending the edges
|
||||
for src, _ in sources:
|
||||
src_window = tuple(zip(rowcol(
|
||||
src.transform, left, top, op=round, precision=precision
|
||||
), rowcol(
|
||||
src.transform, right, bottom, op=round, precision=precision
|
||||
)))
|
||||
|
||||
temp = np.zeros(dst_shape, dtype=dtype)
|
||||
temp = src.read(
|
||||
out=temp, window=src_window, boundless=True, masked=False
|
||||
)
|
||||
|
||||
where = temp[-1] != 0
|
||||
for b in range(0, num_bands):
|
||||
blended = temp[-1] / 255.0 * temp[b] + (1 - temp[-1] / 255.0) * dstarr[b]
|
||||
np.copyto(dstarr[b], blended, casting='unsafe', where=where)
|
||||
dstarr[-1][where] = 255.0
|
||||
|
||||
# check if dest has any nodata pixels available
|
||||
if np.count_nonzero(dstarr[-1]) == blocksize:
|
||||
break
|
||||
|
||||
# Third pass, write cut rasters
|
||||
# blending the cutlines
|
||||
for _, cut in sources:
|
||||
src_window = tuple(zip(rowcol(
|
||||
cut.transform, left, top, op=round, precision=precision
|
||||
|
|
|
@ -502,6 +502,7 @@ class ToolchainTask(Task):
|
|||
outputs=["odm_orthophoto/odm_orthophoto.tif",
|
||||
"odm_orthophoto/cutline.gpkg",
|
||||
"odm_orthophoto/odm_orthophoto_cut.tif",
|
||||
"odm_orthophoto/odm_orthophoto_feathered.tif",
|
||||
"odm_dem",
|
||||
"odm_georeferencing",
|
||||
"odm_georeferencing_25d"])
|
||||
|
|
|
@ -137,6 +137,13 @@ class ODMOrthoPhotoStage(types.ODM_Stage):
|
|||
|
||||
orthophoto.post_orthophoto_steps(args, bounds_file_path, tree.odm_orthophoto_tif)
|
||||
|
||||
# Generate feathered orthophoto also
|
||||
if args.orthophoto_cutline:
|
||||
orthophoto.feather_raster(tree.odm_orthophoto_tif,
|
||||
os.path.join(tree.odm_orthophoto, "odm_orthophoto_feathered.tif"),
|
||||
blend_distance=20
|
||||
)
|
||||
|
||||
geotiffcreated = True
|
||||
if not geotiffcreated:
|
||||
log.ODM_WARNING('No geo-referenced orthophoto created due '
|
||||
|
|
|
@ -209,7 +209,7 @@ class ODMMergeStage(types.ODM_Stage):
|
|||
|
||||
if not io.file_exists(tree.odm_orthophoto_tif) or self.rerun():
|
||||
all_orthos_and_ortho_cuts = get_all_submodel_paths(tree.submodels_path,
|
||||
os.path.join("odm_orthophoto", "odm_orthophoto.tif"),
|
||||
os.path.join("odm_orthophoto", "odm_orthophoto_feathered.tif"),
|
||||
os.path.join("odm_orthophoto", "odm_orthophoto_cut.tif"),
|
||||
)
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue