提交
This commit is contained in:
+33
-6
@@ -24,6 +24,12 @@ import numpy as np
|
||||
import cv2
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
from PIL import Image as _PIL_Image
|
||||
_HAS_PIL = True
|
||||
except ImportError:
|
||||
_HAS_PIL = False
|
||||
|
||||
PARAMS_FILE = "camera_params.json"
|
||||
|
||||
|
||||
@@ -219,7 +225,7 @@ def _undistort_points(u, v, intr, dist):
|
||||
return x_u, y_u
|
||||
|
||||
|
||||
def software_d2c(depth_img, params):
|
||||
def software_d2c(depth_img, params, splat=True):
|
||||
"""
|
||||
Transform a uint16 depth image (depth camera space) to an aligned uint16
|
||||
depth image in color camera space.
|
||||
@@ -294,7 +300,19 @@ def software_d2c(depth_img, params):
|
||||
z_vals = z_vals[order]
|
||||
|
||||
aligned = np.zeros((color_h, color_w), dtype=np.uint16)
|
||||
aligned[v_vals, u_vals] = z_vals
|
||||
|
||||
if splat:
|
||||
# Splat each depth pixel to a 3×3 neighbourhood to fill sub-pixel gaps
|
||||
# that arise from forward projection. Far→near order is preserved so
|
||||
# the nearest surface always wins when splats overlap.
|
||||
for dv in range(-1, 2):
|
||||
for du in range(-1, 2):
|
||||
us = np.clip(u_vals + du, 0, color_w - 1)
|
||||
vs = np.clip(v_vals + dv, 0, color_h - 1)
|
||||
aligned[vs, us] = z_vals
|
||||
else:
|
||||
aligned[v_vals, u_vals] = z_vals
|
||||
|
||||
return aligned
|
||||
|
||||
|
||||
@@ -315,7 +333,7 @@ def depth_to_colormap(aligned, min_depth_mm=200, max_depth_mm=5000, depth_scale=
|
||||
return colormap
|
||||
|
||||
|
||||
def batch_convert(params, depth_dir_str):
|
||||
def batch_convert(params, depth_dir_str, splat=True):
|
||||
depth_dir = Path(depth_dir_str.strip().strip('"\''))
|
||||
if not depth_dir.exists():
|
||||
print(f" Directory not found: {depth_dir}")
|
||||
@@ -343,12 +361,20 @@ def batch_convert(params, depth_dir_str):
|
||||
print(f" Files : {len(png_files)}")
|
||||
print(f" Depth scale : {depth_scale:.6f} mm/unit")
|
||||
print(f" Output size : {color_w}x{color_h} (color resolution)")
|
||||
print(f" Splat (3×3) : {'on' if splat else 'off'}")
|
||||
print()
|
||||
|
||||
t0 = time.time()
|
||||
ok = 0
|
||||
for i, fpath in enumerate(png_files, 1):
|
||||
depth_img = cv2.imread(str(fpath), cv2.IMREAD_UNCHANGED)
|
||||
depth_img = None
|
||||
if _HAS_PIL:
|
||||
try:
|
||||
depth_img = np.array(_PIL_Image.open(str(fpath)))
|
||||
except Exception:
|
||||
depth_img = None
|
||||
if depth_img is None:
|
||||
depth_img = cv2.imread(str(fpath), cv2.IMREAD_UNCHANGED)
|
||||
if depth_img is None:
|
||||
print(f" [{i:>4}/{len(png_files)}] SKIP (unreadable): {fpath.name}")
|
||||
continue
|
||||
@@ -356,7 +382,7 @@ def batch_convert(params, depth_dir_str):
|
||||
depth_img = depth_img[:, :, 0]
|
||||
depth_img = depth_img.astype(np.uint16)
|
||||
|
||||
aligned = software_d2c(depth_img, params)
|
||||
aligned = software_d2c(depth_img, params, splat=splat)
|
||||
|
||||
# Save aligned uint16 depth
|
||||
cv2.imwrite(str(out_dir / fpath.name), aligned)
|
||||
@@ -405,6 +431,7 @@ def print_params_summary(params):
|
||||
def main():
|
||||
only_params = "--params" in sys.argv
|
||||
only_convert = "--convert" in sys.argv
|
||||
no_splat = "--no-splat" in sys.argv
|
||||
|
||||
params = None
|
||||
|
||||
@@ -448,7 +475,7 @@ def main():
|
||||
print("No directory entered. Exiting.")
|
||||
return
|
||||
|
||||
batch_convert(params, depth_dir)
|
||||
batch_convert(params, depth_dir, splat=not no_splat)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user