Skip to content

Commit

Permalink
Fix file sizes
Browse files Browse the repository at this point in the history
  • Loading branch information
kostrykin committed Mar 21, 2024
1 parent 7fc8c41 commit df87279
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 0 deletions.
Binary file modified tools/concat_channels/test-data/input1_uint8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tools/concat_channels/test-data/input2_float.tiff
Binary file not shown.
Binary file modified tools/concat_channels/test-data/res_preserve_brightness.tiff
Binary file not shown.
Binary file modified tools/concat_channels/test-data/res_preserve_values.tiff
Binary file not shown.
1 change: 1 addition & 0 deletions util/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.*.venv
31 changes: 31 additions & 0 deletions util/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Utility scripts

## Use case: An input TIFF file is too large

Assuming that the TIFF file is an RGB file:

```bash
../../util/shrink_tiff.sh test-data/input2_float.tiff --channel_axis 2
```

The script preserves the brightness and range of values of the image.

## Use case: An output TIFF file is too large

Assuming that the TIFF file is an RGB file:

```bash
../../util/shrink_tiff.sh test-data/res_preserve_values.tiff --channel_axis 2
```

This shrinks the file, but the *input files* also need to be shrinked accordingly.
The output of the above command tells the exact scaling factor that was used.
Denote this factor, and then run:

```bash
../../util/scale_image.sh test-data/input2_float.tiff --channel_axis 2 --scale SCALE
```

where you replace `SCALE` by the denoted factor. This also works for PNG files.

The script preserves the brightness and range of values of the image.
40 changes: 40 additions & 0 deletions util/scale_image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import argparse

import numpy as np
import skimage.transform
import skimage.io


def scale_image(filepath, **kwargs):
im = skimage.io.imread(filepath)
res = skimage.transform.rescale(im, preserve_range=True, **kwargs)

# Preserve the `dtype` so that both brightness and range of values is preserved
if res.dtype != im.dtype:
if np.issubdtype(im.dtype, np.integer):
res = res.round()
res = res.astype(im.dtype)

skimage.io.imsave(filepath, res)
return res


if __name__ == '__main__':

parser = argparse.ArgumentParser()
parser.add_argument('filepath', type=str, help='Image filepath')
parser.add_argument('--scale', type=float, help='Scaling factor', required=True)
parser.add_argument('--anti_aliasing', default=False, action='store_true', help='Use anti-aliasing')
parser.add_argument('--order', type=int, default=0, help='Order of interpolation (0: nearest-neighbor, 1: bi-linear)')
parser.add_argument('--channel_axis', type=int, default=None, help='Given axis will not be rescaled')
args = parser.parse_args()

res = scale_image(
filepath=args.filepath,
scale=args.scale,
anti_aliasing=args.anti_aliasing,
order=args.order,
channel_axis=args.channel_axis,
)

print(f'File {args.filepath} has been scaled to a resolution of {str(res.shape)} pixels.')
19 changes: 19 additions & 0 deletions util/scale_image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

set -e

script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
cwd=$( pwd )
cd "$script_path"

if [ ! -d ".scale_image.venv" ]
then
python -m venv ".scale_image.venv"
source ".scale_image.venv/bin/activate"
pip install "scikit-image>=0.19" "tifffile" "pillow"
else
source ".scale_image.venv/bin/activate"
fi

cd "$cwd"
python "$script_path/scale_image.py" $*
85 changes: 85 additions & 0 deletions util/shrink_tiff.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import argparse
import itertools
import math
import os
import tempfile
import shutil

import humanize
import skimage.transform
import tifffile


DEFAULT_MAX_SIZE = 1024 ** 2


def shrink_tiff(filepath, anti_aliasing, order, channel_axis, max_size=DEFAULT_MAX_SIZE, dry=True):
im_full = tifffile.imread(filepath)

for step in itertools.count(1):
scale = math.sqrt(1 / step)
im = skimage.transform.rescale(
im_full,
scale=scale,
anti_aliasing=anti_aliasing,
order=order,
preserve_range=True,
channel_axis=channel_axis,
)

with tempfile.NamedTemporaryFile(suffix='.tiff', mode='wb') as fp:
tifffile.imwrite(fp.name, im)
byte_size = os.path.getsize(fp.name)

if byte_size <= max_size:
if not dry:
shutil.copy(fp.name, filepath)
return im, scale, byte_size


if __name__ == '__main__':

exec_name = 'shrink_tiff.sh'
long_help = f"""
Example for single-channel binary images and label maps:
{exec_name} filepath.tiff
Example for multi-channel binary images:
{exec_name} filepath.tiff --channel_axis 2
Example for single-channel intensity images:
{exec_name} filepath.tiff --anti_aliasing --order 1
"""

parser = argparse.ArgumentParser()
parser.add_argument('filepath', type=str, help='TIFF filepath')
parser.add_argument('--max_size', type=int, default=DEFAULT_MAX_SIZE, help='Maximum size in bytes')
parser.add_argument('--anti_aliasing', default=False, action='store_true', help='Use anti-aliasing')
parser.add_argument('--order', type=int, default=0, help='Order of interpolation (0: nearest-neighbor, 1: bi-linear)')
parser.add_argument('--channel_axis', type=int, default=None, help='Given axis will not be rescaled')
parser.add_argument('--run', default=False, action='store_true', help='Update the TIFF file (default is dry run)')
args = parser.parse_args()

if not args.run:
print(long_help)

result, scale, result_size = shrink_tiff(
filepath=args.filepath,
max_size=args.max_size,
anti_aliasing=args.anti_aliasing,
order=args.order,
channel_axis=args.channel_axis,
dry=not args.run,
)

result_size_str = humanize.naturalsize(result_size, binary=True)
if args.run:
print(f'File {args.filepath} has been shrinked to {result_size_str} and a resolution of {str(result.shape)} pixels by a factor of {scale}.')
else:
print(f'File {args.filepath} will be shrinked to {result_size_str} and a resolution of {str(result.shape)} pixels by a factor of {scale}.')
print('\nUse the switch "--run" to update the file.')
19 changes: 19 additions & 0 deletions util/shrink_tiff.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

set -e

script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
cwd=$( pwd )
cd "$script_path"

if [ ! -d ".shrink_tiff.venv" ]
then
python -m venv ".shrink_tiff.venv"
source ".shrink_tiff.venv/bin/activate"
pip install "scikit-image>=0.19" "humanize" "tifffile"
else
source ".shrink_tiff.venv/bin/activate"
fi

cd "$cwd"
python "$script_path/shrink_tiff.py" $*

0 comments on commit df87279

Please sign in to comment.