Code Monkey home page Code Monkey logo

apoc's Introduction

Accelerated Pixel and Object Classification (APOC)

License PyPI Python Version tests codecov Development Status DOI

clesperanto meets scikit-learn to classify pixels, objects and edges in images, on a GPU using OpenCL.

TL;DR: Graphical abstract (source)

This repository contains the backend for Python developers. User-friendly plugins for Fiji and napari can be found here:

For training classifiers from pairs of image and label-mask folders, please see this notebook.

Object segmentation

With a given blobs image and a corresponding annotation...

import apoc
from skimage.io import imread, imshow
import pyclesperanto_prototype as cle

image = imread('blobs.tif')
imshow(image)

img.png

manual_annotations = imread('annotations.tif')
imshow(manual_annotations, vmin=0, vmax=3)

img.png

... objects can be segmented (see full example):

# define features: original image, a blurred version and an edge image
features = apoc.PredefinedFeatureSet.medium_quick.value

# Training
clf = apoc.ObjectSegmenter(opencl_filename='object_segmenter.cl', positive_class_identifier=2)
clf.train(features, manual_annotations, image)

# Prediction
segmentation_result = clf.predict(image=image)
cle.imshow(segmentation_result, labels=True)

img.png

Object classification

With a given annotation, blobs can also be classified according to their shape (see full example).

features = 'area,mean_max_distance_to_centroid_ratio,standard_deviation_intensity'

# Create an object classifier
classifier = apoc.ObjectClassifier("object_classifier.cl")

# Training
classifier.train(features, segmentation_result, annotation, image)

# Prediction / determine object classification
classification_result = classifier.predict(segmentation_result, image)

cle.imshow(classification_result, labels=True)

img.png

Object selector

If the desired analysis goal is to select objects of a specific class, the object selector can be used (see full example).

features = 'area,mean_max_distance_to_centroid_ratio,standard_deviation_intensity'

cl_filename = "object_selector.cl"

# Create an object classifier
apoc.erase_classifier(cl_filename) # delete it if it was existing before
classifier = apoc.ObjectSelector(cl_filename, positive_class_identifier=1)

# train it
classifier.train(features, labels, annotation, image)

result = classifier.predict(labels, image)
cle.imshow(result, labels=True)

img.png

Object merger

APOC also comes with a ObjectMerger allowing to train a classifier on label edges for deciding to merge them or to keep them. (See full example)

feature_definition = "touch_portion mean_touch_intensity"

classifier_filename = "label_merger.cl"

apoc.erase_classifier(classifier_filename)
classifier = apoc.ObjectMerger(opencl_filename=classifier_filename)

classifier.train(features=feature_definition,
                 labels=oversegmented,
                 sparse_annotation=annotation,
                 image=background_subtracted) 

merged_labels = classifier.predict(labels=oversegmented, image=background_subtracted)
cle.imshow(merged_labels, labels=True)

img.png

More detailed examples

More example notebooks are available in this folder.

Installation

You can install apoc using conda or pip:

conda install -c conda-forge apoc-backend

OR:

conda install pyopencl
pip install apoc

Mac-users please also install this:

conda install -c conda-forge ocl_icd_wrapper_apple

Linux users please also install this:

conda install -c conda-forge ocl-icd-system

Contributing

Contributions are very welcome. Tests can be run with pytest, please ensure the coverage at least stays the same before you submit a pull request.

License

Distributed under the terms of the BSD-3 license, "apoc" is free and open source software

Issues

If you encounter any problems, please open a thread on image.sc along with a detailed description and tag @haesleinhuepf.

apoc's People

Contributors

haesleinhuepf avatar isuruf avatar jo-mueller avatar kevinyamauchi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

apoc's Issues

'clf.train' error = boolean index did not match indexed array along dimension 0

Hi
Great stuff.

I am running the apoc.pixelclassifer via a pipeline (spyder).

So I do as shown in one of your demos

features = "original_image gaussian_blur=7"
cl_filename = workingdir + foldername + '_classifier.cl'
apoc.erase_classifier(cl_filename)
clf = apoc.PixelClassifier(opencl_filename=cl_filename)
clf.train(features, label1, raw1,continue_training=True)
clf.train(features, label2, raw2,continue_training=True)
clf.train(features, label3, raw3,continue_training=True)

and I get this error when it attempts the second clf.train with label2 and raw2

I checked the images, and they seem fine.

any comment or advice will be great

thanks

