Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Imglib roi io support #5

Draft
wants to merge 26 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c3a596e
Added implementation for adding segmentation source while fetching se…
Dec 18, 2019
d3283f3
Get method for getting segmentation source from each label of a region
Dec 25, 2019
ceafba7
TEMPORARY SNAPSHOT dependency imglib2-roi-0.10.3-SNAPSHOT
tpietzsch Jun 24, 2020
3428e31
Replace use of deprecated LabelingMapping.SerialisationAccess
tpietzsch Jun 24, 2020
2a9af7a
TEMPORARY debug output
tpietzsch Jun 24, 2020
cbd14ea
Apparent fix for SCIFIO throwing error messages
tpietzsch Jun 24, 2020
7ae161a
TEMPORARY debug output
tpietzsch Jun 24, 2020
f07476b
XmlIoLabelingPlus: write LabelingMapping to separate file in binary f…
tpietzsch Jun 25, 2020
d024e74
LabelData: Use Trove TIntList for fragmentIndices
tpietzsch Jun 25, 2020
9174135
Remove unnecessary explicit type arguments
tpietzsch Jun 25, 2020
3f7fb29
Add LabelingPlus.pack() method to discard unused intermediate label sets
tpietzsch Jun 25, 2020
f9dae07
Remove debug output
tpietzsch Jun 25, 2020
4ccd670
Fix LabelingPlus.pack() bug
tpietzsch Jun 29, 2020
d176639
Let LabelingSegment only construct its LabelRegion on demand
tpietzsch Jun 29, 2020
25ffdeb
Let FlatForest.Node return its size
tpietzsch Jun 29, 2020
7bbcff0
Add support for BSON file format
tomburke-rse Oct 20, 2020
2f5b3fe
Update tests, usage and dependency
tomburke-rse Oct 21, 2020
2d0ccaf
Merge branch 'TagSegmentWithSource-tobi' into imglib-roi-io_support
tomburke-rse Nov 5, 2020
4f1f552
Fit the latest roi-io changes
tomburke-rse Jan 20, 2021
bccba75
New mvn wants https only...
fjug Apr 12, 2021
123cd7b
more https stuff
fjug Apr 12, 2021
35f1959
Update version
tomburke-rse Apr 12, 2021
d149684
Merge branch 'imglib-roi-io_support' of https://github.com/TrNdy/inda…
tomburke-rse Apr 12, 2021
b2686b9
Quickfix tests
tomburke-rse Apr 12, 2021
c8f400a
Switch parent-pom to scijava
tomburke-rse Apr 21, 2021
60cb93d
Fix tests
tomburke-rse Apr 21, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
Expand All @@ -15,6 +15,8 @@

<!-- NB: Deploy releases to the ImageJ Maven repository. -->
<releaseProfiles>deploy-to-scijava</releaseProfiles>
<imglib2-roi.version>0.11.0</imglib2-roi.version>
<imglib2-roi-io.version>0.2.0-SNAPSHOT</imglib2-roi-io.version>
</properties>

<groupId>com.indago</groupId>
Expand Down Expand Up @@ -50,6 +52,15 @@
<groupId>net.imglib2</groupId>
<artifactId>imglib2-ij</artifactId>
</dependency>
<dependency>
<groupId>net.imglib2</groupId>
<artifactId>imglib2-roi</artifactId>
</dependency>
<dependency>
<groupId>net.imglib2</groupId>
<artifactId>imglib2-roi-io</artifactId>
<version>${imglib2-roi-io.version}</version>
</dependency>
<dependency>
<groupId>nz.ac.waikato.cms.weka</groupId>
<artifactId>weka-dev</artifactId>
Expand Down Expand Up @@ -141,11 +152,11 @@
<repositories>
<repository>
<id>imagej.public</id>
<url>http://maven.scijava.org/content/groups/public</url>
<url>https://maven.scijava.org/content/groups/public</url>
</repository>
<repository>
<id>erichseifert.de</id>
<url>http://mvn.erichseifert.de/maven2</url>
<url>https://mvn.erichseifert.de/maven2</url>
</repository>
</repositories>
</project>
21 changes: 18 additions & 3 deletions src/main/java/com/indago/data/segmentation/LabelData.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.indago.data.segmentation;

