Skip to content

Commit 30d6f91

Browse files
author
Donglai Wei
committed
mitoEM
1 parent fbabdcf commit 30d6f91

File tree

4 files changed

+254
-191
lines changed

4 files changed

+254
-191
lines changed

connectomics/data/dataset/dataset_volume_cached.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,15 @@ def crop_volume(volume: np.ndarray, size: Tuple[int, ...], start: Tuple[int, ...
8080
else:
8181
full_pad_width = pad_width
8282

83-
# Use reflect padding to match the volume's edge values
84-
cropped = np.pad(cropped, full_pad_width, mode="reflect")
83+
# Check if cropped array is empty or has zero-sized dimensions
84+
# Reflect padding cannot work on empty arrays, so fall back to constant padding
85+
is_empty = cropped.size == 0 or any(s == 0 for s in cropped.shape)
86+
if is_empty:
87+
# Use constant padding for empty arrays (reflect padding requires at least one element)
88+
cropped = np.pad(cropped, full_pad_width, mode="constant", constant_values=0)
89+
else:
90+
# Use reflect padding to match the volume's edge values
91+
cropped = np.pad(cropped, full_pad_width, mode="reflect")
8592

8693
# Final safety check: ensure output has exactly the requested size
8794
# This handles any edge cases where padding calculation might be off
@@ -100,7 +107,16 @@ def crop_volume(volume: np.ndarray, size: Tuple[int, ...], start: Tuple[int, ...
100107
full_pad_width = [(0, 0)] + pad_needed
101108
else:
102109
full_pad_width = pad_needed
103-
cropped = np.pad(cropped, full_pad_width, mode="reflect")
110+
111+
# Check if cropped array is empty or has zero-sized dimensions
112+
# Reflect padding cannot work on empty arrays, so fall back to constant padding
113+
is_empty = cropped.size == 0 or any(s == 0 for s in cropped.shape)
114+
if is_empty:
115+
# Use constant padding for empty arrays (reflect padding requires at least one element)
116+
cropped = np.pad(cropped, full_pad_width, mode="constant", constant_values=0)
117+
else:
118+
# Use reflect padding to match the volume's edge values
119+
cropped = np.pad(cropped, full_pad_width, mode="reflect")
104120

105121
# If still wrong (shouldn't happen), trim excess
106122
if has_channel:

scripts/convert_tiff_to_h5.py

Lines changed: 0 additions & 51 deletions
This file was deleted.

scripts/images_to_h5.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Convert a directory of image files (TIFF, PNG, JPG, etc.) into a single 3D HDF5 volume.
4+
5+
Supports various image formats:
6+
- TIFF (single or multi-page)
7+
- PNG
8+
- JPEG/JPG
9+
- BMP
10+
- And any other formats supported by the I/O backend
11+
12+
Usage:
13+
python scripts/images_to_h5.py <input_pattern> <output_file.h5> [dataset_key]
14+
15+
Examples:
16+
# TIFF files (default dataset key: 'main')
17+
python scripts/images_to_h5.py "datasets/bouton-lv/LV_EM/*.tiff" datasets/bouton-lv/LV_EM.h5
18+
19+
# PNG files (default dataset key: 'main')
20+
python scripts/images_to_h5.py "/path/to/images/*.png" output.h5
21+
22+
# Custom dataset key
23+
python scripts/images_to_h5.py "/path/to/labels/*.png" labels.h5 labels
24+
25+
Note: Use quotes around the input pattern to prevent shell expansion.
26+
"""
27+
28+
import sys
29+
import os
30+
from pathlib import Path
31+
from connectomics.data.io import read_volume, write_hdf5
32+
33+
34+
def main():
35+
"""Main conversion function."""
36+
if len(sys.argv) < 3:
37+
print("Usage: python scripts/images_to_h5.py <input_pattern> <output_file.h5> [dataset_key]")
38+
print("")
39+
print("Examples:")
40+
print(' python scripts/images_to_h5.py "datasets/images/*.tiff" output.h5')
41+
print(' python scripts/images_to_h5.py "/path/to/images/*.png" output.h5')
42+
print(' python scripts/images_to_h5.py "/path/to/labels/*.png" labels.h5 labels')
43+
print("")
44+
print("Note: Use quotes around the input pattern to prevent shell expansion.")
45+
sys.exit(1)
46+
47+
input_pattern = sys.argv[1]
48+
output_file = sys.argv[2]
49+
dataset_key = sys.argv[3] if len(sys.argv) > 3 else "main"
50+
51+
# Ensure output directory exists
52+
output_dir = os.path.dirname(output_file)
53+
if output_dir and not os.path.exists(output_dir):
54+
print(f"Creating output directory: {output_dir}")
55+
os.makedirs(output_dir, exist_ok=True)
56+
57+
# Detect file format from pattern
58+
pattern_lower = input_pattern.lower()
59+
if any(ext in pattern_lower for ext in ['.tif', '.tiff']):
60+
format_name = "TIFF"
61+
elif '.png' in pattern_lower:
62+
format_name = "PNG"
63+
elif any(ext in pattern_lower for ext in ['.jpg', '.jpeg']):
64+
format_name = "JPEG"
65+
else:
66+
format_name = "image"
67+
68+
print(f"Reading {format_name} files matching: {input_pattern}")
69+
print("This may take a while for large volumes...")
70+
71+
# Read all image files as a 3D volume
72+
try:
73+
volume = read_volume(input_pattern)
74+
except Exception as e:
75+
print(f"Error reading images: {e}")
76+
print("\nTips:")
77+
print(" - Check that the file pattern is correct")
78+
print(" - Ensure all images have the same dimensions")
79+
print(" - Verify the image files are readable")
80+
sys.exit(1)
81+
82+
print(f"\n{'='*60}")
83+
print(f"Volume Information:")
84+
print(f"{'='*60}")
85+
print(f" Shape: {volume.shape}")
86+
print(f" Data type: {volume.dtype}")
87+
print(f" Size: {volume.nbytes / (1024**3):.2f} GB")
88+
print(f" Min value: {volume.min()}")
89+
print(f" Max value: {volume.max()}")
90+
print(f"{'='*60}")
91+
92+
print(f"\nSaving to: {output_file}")
93+
print(f"Dataset key: '{dataset_key}'")
94+
95+
# Save as HDF5
96+
try:
97+
write_hdf5(output_file, volume, dataset=dataset_key)
98+
print(f"\n✓ Successfully saved 3D volume to {output_file}")
99+
print(f" You can access it with h5py using: f['{dataset_key}']")
100+
except Exception as e:
101+
print(f"\n✗ Error writing HDF5 file: {e}")
102+
sys.exit(1)
103+
104+
105+
if __name__ == "__main__":
106+
main()

0 commit comments

Comments
 (0)