'Batch processing of Tiff files using skimage (Python)

I am looking to; open, process and save multiple TIFFs in Python.

I have the following code to open, process and save 1 (one) TIFF, but I have trouble with multiple files:

import skimage.io
import skimage.viewer
import skimage                 
import skimage.io    
         
# Read 1 image.TIF:
image = skimage.io.imread(fname=path)
image[2,1]= 1.0

# Process the file (make binary)
gray_image = skimage.color.rgb2gray(image)

# Blur the image to denoise (larger sigma = more noise removed)
blurred_image = skimage.filters.gaussian(gray_image, sigma=5)

# Adding threshold, t:
t = 0.8
binary_mask = blurred_image < t

# Save the file to another location:
skimage.io.imsave(fname=path, arr = binary_mask)

Any help is appreciated!



Solution 1:[1]

Here's a multiprocessing approach that may help:

import skimage
from concurrent.futures import ProcessPoolExecutor
from glob import glob
import os.path

source_dir = '<your source directory>'
target_dir = '<your target directory>'
filetype = '*.tif'

def process(path):
    image = skimage.io.imread(fname=path)
    image[2,1] = 1.0
    gray_image = skimage.color.rgb2gray(image)
    blurred_image = skimage.filters.gaussian(gray_image, sigma=5)
    outpath = os.path.join(target_dir, os.path.basename(path))
    arr = blurred_image < 0.8
    skimage.io.imsave(fname=outpath, arr=arr)

def main():
    with ProcessPoolExecutor() as executor:
        filelist = glob(os.path.join(source_dir, filetype))
        executor.map(process, filelist)

if __name__ == '__main__':
    main()

Use glob to identify all the files matching the *.tif pattern then utilise the ProcessPoolExecutor's map function to process each file in its own process. As the processing is mainly CPU intensive, multiprocessing is likely to be the best fit for this

Solution 2:[2]

Is it necessary that this be parallelized? It's not a huge bit of processing that you are performing. If you don't need parallel processing you can just run a for loop on your images

import skimage.io
import skimage.viewer
import skimage                 
import skimage.io
import os
import glob

# set up an in and out directory
in_dir = 'directory\with\images'
out_ir = 'directory\for\procecessed\images'

# make a list of all of the raw image files
os.chdir(in_dir)
filelist = glob.glob('*.png') # change to whatever file pattern you need here


for file_iter in filelist:
        
    os.chdir(in_dir)
    image = skimage.io.imread(fname=file_iter)
    image[2,1]= 1.0

    # Process the file (make binary)
    gray_image = skimage.color.rgb2gray(image)

    # Blur the image to denoise (larger sigma = more noise removed)
    blurred_image = skimage.filters.gaussian(gray_image, sigma=5)

    # Adding threshold, t:
    t = 0.8
    binary_mask = blurred_image < t

    # Save the file to another location:
    out_filename = file_iter[:-4] + 'processed.png' # make new filename based on old filename
    os.chdir(out_dir)
    skimage.io.imsave(fname=out_filename, arr = binary_mask)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Albert Winestein
Solution 2 tdaugird