import gnu.trove.list.TIntList;
import gnu.trove.list.array.TIntArrayList;
import java.util.ArrayList;

/**
Expand All @@ -22,7 +24,9 @@ public class LabelData {

private LabelingTreeNode labelingTreeNode;

private final ArrayList< Integer > fragmentIndices;
private final TIntList fragmentIndices;

private String segmentSource;

LabelData() {
this( createId() );
Expand All @@ -33,7 +37,8 @@ public class LabelData {
useId( id );
segment = null;
labelingTreeNode = null;
fragmentIndices = new ArrayList<>();
fragmentIndices = new TIntArrayList();
segmentSource = null;
}

void setSegment( final LabelingSegment segment ) {
Expand All @@ -52,7 +57,7 @@ public LabelingTreeNode getLabelingTreeNode() {
return labelingTreeNode;
}

public ArrayList< Integer > getFragmentIndices() {
public TIntList getFragmentIndices() {
return fragmentIndices;
}

Expand All @@ -70,4 +75,14 @@ private static synchronized void useId( final int id ) {
if ( nextId < id + 1 )
nextId = id + 1;
}

public void setSegmentSource( String source ) {
this.segmentSource = source;

}

public String getSegmentSource() {
return segmentSource;
}

}
28 changes: 23 additions & 5 deletions src/main/java/com/indago/data/segmentation/LabelingBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,22 @@ public LabelingBuilder( final LabelingPlus labelingPlus ) {
super( labelingPlus );
}

public synchronized < T extends TreeNode< T > & Iterable< ? extends Localizable > > LabelingForest buildLabelingForest( final Forest< T > forest ) {
public synchronized < T extends TreeNode< T > & Iterable< ? extends Localizable > > LabelingForest buildLabelingForest(
final Forest< T > forest ) {
String segmentationSource = "";
return buildingLabelingForestWithSegmentationSource( forest, segmentationSource );
}

private < T extends TreeNode< T > & Iterable< ? extends Localizable > > LabelingForest buildingLabelingForestWithSegmentationSource(
final Forest< T > forest,
String segmentationSource ) {

return buildingLabelingForestWithSegmentationSource( forest, segmentationSource );
}

public synchronized < T extends TreeNode< T > & Iterable< ? extends Localizable > > LabelingForest buildLabelingForest(
final Forest< T > forest,
String segmentationSource ) {
// invalidate fragments and segments because we will add new labels
fragments = null;
segments = null;
Expand Down Expand Up @@ -61,7 +76,7 @@ public LabelingBuilder( final LabelingPlus labelingPlus ) {
// build a LabelingForest using the structure of the original forest
final HashSet< LabelingTreeNode > roots = new HashSet<>();
for ( final T node : forest.roots() )
roots.add( buildLabelingTreeNodeFor( node, nodeToLabel ) );
roots.add( buildLabelingTreeNodeFor( node, nodeToLabel, segmentationSource ) );

// add new forest to list of forests ever added
final LabelingForest labelingForest = new LabelingForest( roots );
Expand All @@ -70,12 +85,15 @@ public LabelingBuilder( final LabelingPlus labelingPlus ) {
return labelingForest;
}

private < T extends TreeNode< T > > LabelingTreeNode buildLabelingTreeNodeFor( final T node, final HashMap< T, LabelData > nodeToLabel ) {
private < T extends TreeNode< T > > LabelingTreeNode buildLabelingTreeNodeFor(
final T node,
final HashMap< T, LabelData > nodeToLabel,
final String segmentationSource ) {
final LabelData label = nodeToLabel.get( node );
createSegmentAndTreeNode( label );
createSegmentAndTreeNode( label, segmentationSource );
final LabelingTreeNode ltn = label.getLabelingTreeNode();
for ( final T c : node.getChildren() )
ltn.addChild( buildLabelingTreeNodeFor( c, nodeToLabel ) );
ltn.addChild( buildLabelingTreeNodeFor( c, nodeToLabel, segmentationSource ) );
return ltn;
}
}
70 changes: 64 additions & 6 deletions src/main/java/com/indago/data/segmentation/LabelingPlus.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.indago.data.segmentation;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import java.util.Set;
import net.imglib2.Cursor;
import net.imglib2.Dimensions;
import net.imglib2.img.Img;
import net.imglib2.roi.labeling.ImgLabeling;
import net.imglib2.roi.labeling.LabelRegion;
import net.imglib2.roi.labeling.LabelRegions;
import net.imglib2.roi.labeling.LabelingMapping;
import net.imglib2.roi.labeling.LabelingType;
import net.imglib2.type.numeric.integer.IntType;
import net.imglib2.util.Util;

Expand All @@ -34,13 +38,20 @@ public class LabelingPlus
public LabelingPlus( final Dimensions dimensions ) {
indexImg = Util.getArrayOrCellImgFactory( dimensions, intType ).create( dimensions, intType );
labeling = new ImgLabeling<>( indexImg );
labelRegions = new LabelRegions< LabelData >( labeling );
labelingForests = new ArrayList< LabelingForest >();
labelRegions = new LabelRegions<>( labeling );
labelingForests = new ArrayList<>();
}

public LabelingPlus( final Img< IntType > indexImg ) {
this.indexImg = indexImg;
labeling = new ImgLabeling<>( indexImg );
labelRegions = new LabelRegions<>( labeling );
labelingForests = new ArrayList<>();
}

public LabelingPlus( final Img< IntType > indexImg, final ImgLabeling labeling ) {
this.indexImg = indexImg;
this.labeling = labeling;
labelRegions = new LabelRegions< LabelData >( labeling );
labelingForests = new ArrayList< LabelingForest >();
}
Expand Down Expand Up @@ -69,7 +80,8 @@ public synchronized ArrayList< LabelingFragment > getFragments() {
if ( fragments == null ) {
fragments = new ArrayList<>();
final LabelingMapping< LabelData > mapping = labeling.getMapping();
for ( final LabelData label : mapping.getLabels() )
final Set< LabelData > labels = mapping.getLabels();
for ( final LabelData label : labels )
label.getFragmentIndices().clear();
final int numLabelSets = mapping.numSets();
final boolean[] flags = new boolean[ numLabelSets ];
Expand Down Expand Up @@ -99,12 +111,58 @@ public synchronized ArrayList< LabelingSegment > getSegments() {
return segments;
}

void createSegmentAndTreeNode( final LabelData label )
void createSegmentAndTreeNode( final LabelData label, final String source )
{
final LabelRegion< LabelData > labelRegion = labelRegions.getLabelRegion( label );
final LabelingSegment segment = new LabelingSegment( labelRegion );
final LabelingSegment segment = new LabelingSegment( () -> labelRegions.getLabelRegion( label ) );
label.setSegment( segment );
label.setSegmentSource( source );
final LabelingTreeNode ltn = new LabelingTreeNode( segment, label );
label.setLabelingTreeNode( ltn );
}

/**
* "Compress" labeling by removing (from mapping and index image) label sets that don't occur in the index image.
* <p>
* TODO:
* - move to imglib2-roi ImgLabeling

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 for moving this upstream into imglib2-roi!

* - parallelize indexImg remapping using Parallelization/LoopBuilder
* - increment modcount
*/
public synchronized void pack()
{
final LabelingMapping< LabelData > mapping = labeling.getMapping();

// indexMap[ oldIndex ] == newIndex
final int[] indexMap = new int[ mapping.numSets() ];
final int[] inverseIndexMap = new int[ mapping.numSets() ];

int nextIndex = 1;
final Cursor< IntType > c = indexImg.cursor();
while ( c.hasNext() )
{
final IntType type = c.next();
final int oldIndex = type.get();
if ( oldIndex != 0 )
{
int newIndex = indexMap[ oldIndex ];
if ( newIndex == 0 )
{
newIndex = nextIndex++;
indexMap[ oldIndex ] = newIndex;
inverseIndexMap[ newIndex ] = oldIndex;
}
type.set( newIndex );
}
}
final int numLabelSets = nextIndex;

final List< Set< LabelData > > labelSets = new ArrayList<>( numLabelSets );
labelSets.add( new HashSet<>() );
for ( int i = 1; i < numLabelSets; i++ )
labelSets.add( new HashSet<>( mapping.labelsAtIndex( inverseIndexMap[ i ] ) ) );
mapping.setLabelSets( labelSets );

LabelingType< LabelData > t = labeling.firstElement();
t.set( t );
}
}
38 changes: 29 additions & 9 deletions src/main/java/com/indago/data/segmentation/LabelingSegment.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.indago.data.segmentation;

