Commit 15f04320 authored by Daniel Felipe  GONZALEZ OBANDO's avatar Daniel Felipe GONZALEZ OBANDO
Browse files

Re-enabled volume constraint with revised method taking into account

both model and feedback forces
parent 4633b6e6
......@@ -16,5 +16,7 @@
<classpathentry kind="var" path="ICY_PLUGINS/nchenouard/spot/DetectionResult.jar"/>
<classpathentry kind="var" path="ICY_PLUGINS/adufour/blocks/Blocks.jar"/>
<classpathentry kind="var" path="ICY_PLUGINS/adufour/roi/mesh/ROI3DMeshPlugin.jar"/>
<classpathentry kind="var" path="ICY_PLUGINS/adufour/thresholder/Thresholder.jar"/>
<classpathentry kind="var" path="ICY_PLUGINS/adufour/roi/LabelExtractor.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
......@@ -145,7 +145,7 @@ public abstract class ActiveContour extends Detection implements Iterable<Point3
abstract void computeInternalForces(double weight);
abstract void computeVolumeConstraint(double targetVolume);
abstract void computeVolumeConstraint(double targetVolume, double weight);
/**
* Computes the feedback forces yielded by the penetration of the current contour into the
......
......@@ -338,9 +338,8 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
public final EzVarBoolean tracking_newObjects = new EzVarBoolean("Watch entering objects", false);
private final HashMap<TrackSegment, Double> volumes = new HashMap<TrackSegment, Double>();
// TODO: we disabled volume constraint feature as it doesn't work and sometime end to crazy contour (Stephane)
public final EzVarBoolean volume_constraint = new EzVarBoolean("Volume constraint (disabled)", false);
// public final EzVarBoolean volume_constraint = new EzVarBoolean("Volume constraint", false);
public final EzVarBoolean volume_constraint = new EzVarBoolean("Volume constraint", false);
public final EzVarDouble volume_weight = new EzVarDouble("Volume weight", 0.01, 0,1, 0.01);
public final EzButton showTrackManager;
......@@ -515,7 +514,7 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
{
super.loadParameters(file);
// TODO: we disabled volume constraint feature as it doesn't work and sometime end to crazy contour (Stephane)
// TODO: disabled as the feature is broken (Stephane)
volume_constraint.setValue(Boolean.FALSE);
}
......@@ -1430,7 +1429,7 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
if (volume_constraint.getValue() && volumes.containsKey(segment))
{
contour.computeVolumeConstraint(volumes.get(segment));
contour.computeVolumeConstraint(volumes.get(segment), volume_weight.getValue());
}
contour.move(boundField, contour_timeStep.getValue());
......@@ -1491,10 +1490,12 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
contour.computeFeedbackForces(otherContour);
}
// we disabled volume constraint feature as it doesn't work and sometime end to crazy contour (Stephane)
// re-enabled volume constraint after taking into account both shrinking and growing contours instead of just growing ones(Daniel)
if (volume_constraint.getValue() && volumes.containsKey(segment))
{
contour.computeVolumeConstraint(volumes.get(segment));
}
{
contour.computeVolumeConstraint(volumes.get(segment), volume_weight.getValue());
}
}
else
{
......@@ -1863,9 +1864,8 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
inputMap.add("tracking", tracking.getVariable());
inputMap.add("division sensitivity", division_sensitivity.getVariable());
inputMap.add("axis constraint", axis_weight.getVariable());
// TODO: we disabled volume constraint feature as it doesn't work and sometime end to crazy contour (Stephane)
inputMap.add("volume constraint (disabled)", volume_constraint.getVariable());
// inputMap.add("volume constraint", volume_constraint.getVariable());
volume_constraint.setValue(true);
inputMap.add("Volume weight", volume_weight.getVariable());
inputMap.add("watch entering objects", tracking_newObjects.getVariable());
}
......
......@@ -335,7 +335,8 @@ public class Mesh3D extends ActiveContour
}
}
void computeVolumeConstraint(double targetVolume)
// TODO take into account weight
void computeVolumeConstraint(double targetVolume, double weight)
{
// 1) compute the difference between target and current volume
final double volumeDiff = targetVolume - getDimension(2);
......
......@@ -417,7 +417,7 @@ public class Polygon2D extends ActiveContour
Polygon2D child1 = new Polygon2D(sampling, new SlidingWindow(this.convergence.getSize()));
for (int p = 0; p < nPoints; p++)
{
Point3d pp = points.get(p + i);
Point3d pp = points.get((p + i) % n);
center.add(pp);
child1.addPoint(pp);
}
......@@ -689,40 +689,26 @@ public class Polygon2D extends ActiveContour
weight /= sampling.getValue();
// first point
prev = points.get(n - 1);
curr = points.get(0);
next = points.get(1);
force = feedbackForces[0];
force.x += weight * (prev.x - 2 * curr.x + next.x);
force.y += weight * (prev.y - 2 * curr.y + next.y);
// initialize points
prev = points.get(n - 2);
curr = points.get(n - 1);
next = points.get(0);
// middle points
for (int i = 1; i < n - 1; i++)
for (int i = 0; i < n; i++)
{
force = feedbackForces[i];
prev = points.get(i - 1);
curr = points.get(i);
next = points.get(i + 1);
prev = curr;
curr = next;
next = points.get((i + 1)%n);
force = feedbackForces[i];
force.x += weight * (prev.x - 2 * curr.x + next.x);
force.y += weight * (prev.y - 2 * curr.y + next.y);
}
// last point
force = feedbackForces[n - 1];
prev = points.get(n - 2);
curr = points.get(n - 1);
next = points.get(0);
force.x += weight * (prev.x - 2 * curr.x + next.x);
force.y += weight * (prev.y - 2 * curr.y + next.y);
}
@Override
void computeVolumeConstraint(double targetVolume)
void computeVolumeConstraint(double targetVolume, double weight)
{
// 1) compute the difference between target and current volume
double volumeDiff = targetVolume - getDimension(2);
......@@ -731,46 +717,18 @@ public class Polygon2D extends ActiveContour
int n = points.size();
Vector3d avgFeedback = new Vector3d();
int nbFeedbackForces = 0;
Vector3d totalForce = new Vector3d();
for (int i = 0; i < n; i++)
{
Vector3d mf = modelForces[i];
totalForce.add(feedbackForces[i], modelForces[i]);
// 2) check whether the final force has same direction as the outer normal
double forceNorm = mf.dot(contourNormals[i]);
// if forces have same direction (forceNorm > 0): contour is growing
// if forces have opposite direction (forceNorm < 0): contour is shrinking
// if (forceNorm * volumeDiff < 0)
// {
// // forceNorm and volumeDiff have opposite signs because:
// // - contour too small (volumeDiff > 0) and shrinking (forceNorm < 0)
// // or
// // - contour too large (volumeDiff < 0) and growing (forceNorm > 0)
// // => in both cases, constrain the final force accordingly
// mf.scale(1.0 / (1.0 + Math.abs(volumeDiff) / 10));
// }
// estimate an average feedback
if (forceNorm > 0 && volumeDiff < 0)
{
avgFeedback.add(feedbackForces[i]);
nbFeedbackForces++;
}
}
if (avgFeedback.length() > 0)
{
avgFeedback.scale(1.0 / nbFeedbackForces);
avgFeedback.scale(Math.abs(volumeDiff / targetVolume) / 0.5);
double forceNorm = totalForce.dot(contourNormals[i]);
// move the entire mesh (ugly, but amazingly efficient!!)
for (int i = 0; i < n; i++)
{
volumeConstraintForces[i].add(avgFeedback);
if (forceNorm * volumeDiff < 0) {
totalForce.set(contourNormals[i]);
totalForce.scale(volumeDiff * weight / targetVolume);
volumeConstraintForces[i].set(totalForce);
}
}
}
......@@ -1570,28 +1528,17 @@ public class Polygon2D extends ActiveContour
protected void updateNormals()
{
int n = points.size();
Point3d p1 = points.get(n - 2);
Point3d p = points.get(n - 1);
Point3d p2 = points.get(0);
// first point
{
Point3d p1 = points.get(n - 1);
Point3d p2 = points.get(1);
contourNormals[0].normalize(new Vector3d(p2.y - p1.y, p1.x - p2.x, 0));
}
// middle points
for (int i = 1; i < n - 1; i++)
for (int i = 0; i < n; i++)
{
Point3d p1 = points.get(i - 1);
Point3d p2 = points.get(i + 1);
p1 = p;
p = p2;
p2 = points.get((i + 1) % n);
contourNormals[i].normalize(new Vector3d(p2.y - p1.y, p1.x - p2.x, 0));
}
// last point
{
Point3d p1 = points.get(n - 2);
Point3d p2 = points.get(0);
contourNormals[n - 1].normalize(new Vector3d(p2.y - p1.y, p1.x - p2.x, 0));
}
}
@Override
......@@ -1633,7 +1580,6 @@ public class Polygon2D extends ActiveContour
this.path = newPath;
}
@SuppressWarnings("deprecation")
@Deprecated
@Override
public ROI2D toROI()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment