package de.mpicbg.scf.skeletonanalysis; | ||
import ij.IJ; | ||
import ij.ImageJ; | ||
import ij.ImagePlus; | ||
import ij.gui.Overlay; | ||
import ij.gui.PointRoi; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
import sc.fiji.analyzeSkeleton.*; | ||
import java.util.ArrayList; | ||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertTrue; | ||
/** | ||
* Author: Robert Haase, Scientific Computing Facility, MPI-CBG Dresden, rhaase@mpi-cbg.de | ||
* Date: September 2016 | ||
*/ | ||
public class SkeletonAnalyserTest { | ||
@Test | ||
public void academicTestExample() | ||
{ | ||
ImageJ.main( new String[1] ); | ||
// --------------------------------- | ||
// load images | ||
ImagePlus skeletonImage = IJ.openImage( | ||
AnalyzeSkeleton_.class.getResource( | ||
"/skelRaw.tif" ).getFile() ); | ||
skeletonImage.show(); | ||
ImagePlus greyValueImage = IJ.openImage( | ||
AnalyzeSkeleton_.class.getResource( | ||
"/greyValueImage.tif" ).getFile() ); | ||
greyValueImage.show(); | ||
if (greyValueImage.getOverlay() == null) { | ||
greyValueImage.setOverlay(new Overlay()); | ||
} | ||
// --------------------------------- | ||
// derive skeleton | ||
AnalyzeSkeleton_ skel = new AnalyzeSkeleton_(); | ||
skel.setup("", skeletonImage); | ||
Please
register
or
sign in
to reply
|
||
simpleSkeletonResult = skel.run(AnalyzeSkeleton_.SHORTEST_BRANCH, false, false, greyValueImage, false, false); | ||
// --------------------------------- | ||
// run the skeleton Analyser | ||
skeletonAnalyser = new SkeletonAnalyser(simpleSkeletonResult); | ||
// --------------------------------- | ||
// get largest junction and its position | ||
|
||
Vertex soma = skeletonAnalyser.getLargestJunction(); | ||
Point somaCenter = SkeletonAnalyser.getCenterOfJunction(soma); | ||
System.out.println("Some at: " + somaCenter); | ||
assertTrue(somaCenter.x == 44); | ||
assertTrue(somaCenter.y == 1031); | ||
assertTrue(somaCenter.z == 0); | ||
// --------------------------------- | ||
// get number of processes | ||
ArrayList<Edge> edgesStartingAtSoma = skeletonAnalyser.getEdgesStartingAtJunction(soma); | ||
System.out.println("Numbe of processes (edges starting at soma) " + edgesStartingAtSoma.size()); | ||
assertTrue(edgesStartingAtSoma.size() == 2); | ||
|
||
// --------------------------------- | ||
// navigate in edges starting at soma | ||
for (Edge edge : edgesStartingAtSoma) | ||
{ | ||
assertTrue(SkeletonAnalyser.junctionsEqual(edge.getV1(), soma)); | ||
// check if the edges end is a leaf | ||
Vertex otherJunction = edge.getV2(); | ||
ArrayList<Edge> edgesStartingAtJunction = skeletonAnalyser.getEdgesStartingAtJunction(otherJunction); | ||
System.out.println("Number of edges starting at junction " + edgesStartingAtJunction.size()); | ||
if (edgesStartingAtJunction.size() == 1) | ||
{ | ||
// leaf | ||
System.out.println("Found leaf directly connected to soma."); | ||
} | ||
else | ||
{ | ||
// it's not a leaf so go through following edges | ||
for (Edge deeperEdge : edgesStartingAtJunction) | ||
{ | ||
// don't go back in tree | ||
if (SkeletonAnalyser.edgesEqual(edge, deeperEdge)) | ||
{ | ||
System.out.println("Deeper in tree"); | ||
// continue recursively | ||
} | ||
} | ||
} | ||
} | ||
// --------------------------------- | ||
// get all leafs | ||
ArrayList<Vertex> leafs = skeletonAnalyser.getLeafs(); | ||
System.out.println("number of leafs: " + leafs.size()); | ||
assertTrue(leafs.size() == 2); | ||
|
||
// --------------------------------- | ||
// get shortest paths from leafs to | ||
// soma and analyse their straightness | ||
for (Vertex leaf : leafs) | ||
{ | ||
ArrayList<Edge> path = skeletonAnalyser.getShortestPath(leaf, soma); | ||
// measure from junction center to junction center | ||
double pathLength = SkeletonAnalyser.getLengthAlongPath(path); | ||
System.out.println("path length " + pathLength); | ||
// last edge ends at soma | ||
Edge edgeAtSoma = path.get(path.size() - 1); | ||
assertTrue(SkeletonAnalyser.junctionsEqual(soma, edgeAtSoma.getV2())); | ||
// but it neads to be flipped, because its second vertex is the soma | ||
Edge edgeStartingAtSoma = SkeletonAnalyser.flipEdge(edgeAtSoma); | ||
assertTrue(SkeletonAnalyser.junctionsEqual(soma, edgeStartingAtSoma.getV1())); | ||
// determine length along path from starting point (at the border of soma) to leaf | ||
double distanceBetweenStartingPointAndSomaCenter = SkeletonAnalyser.getDistanceBetweenStartingPointAndJunctionCenter(edgeStartingAtSoma); | ||
double actualLength = pathLength - distanceBetweenStartingPointAndSomaCenter; | ||
// get starting and ending point | ||
Point startingPoint = edgeStartingAtSoma.getSlabs().get(0); | ||
Point leafCenter = SkeletonAnalyser.getCenterOfJunction(leaf); | ||
// calculate euclidean distance between both points and the actual straightness | ||
double euclideanDistance = SkeletonAnalyser.getPointDistance(startingPoint, leafCenter); | ||
double actualStraightness = euclideanDistance / actualLength; | ||
System.out.println("Straightness (startpoint to leaf center) " + actualStraightness); | ||
System.out.println("Straightness (soma center to leaf center) " + SkeletonAnalyser.getStraightness(path)); | ||
} | ||
// --------------------------------- | ||
// draw paths from soma to leaf | ||
for (Vertex leaf : leafs) { | ||
ArrayList<Edge> path = skeletonAnalyser.getShortestPath(leaf, soma); | ||
ArrayList<Point> polygon = SkeletonAnalyser.getPointsAlongPath(path); | ||
for (Point point : polygon) | ||
{ | ||
greyValueImage.getOverlay().add(new PointRoi(point.x, point.y)); | ||
} | ||
} | ||
|
||
// --------------------------------- | ||
// determine longest path per process | ||
for (Edge edge : edgesStartingAtSoma) { | ||
double maximumLength = Double.POSITIVE_INFINITY; | ||
for (Vertex leaf : leafs) { | ||
ArrayList<Edge> path = skeletonAnalyser.getShortestPath(soma, leaf); | ||
// check if the leaf is part of the current process | ||
if (SkeletonAnalyser.pathContainsEdge(path, edge)) { | ||
double length = SkeletonAnalyser.getLengthAlongPath(path); | ||
if (maximumLength < length) { | ||
maximumLength = length; | ||
} | ||
} | ||
} | ||
System.out.println("Longest path of process " + (maximumLength - SkeletonAnalyser.getDistanceBetweenStartingPointAndJunctionCenter(edge))); | ||
} | ||
// --------------------------------- | ||
} | ||
SkeletonResult simpleSkeletonResult; | ||
double tolerance = 1; | ||
SkeletonAnalyser skeletonAnalyser; | ||
@Before | ||
public void initialize() | ||
{ | ||
ImageJ.main( new String[1] ); | ||
ImagePlus target = IJ.openImage( | ||
AnalyzeSkeleton_.class.getResource( | ||
"/verysimple.tif" ).getFile() ); | ||
target.show(); | ||
AnalyzeSkeleton_ skel = new AnalyzeSkeleton_(); | ||
skel.setup("", target); | ||
//skel.run( null ); | ||
simpleSkeletonResult = skel.run(AnalyzeSkeleton_.SHORTEST_BRANCH, false, false, target, false, false); | ||
// = skel.assembleResults(); | ||
skeletonAnalyser = new SkeletonAnalyser(simpleSkeletonResult); | ||
} | ||
@Test | ||
public void testIfGettingLargestJunctionWorks() | ||
{ | ||
// from one particular graph | ||
Vertex v1 = skeletonAnalyser.getLargestJunction(); | ||
assertTrue(v1.getPoints().size() == 2); | ||
} | ||
@Test | ||
public void testIfNumberOfStartingEdgesIsCorrect() | ||
{ | ||
Vertex v1 = skeletonAnalyser.getLargestJunction(); | ||
ArrayList<Edge> edges = skeletonAnalyser.getEdgesStartingAtJunction(v1); | ||
assertTrue(edges.size() == 4); | ||
} | ||
@Test | ||
public void testIfNumberOfLeafsIsCorrect() | ||
{ | ||
ArrayList<Vertex> leafs = skeletonAnalyser.getLeafs(); | ||
assertTrue(leafs.size() == 4); | ||
} | ||
@Test | ||
public void testIfEdgeCountIsCorrect() | ||
{ | ||
assertEquals(simpleSkeletonResult.getGraph()[0].getEdges().size(), 4); | ||
} | ||
@Test | ||
public void testIfAllEdgesHaveSameLength() | ||
{ | ||
double length = -1; | ||
for (Edge edge : simpleSkeletonResult.getGraph()[0].getEdges()) | ||
{ | ||
System.out.println(edge.toString()); | ||
System.out.println("V1: " + SkeletonAnalyser.getCenterOfJunction(edge.getV1())); | ||
System.out.println("V1raw: " + edge.getV1()); | ||
System.out.println("V2: " + SkeletonAnalyser.getCenterOfJunction(edge.getV2())); | ||
System.out.println("V2raw: " + edge.getV2()); | ||
System.out.println("len: " + SkeletonAnalyser.getLengthOfEdge(edge)); | ||
if (length < 0) | ||
{ | ||
length = SkeletonAnalyser.getLengthOfEdge(edge); | ||
} | ||
else | ||
{ | ||
assertEquals(length, SkeletonAnalyser.getLengthOfEdge(edge), tolerance); | ||
} | ||
} | ||
} | ||
// 1,1 | ||
// 8,1 | ||
@Test | ||
public void testIfShortestPathWorks() | ||
{ | ||
Vertex v1 = skeletonAnalyser.getVertexAtPosition(1,1,0); | ||
Vertex v2 = skeletonAnalyser.getVertexAtPosition(8,1,0); | ||
ArrayList<Edge> shortPath = skeletonAnalyser.getShortestPath(v1, v2); | ||
assertTrue(shortPath.size() == 2); | ||
Vertex vCenter = shortPath.get(0).getV2(); | ||
Vertex soma = skeletonAnalyser.getLargestJunction(); | ||
assertTrue(SkeletonAnalyser.junctionsEqual(vCenter, soma)); | ||
} | ||
} |