import java.util.function.Supplier;
import net.imglib2.Cursor;
import net.imglib2.RandomAccess;
import net.imglib2.RealLocalizable;
Expand All @@ -16,10 +17,12 @@
*/
public class LabelingSegment implements Segment {

private final LabelRegion< LabelData > region;
private final Supplier< LabelRegion< LabelData > > regionSupplier;

protected LabelingSegment( final LabelRegion< LabelData > region ) {
this.region = region;
private LabelRegion< LabelData > region = null;

protected LabelingSegment( final Supplier< LabelRegion< LabelData > > region ) {
this.regionSupplier = region;
}

/**
Expand All @@ -30,23 +33,23 @@ protected LabelingSegment( final LabelRegion< LabelData > region ) {
* @return unique serialization id of the backing {@code LabelRegion}.
*/
public int getId() {
return region.getLabel().getId();
return region().getLabel().getId();
}

@Override
public long getArea() {
return region.size();
return region().size();
}

@Override
public RealLocalizable getCenterOfMass() {
return region.getCenterOfMass();
return region().getCenterOfMass();
}

@Override
public IterableRegion< ? > getRegion()
{
return region;
return region();
}

/**
Expand All @@ -57,10 +60,10 @@ public RealLocalizable getCenterOfMass() {
public boolean conflictsWith( final Segment segment ) {
final IterableRegion< ? > segmentRegion = segment.getRegion();
if ( segment instanceof LabelingSegment )
if ( Intervals.isEmpty( Intervals.intersect( this.region, segmentRegion ) ) )
if ( Intervals.isEmpty( Intervals.intersect( this.region(), segmentRegion ) ) )
return false;

final RandomAccess< BoolType > raMask = region.randomAccess();
final RandomAccess< BoolType > raMask = region().randomAccess();
final Cursor< ? > cSegment = segmentRegion.cursor();
while ( cSegment.hasNext() ) {
cSegment.fwd();
Expand All @@ -84,4 +87,21 @@ public String toString() {
}
return ret;
}

public String getSegmentationSource() {
return region.getLabel().getSegmentSource();
}

private LabelRegion< LabelData > region()
{
if ( region == null )
{
synchronized ( this )
{
if ( region == null )
region = regionSupplier.get();
}
}
return region;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.indago.data.segmentation;

import gnu.trove.list.TIntList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -68,8 +69,8 @@ public static ArrayList< ArrayList< LabelingSegment > > getConflictGraphCliques(
Arrays.fill( heads, 1, numLists, 0 );
heads[ 0 ] = -1;
int currListIndex, firstListElem, currListElem;
ArrayList< Integer > currList;
final ArrayList< Integer > firstList = intersect.get( 0 ).getFragmentIndices();
TIntList currList;
final TIntList firstList = intersect.get( 0 ).getFragmentIndices();
A2: while ( true ) {
if ( ++heads[ 0 ] >= firstList.size() ) {
// done. we found all elements of the intersection.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.indago.data.segmentation;

import gnu.trove.list.TIntList;
import java.util.ArrayList;
import java.util.Collection;

Expand Down Expand Up @@ -36,7 +37,10 @@ public static ArrayList< ArrayList< LabelingSegment > > getConflictGraphCliques(
final LabelData sli = segmentLabels.get( i );
for ( int j = i + 1; j < numSegments; ++j ) {
final LabelData slj = segmentLabels.get( j );
for ( final Integer fj : slj.getFragmentIndices() ) {
final TIntList fragmentIndices = slj.getFragmentIndices();
for ( int k = 0; k < fragmentIndices.size(); k++ )
{
int fj = fragmentIndices.get( k );
if ( sli.getFragmentIndices().contains( fj ) ) {
final ArrayList< LabelingSegment > clique = new ArrayList<>();
clique.add( sli.getSegment() );
Expand Down
Loading