------------------------------------------
  File "C:\Users\piango\AppData\Local\Temp/ipykernel_27864/2139741856.py", line 1, in <module>
    runfile('D:/OneDrive/Postdoc/GB_Lab/Analysis/quantification/organoid-segmentation-3D/predict_mesh_multipleobjects.py', wdir='D:/OneDrive/Postdoc/GB_Lab/Analysis/quantification/organoid-segmentation-3D')

  File "C:\Users\piango\anaconda3\envs\apoc\lib\site-packages\debugpy\_vendored\pydevd\_pydev_bundle\pydev_umd.py", line 167, in runfile
    execfile(filename, namespace)

  File "C:\Users\piango\anaconda3\envs\apoc\lib\site-packages\debugpy\_vendored\pydevd\_pydev_imps\_pydev_execfile.py", line 25, in execfile
    exec(compile(contents + "\n", file, 'exec'), glob, loc)

  File "D:/OneDrive/Postdoc/GB_Lab/Analysis/quantification/organoid-segmentation-3D/predict_mesh_multipleobjects.py", line 54, in <module>
    clf.train(features,

  File "C:\Users\piango\anaconda3\envs\apoc\lib\site-packages\apoc\_pixel_classifier.py", line 63, in train
    X, y = self._to_np(features, ground_truth)

  File "C:\Users\piango\anaconda3\envs\apoc\lib\site-packages\apoc\_pixel_classifier.py", line 206, in _to_np
    X = X[mask]

IndexError: boolean index did not match indexed array along dimension 0; dimension is 1221025 but corresponding boolean dimension is 1660594
--------------------------------------

Question about the ObjectClassifer._select_features() docstring

Hello! Quick question about the ObjectClassifer._select_features() docstring.

def _select_features(self, all_features, features_to_select, labels, ground_truth=None):
"""Provided with all easy-to-determine features, select requested features and calculate the more complicated
features.
Parameters
----------
all_features: dict[vector]
features_to_select: list[str]
labels: ndimage
ground_truth: ndimage, optional
Returns
-------
result:list[vector]
list of vectors corresponding to the requested features. The vectors are shaped (n+1) for n labels. The
first element corresponds to background.
ground_truth: ndimage
selected elements of provided ground truth where it's not 0
"""

It says that the returned result vectors (i.e., table columns) are length n+1 for n labels. When I use the debugger in test_object_classification(), it looks like the result vectors have length 2. Since there are two label values (1 and 2 in labels), I would have expected them to be length 3. However, I can see why length 2 makes more sense. Which is correct? (working on the TableRowClassifer - just making sure I understand)

Thanks!

SimpleITK-based object classifier?

To give more options for object classification while maintaining the installability of apoc, it might make sense to setup a second ObjectClassfier, that uses internally the regionprops from SimpleITK.

We could then classify objects accorind to their

  • maximum
  • mean
  • median
  • minimum
  • sigma
  • sum
  • variance
  • bbox
  • centroid_0
  • elongation
  • feret_diameter
  • flatness
  • roundness
  • equivalent_ellipsoid_diameter_0
  • equivalent_ellipsoid_diameter_1
  • equivalent_spherical_perimeter
  • equivalent_spherical_radius
  • number_of_pixels
  • number_of_pixels_on_border
  • perimeter
  • perimeter_on_border
  • perimeter_on_border_ratio
  • principal_axes0
  • principal_axes1
  • principal_axes2
  • principal_axes3
  • principal_moments0
  • principal_moments1

We could alternatively build this in optionally in the existing object classifier. The user-interface in napari may need a major redesign for this.

See also:
https://github.com/haesleinhuepf/napari-simpleitk-image-processing/blob/main/src/napari_simpleitk_image_processing/_simpleitk_image_processing.py#L789

Documentation?

Hello,
I am an APOC newbie and was wondering if there was a formal API document?
Specifically, what is my total choice (description) for selecting features?
Can I input, train, and test on RGB or BGR color images?

segmenter = apoc.ObjectSegmenter(opencl_filename=cl_filename, positive_class_identifier=5) features = apoc.PredefinedFeatureSet.object_size_1_to_5_px.value apoc.train_classifier_from_image_folders( segmenter, features, image = image_folder, ground_truth = masks_folder)
thx e.-

auto-context

Would be cool to have auto-context classifiers

Remove 'return_numpy' from TableRowClassifier API

I'd like to get rid of the return_numpy parameter here, because:

Instead of this:

result_numpy = table_row_classifier.predict(table, return_numpy=True)

A user could run this:

result_numpy = np.asarray( table_row_classifier.predict(table) )

The second appears more standard to me and it simplifies the API. The other classifers also don't have this parameter.

@kevinyamauchi what do you think about this? Would it be ok to remove it immediately or shall we use some deprecation mechanism? I guess you and me might be the only users as this is relatively young functionality?

pytest-fy tests

It might be worth converting the tests to pytest. Then we could take advantage of fixtures such as temporary directories for writing the .cl files so that we don't get conflicts between tests. Also, it would allow for test parameterization.

Train / predict from tables

It should be pretty straight forward to rip out some parts of the ObjectClassifier and make a new classifier that does not use images, but table as input.

That would also make this easier to implement:

Feature request: Classifier uncertainty

This idea is very much borrowed from Ilastik, which shows an uncertainty overlay on top of the output classification. I did a quick search, and it seems like uncertainty for random forest classifiers is simply the difference of the two highest probabilities (see also here).

So for a background/foreground segmentation, this would mean the following.

If - for a single pixel - 90 trees vote for class 1 and 10 trees vote for class 2, the uncertainty would be 1 - (0.9 - 0.1) = 0.2

LMKWYT :)

Feature request: Print classifier info

It would be nice if there were a function that could show some info about the classifier, e.g. the expexted dimensionality of input data, the used features, etc.

File not found error if folder path does not end with `\\`

Hi @haesleinhuepf

Just a minor "bug": I just discovered that the training from folder throws an error if the paths are passed as path/to/image rather than path/to/image/. There is probably a folder + filename somewhere in the code when the data is loaded, but I couldn't find it straight away. If you point me to the right place I'd be happy to send a PR - putting a os.path.join() there should probably do it.

Remove dual feature specification in TableRowClassifier

Since #17 we have we have two places where feature specification is stored in the TableRowClassifier:

  • self.feature_specification is a string separated list of features
  • self._ordered_feature_names is a list with the same content, but split by spaces

All other classifiers have feature_specification, so we may potentially reduce the code to only this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.