Created
September 2, 2019 01:49
-
-
Save VolkerH/06cb11218a2c4adea63e000adc8f9fce to your computer and use it in GitHub Desktop.
Proof-of-concept class to run ilastik pixel classifier in headless mode from python (intermediate files are generated as temp files)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# tools to call an external ilastik classifier and run in headless mode | |
# see | |
# https://www.ilastik.org/documentation/basics/headless.html | |
# | |
# Volker Hilsenstein, Monash Micro Imaging 2019 | |
# License: BSD-3 | |
import subprocess | |
from abc import ABC, abstractmethod | |
from typing import List | |
import pathlib | |
import warnings | |
import tempfile | |
import h5py | |
import numpy as np | |
def ilastik_h5_asarray(h5file: str): | |
with h5py.File(h5file, mode="r") as f: | |
tmp = f["exported_data"][:] | |
return tmp | |
class ilastikClassifier(ABC): | |
def __init__(self, executable: str, project: str): | |
"""initialize an ilastik classifier with the path to ilastik and the project | |
Arguments: | |
executable {str} -- Path to ilastik executable | |
project {str} -- Path to ilastik projcet file | |
""" | |
self.ilastik_exe = executable | |
self.project = project | |
if not pathlib.Path(self.project).is_file(): | |
warnings.warn(f"project file {self.project} does not exist") | |
if not pathlib.Path(self.ilastik_exe).is_file(): | |
warnings.warn(f"ilastik executable path incorrect: {self.ilastik_exe} does not exist") | |
super().__init__() | |
@abstractmethod | |
def run(self, files: List[str], outfile_pattern: str=''): | |
pass | |
class ilastikPixelClassifier(ilastikClassifier): | |
def run(self, files: List[str], outfile_pattern: str=''): | |
"""run the ilastik classifier on image file | |
Arguments: | |
file {str} -- input file path | |
Keyword Arguments: | |
outfile {str} -- output file name (default: {''}) | |
""" | |
args = [self.ilastik_exe, "--headless", "--project", self.project] | |
if outfile_pattern: | |
args += ['--output_filename_format', outfile_pattern] | |
args += files | |
print(args) | |
return subprocess.call(args) | |
def get_predictions(self, files: List[str]): | |
"""returns a generator for predictions for files as numpy arrays. Ilastik output is directed to tmp files and deleted afterwards. | |
Arguments: | |
files {List[str]} -- list of input files | |
""" | |
with tempfile.TemporaryDirectory() as temp_dir: | |
# run ilastik on all files | |
print("temporary directory ******************** " + temp_dir) | |
self.run(sorted(files), outfile_pattern=temp_dir+'/{nickname}_pred.h5') | |
generated_files = list(pathlib.Path(temp_dir).rglob("*_pred.h5")) | |
generated_files = list(map(str, generated_files)) | |
generated_files = sorted(generated_files) | |
for gfile in generated_files: | |
yield {"file" : gfile, "pred": ilastik_h5_asarray(gfile)} | |
def testPixelClassifier(): | |
ilastikexe = "c:/Program Files/ilastik-1.3.2post1/ilastik.exe" | |
proj = "C:/Users/Volker/Data/Natasha/podo.ilp" | |
samplefiles = [r'c:\Users\Volker\Dropbox\Github\podocytes\CroppedPodos\1644 Cropped\1644 Glom 2.tif', | |
r'c:\Users\Volker\Dropbox\Github\podocytes\CroppedPodos\1644 Cropped\1644 Glom 1.tif'] | |
irunner = ilastikPixelClassifier(ilastikexe , proj) | |
#print(irunner.run([samplefiles], "C:/Users/Volker/Data/Natasha/{nickname}_pred.h5")) | |
preds = irunner.get_predictions(samplefiles) | |
import time | |
for p in preds: | |
print(p.shape) | |
#testPixelClassifier() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Beware, there may still be a bug in the file sorting affecting the association of input files with output predictions in some cases. Beware !