66from math import ceil
77import numpy as np
88from PIL import Image
9+ from scipy .ndimage .interpolation import zoom
910from typing import Tuple , Dict , Union , List
1011
1112from wkcuber .metadata import read_metadata_for_layer
@@ -53,6 +54,10 @@ def create_parser():
5354 "--mag" , "-m" , help = "The magnification that should be read" , default = 1
5455 )
5556
57+ parser .add_argument (
58+ "--downsample" , help = "Downsample each tiff image" , default = 1 , type = int
59+ )
60+
5661 tiling_option_group = parser .add_mutually_exclusive_group ()
5762
5863 tiling_option_group .add_argument (
@@ -80,12 +85,12 @@ def create_parser():
8085
8186def wkw_name_and_bbox_to_tiff_name (name : str , slice_index : int ) -> str :
8287 if name is None or name == "" :
83- return f"{ slice_index } .tiff"
88+ return f"{ slice_index :06d } .tiff"
8489 else :
85- return f"{ name } _{ slice_index } .tiff"
90+ return f"{ name } _{ slice_index :06d } .tiff"
8691
8792
88- def wkw_slice_to_image (data_slice : np .ndarray ) -> Image :
93+ def wkw_slice_to_image (data_slice : np .ndarray , downsample : int = 1 ) -> Image :
8994 if data_slice .shape [0 ] == 1 :
9095 # discard greyscale dimension
9196 data_slice = data_slice .squeeze (axis = 0 )
@@ -94,6 +99,18 @@ def wkw_slice_to_image(data_slice: np.ndarray) -> Image:
9499 else :
95100 # swap axis and move the channel axis
96101 data_slice = data_slice .transpose ((2 , 1 , 0 ))
102+
103+ if downsample > 1 :
104+ data_slice = zoom (
105+ data_slice ,
106+ 1 / downsample ,
107+ output = data_slice .dtype ,
108+ order = 1 ,
109+ # this does not mean nearest interpolation,
110+ # it corresponds to how the borders are treated.
111+ mode = "nearest" ,
112+ prefilter = True ,
113+ )
97114 return Image .fromarray (data_slice )
98115
99116
@@ -107,6 +124,7 @@ def export_tiff_slice(
107124 str ,
108125 Union [None , Tuple [int , int ]],
109126 int ,
127+ int ,
110128 ],
111129 ]
112130):
@@ -117,6 +135,7 @@ def export_tiff_slice(
117135 dataset_path ,
118136 tiling_size ,
119137 batch_size ,
138+ downsample ,
120139 ) = export_args
121140 number_of_slices = min (tiff_bbox ["size" ][2 ] - batch_number * batch_size , batch_size )
122141 tiff_bbox ["size" ] = [tiff_bbox ["size" ][0 ], tiff_bbox ["size" ][1 ], number_of_slices ]
@@ -138,7 +157,7 @@ def export_tiff_slice(
138157
139158 tiff_file_path = os .path .join (dest_path , tiff_file_name )
140159
141- image = wkw_slice_to_image (tiff_data [:, :, :, slice_index ])
160+ image = wkw_slice_to_image (tiff_data [:, :, :, slice_index ], downsample )
142161 image .save (tiff_file_path )
143162 logging .info (f"saved slice { slice_name_number } " )
144163
@@ -162,7 +181,8 @@ def export_tiff_slice(
162181 * tiling_size [1 ] : (y_tile_index + 1 )
163182 * tiling_size [1 ],
164183 slice_index ,
165- ]
184+ ],
185+ downsample ,
166186 )
167187
168188 tile_image .save (
@@ -183,6 +203,7 @@ def export_tiff_stack(
183203 name ,
184204 tiling_slice_size ,
185205 batch_size ,
206+ downsample ,
186207 args ,
187208):
188209 os .makedirs (destination_path , exist_ok = True )
@@ -201,6 +222,7 @@ def export_tiff_stack(
201222 dataset_path ,
202223 tiling_slice_size ,
203224 batch_size ,
225+ downsample ,
204226 )
205227 ]
206228 * num_slices ,
@@ -214,7 +236,8 @@ def export_wkw_as_tiff(args):
214236 logging .basicConfig (level = logging .DEBUG )
215237
216238 if args .bbox is None :
217- _ , _ , bbox , _ = read_metadata_for_layer (args .source_path , args .layer_name )
239+ _ , _ , bbox , origin = read_metadata_for_layer (args .source_path , args .layer_name )
240+ bbox = {"topleft" : origin , "size" : bbox }
218241 else :
219242 bbox = [int (s .strip ()) for s in args .bbox .split ("," )]
220243 assert len (bbox ) == 6
@@ -248,6 +271,7 @@ def export_wkw_as_tiff(args):
248271 name = args .name ,
249272 tiling_slice_size = args .tile_size ,
250273 batch_size = args .batch_size ,
274+ downsample = args .downsample ,
251275 args = args ,
252276 )
253277
0 commit comments