net.raumzeitfalle.registration.DegreesOfFreedom Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of image-registration Show documentation
Show all versions of image-registration Show documentation
A collection of functions for image registration based on control points using rigid and affine transforms.
/*-
* #%L
* Image-Registration
* %%
* Copyright (C) 2019, 2021 Oliver Loeffler, Raumzeitfalle.net
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package net.raumzeitfalle.registration;
import java.util.*;
import java.util.function.*;
import net.raumzeitfalle.registration.displacement.Displacement;
/**
*
* Rigid Body 3-parameter Model
*
* - DoF = 0 -> no calculation possible
* - DoF = 1 -> translation only
* - DoF >= 2 -> translation and rotation
*
*
*
*/
public class DegreesOfFreedom implements Consumer, UnaryOperator, OrientedOperation {
private final Set xLocations = new HashSet<>(1000);
private final Set yLocations = new HashSet<>(1000);
@Override
public void accept(Displacement t) {
if (Double.isFinite(t.getXd()))
xLocations.add(Double.valueOf(t.getX()));
if (Double.isFinite(t.getYd()))
yLocations.add(Double.valueOf(t.getY()));
}
public Orientation getDirection() {
if (xLocations.size() == 0 && yLocations.size() == 0) {
return Orientations.XY;
}
if (xLocations.size() > 0 && yLocations.size() > 0) {
return Orientations.XY;
}
if (xLocations.size() > 0) {
return Orientations.X;
}
return Orientations.Y;
}
public Distribution getDistribution() {
if (xLocations.isEmpty() && yLocations.isEmpty()) {
throw new IllegalArgumentException("Could not determine data distribution as no valid displacements have been processed yet.");
}
if (xLocations.size() > 1 && yLocations.size() > 1)
return Distribution.AREA;
if (xLocations.size() == 1 && yLocations.size() > 1)
return Distribution.VERTICAL;
if (yLocations.size() == 1 && xLocations.size() > 1)
return Distribution.HORIZONTAL;
return Distribution.SINGULARITY;
}
@Override
public Displacement apply(Displacement t) {
accept(t);
return t;
}
public Integer getX() {
return this.xLocations.size();
}
public Integer getY() {
return this.yLocations.size();
}
public Integer getCombined() {
return Math.max(this.getX(),this.getY());
// return this.xLocations.size() + this.yLocations.size();
}
public int getDimensions() {
return getDirection().getDimensions();
}
public int getDegrees() {
Orientation orientation = this.getDirection();
return orientation.runOperation(this);
}
@Override
public String toString() {
return String.format("DegreesOfFreedom [xLocations=%s, yLocations=%s]", xLocations.size(), yLocations.size());
}
}