1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
#!/usr/bin/env python3
import numpy as np
import cv2
import argparse
import os
def compute_sdf(img, scale_factor):
# Convert to binary image if not already
_, binary = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# Compute distance transform for both foreground and background
dist_transform_fg = cv2.distanceTransform(binary, cv2.DIST_L2, 5)
dist_transform_bg = cv2.distanceTransform(255 - binary, cv2.DIST_L2, 5)
# Combine the distance fields and scale by factor
sdf = (dist_transform_fg - dist_transform_bg) / scale_factor
# Clamp values to [0, 255] range
sdf = np.clip(sdf + 128, 0, 255)
return sdf.astype(np.uint8)
def main():
parser = argparse.ArgumentParser(description='Generate SDF from black and white image')
parser.add_argument('input_image', help='Path to input image')
parser.add_argument('--scale', type=float, default=1.0,
help='Scale factor for distance (in texels)')
args = parser.parse_args()
# Get input and output paths
input_path = args.input_image
filename, ext = os.path.splitext(input_path)
output_path = f"{filename}-sdf{ext}"
# Read input image
img = cv2.imread(input_path, cv2.IMREAD_GRAYSCALE)
if img is None:
print(f"Error: Could not read image {input_path}")
return
# Compute SDF with scale factor
sdf = compute_sdf(img, args.scale)
# Save result
cv2.imwrite(output_path, sdf)
print(f"SDF generated and saved to {output_path}")
if __name__ == "__main__":
main()
|