def main(args=sys.argv[1:]): args = parse_args(args) if args.output is None: get_tiff_dims(input_glob_or_list=args.input, print_out=True) else: if args.x_pixels or args.y_pixels or args.z_pixels: x_dim, y_dim, z_dim = get_tiff_dims(args.input, print_out=False) crop_xyz = parse_crop_dims_str(args.crop_x, args.crop_y, args.crop_z) crop_x, crop_y, crop_z = validate_tiff_crop_dims(x_dim, y_dim, z_dim, *crop_xyz) if args.x_pixels: args.scale_x = float(args.x_pixels) / (crop_x[1] - crop_x[0] + 1) if args.y_pixels: args.scale_y = float(args.y_pixels) / (crop_y[1] - crop_y[0] + 1) if args.z_pixels: args.scale_z = float(args.z_pixels) / (crop_z[1] - crop_z[0] + 1) transform_tiff(input_glob_or_list=args.input, output_path=args.output, crop_x=args.crop_x, crop_y=args.crop_y, crop_z=args.crop_z, flip_x=args.flip_x, flip_y=args.flip_y, flip_z=args.flip_z, scale_x=args.scale_x, scale_y=args.scale_y, scale_z=args.scale_z, split_output=args.split_output, start_num=args.start_num, num_digits=args.num_digits)
def main(args=sys.argv[1:]): args = parse_args(args) x_dim, y_dim, z_dim = get_tiff_dims(args.reference_tiff) with open(args.input) as fd: full_coords = json.load(fd) coords_by_z = [[] for __ in range(z_dim)] # Rounds z to nearest integer for x, y, z in full_coords: coords_by_z[np.intc(z) - 1].append([np.intc(x), np.intc(y)]) # Create output directory if it does not yet exist if not os.path.exists(args.output): print("Creating directory at {}.".format(args.output)) os.mkdir(args.output) with mp.Pool() as pool: results = [] for z in range(z_dim): filename = args.output + "img_" + str(z).zfill( int(np.floor(np.log10(z_dim)) + 1)) + ".tiff" results.append( pool.apply_async(write_tiff, (z, coords_by_z, filename, x_dim, y_dim))) [result.get() for result in tqdm.tqdm(results)]
def main(args=sys.argv[1:]): args = parse_args(args) if args.output is None: num_tuples = get_num_coords(input_path=args.input) print("JSON file at {} has {} coordinate tuples".format( args.input, num_tuples)) else: if args.x_pixels or args.y_pixels or args.z_pixels: x_dim, y_dim, z_dim = get_tiff_dims(args.original_tiff, print_out=False) crop_xyz = parse_crop_dims_str(args.crop_x, args.crop_y, args.crop_z) crop_x, crop_y, crop_z = validate_tiff_crop_dims( x_dim, y_dim, z_dim, *crop_xyz) if args.x_pixels: args.scale_x = float( args.x_pixels) / (crop_x[1] - crop_x[0] + 1) if args.y_pixels: args.scale_y = float( args.y_pixels) / (crop_y[1] - crop_y[0] + 1) if args.z_pixels: args.scale_z = float( args.z_pixels) / (crop_z[1] - crop_z[0] + 1) transform_json(input_path=args.input, output_path=args.output, crop_x=args.crop_x, crop_y=args.crop_y, crop_z=args.crop_z, flip_x=args.flip_x, flip_y=args.flip_y, flip_z=args.flip_z, scale_x=args.scale_x, scale_y=args.scale_y, scale_z=args.scale_z, original_tiff=args.original_tiff)
def transform_tiff(input_glob_or_list: Union[str, List[str]], output_path: str, crop_x: Union[str, List[int], Tuple[int, int]] = None, crop_y: Union[str, List[int], Tuple[int, int]] = None, crop_z: Union[str, List[int], Tuple[int, int]] = None, flip_x: bool = False, flip_y: bool = False, flip_z: bool = False, scale_x: float = 1, scale_y: float = 1, scale_z: float = 1, split_output: bool = False, start_num: int = 0, num_digits: int = None) -> None: """Main function for cropping tiffs Note: progress bars not particularly accurate for inputs with very large tiff files due to IO-limited multiprocessing and how the jobs are queued Parameters ---------- input_glob_or_list : Union[str, List[str]] String containing input glob or list of file paths to individual tiffs output_path : str Output file path, should either be a directory or tiff file, depending on the value of split_output crop_x : Union[str, List[int], Tuple[int, int]] String in format "[x_min,x_max]" or Sequence of ints in format [x_min, x_max] specifying the minimum and maximum x-values (inclusive) to include in the outputted cropped tiff crop_y : Union[str, List[int], Tuple[int, int]] String in format "[y_min,y_max]" or Sequence of ints in format [y_min, y_max] specifying the minimum and maximum y-values (inclusive) to include in the outputted cropped tiff crop_z : Union[str, List[int], Tuple[int, int]] String in format "[z_min,z_max]" or Sequence of ints in format [z_min, z_max] specifying the minimum and maximum x-values (inclusive) to include in the outputted cropped tiff flip_x : bool Specify whether or not the output image should have its x-axis reversed after cropping flip_y : bool Specify whether or not the output image should have its y-axis reversed after cropping flip_z : bool Specify whether or not the output image should have its z-axis reversed after cropping scale_x : float Specify the scaling factor along the x-axis after cropping scale_y : float Specify the scaling factor along the y-axis after cropping scale_z : float Specify the scaling factor along the z-axis after cropping split_output : bool True if output should be a directory of 2D tiffs, False if output should be single multi-page tiff file start_num : int Number from which to start outputting in output TIFF stack num_digits : int Number of digits in output TIFF stack file names Returns ------- None """ tiff_paths = glob_to_list(input_glob_or_list) # Ensures TIFF stack is outputted into a directory if split_output: if platform.system() == "Windows": if output_path[-1] != "\\": output_path += "\\" elif platform.system() == "Linux" or platform.system == "Darwin": if output_path[-1] != "/": output_path += "/" x_dim, y_dim, z_dim = get_tiff_dims(input_glob_or_list) crop_x, crop_y, crop_z = parse_crop_dims_str(crop_x, crop_y, crop_z) crop_x, crop_y, crop_z = validate_tiff_crop_dims(x_dim, y_dim, z_dim, crop_x, crop_y, crop_z) if num_digits is None: num_digits = int(np.floor(np.log10(crop_z[1] - crop_z[0] + 1)) + 1) if len(tiff_paths) == 1: tiff_ndarray_reshape = reshape_single_tiff(tiff_paths[0]) transform_single_tiff(tiff_ndarray_reshape, output_filepath=output_path, output_tiff_stack=split_output, crop_x=crop_x, crop_y=crop_y, crop_z=crop_z, flip_x=flip_x, flip_y=flip_y, flip_z=flip_z, scale_x=scale_x, scale_y=scale_y, scale_z=scale_z, start_num=start_num, num_digits=num_digits) else: transform_multi_tiff(tiff_paths, output_filepath=output_path, output_tiff_stack=split_output, crop_x=crop_x, crop_y=crop_y, crop_z=crop_z, flip_x=flip_x, flip_y=flip_y, flip_z=flip_z, scale_x=scale_x, scale_y=scale_y, scale_z=scale_z, start_num=start_num, num_digits=num_digits)
def transform_json(input_path: str, output_path: str, crop_x: Union[str, List[int], Tuple[int, int]] = None, crop_y: Union[str, List[int], Tuple[int, int]] = None, crop_z: Union[str, List[int], Tuple[int, int]] = None, flip_x: bool = False, flip_y: bool = False, flip_z: bool = False, scale_x: float = 1, scale_y: float = 1, scale_z: float = 1, original_tiff: str = None) -> None: """Writes json file of cropped coordinates given an input json and cropping specifications Assumes json field with coordinates is only content in input json file, maps old coordinates to new coordinates assuming that the lower bounds on each of crop_x, crop_y, and crop_z will be (0, 0, 0) Also assumes coordinates are 3D Order of operations: cropping > scaling > flipping Parameters ---------- input_path : str Path to input json file with uncropped coordinates output_path : str Path to output the resulting json file crop_x : Union[str, List[int], Tuple[int, int]] String in format "[x_min,x_max]" or Sequence of ints in format [x_min, x_max] specifying the minimum and maximum x-values (inclusive) to include in the resulting coordinates crop_y : Union[str, List[int], Tuple[int, int]] String in format "[y_min,y_max]" or Sequence of ints in format [y_min, y_max] specifying the minimum and maximum y-values (inclusive) to include in the resulting coordinates crop_z : Union[str, List[int], Tuple[int, int]] String in format "[z_min,z_max]" or Sequence of ints in format [z_min, z_max] specifying the minimum and maximum x-values (inclusive) to include in the resulting coordinates flip_x : bool Specify whether or not the output coordinates should be reversed along the x-axis after cropping flip_y : bool Specify whether or not the output coordinates should be reversed along the y-axis after cropping flip_z : bool Specify whether or not the output coordinates should be reversed along the z-axis after cropping scale_x : float Specify the scaling factor for x-coordinates after cropping scale_y : float Specify the scaling factor for y-coordinates after cropping scale_z : float Specify the scaling factor for z-coordinates after cropping original_tiff : str UNIX-style glob expression to original TIFF stack Required for flipping Returns ------- None """ crop_x, crop_y, crop_z = parse_crop_dims_str(crop_x=crop_x, crop_y=crop_y, crop_z=crop_z) if (crop_x[1] == float("Inf") and flip_x) or \ (crop_y[1] == float("Inf") and flip_y) or \ (crop_z[1] == float("Inf") and flip_z): x_dim, y_dim, z_dim = get_tiff_dims(original_tiff) if flip_x: crop_x = 1, x_dim if flip_y: crop_y = 1, y_dim if flip_z: crop_z = 1, z_dim with open(input_path) as fd: full_coords = json.load(fd) print("Reading in {} coordinate tuples from {}".format( len(full_coords), input_path)) cropped_coords = [] for x, y, z in full_coords: if crop_x[0] <= x <= crop_x[1] and crop_y[0] <= y <= crop_y[ 1] and crop_z[0] <= z <= crop_z[1]: # Cropping if crop_x[0] != -float("Inf"): cropped_x = x - crop_x[0] else: cropped_x = x if crop_y[0] != -float("Inf"): cropped_y = y - crop_y[0] else: cropped_y = y if crop_z[0] != -float("Inf"): cropped_z = z - crop_z[0] else: cropped_z = z # Scaling cropped_x = scale_x * cropped_x cropped_y = scale_y * cropped_y cropped_z = scale_z * cropped_z # Flipping if flip_x or flip_y or flip_z: if original_tiff is None: raise ValueError else: x_dim, y_dim, z_dim = get_tiff_dims(original_tiff) if flip_x: cropped_x = x_dim - cropped_x + 1 if flip_y: cropped_y = y_dim - cropped_y + 1 if flip_z: cropped_z = z_dim - cropped_z + 1 cropped_coord = [cropped_x, cropped_y, cropped_z] cropped_coords.append(cropped_coord) print("Writing {} coordinate tuples to {}".format(len(cropped_coords), output_path)) pretty_print_json_coords(cropped_coords, output_path)