Forum

Author Topic: [Updated Solution] Resize bounding box/region to sparse point cloud  (Read 1531 times)

freespace

  • Newbie
  • *
  • Posts: 3
    • View Profile
Hi,

I needed to resize my bounding box/region to sparse point cloud extent and tried to use the solution Alexy posted in

https://www.agisoft.com/forum/index.php?topic=7543.0

This didn't quite work for me, possibly due to changes to the API since then. With a bit of experimentation I got a modified version of Alexy's code to work for my georeferenced dataset and I am positing the solution in the hopes I can help others in the future.

Code: [Select]
# Tested on Metashape 1.7.5 API

# these store the min/max crs coordinates of point cloud points
min_coords = mts.Vector([1e100, 1e100, 1e100])
max_coords = -min_coords
T = chunk.transform.matrix

for point in chunk.point_cloud.points:
    if not point.valid:
        continue
       
    # project into CRS b/c min/max of a collection of point in one projection is not the same
    # as the same points in another projection when rotation and axis inversion is involved
    p = T * point.coord
    p.size =3
    p = chunk.crs.project(p)
    for idx in range(3):
        min_coords[idx] = min(min_coords[idx], p[idx])
        max_coords[idx] = max(max_coords[idx], p[idx])       

def crs_to_global(v):
    return T.inv().mulp(chunk.crs.unproject(v))

new_center = crs_to_global((max_coords + min_coords)/2)

# this assumes that crs easting maps to X and northing maps to Y
v0 = crs_to_global(min_coords)
v1 = crs_to_global(mts.Vector([max_coords[0], min_coords[1], min_coords[2]]))
v2 = crs_to_global(mts.Vector([min_coords[0], max_coords[1], min_coords[2]]))
v3 = crs_to_global(mts.Vector([min_coords[0], min_coords[1], max_coords[2]]))

# x1.05 for buffer
new_size = mts.Vector([(v1 - v0).norm(),
                                         (v2 - v0).norm(),
                                         (v3 - v0).norm()]) * 1.05

v_t = T*mts.Vector([0, 0, 0, 1])
print('v_T', v_t)
v_t.size = 3
R = chunk.crs.localframe(v_t) * T
new_rot = R.rotation().t()

region = chunk.region
region.center = new_center
region.size = new_size
region.rot = new_rot

The main difference is in the size computation which in the original code gave me extremely small volumes.

Sincerely,
Steve
« Last Edit: December 26, 2021, 05:55:23 AM by freespace »