use of boofcv.struct.geo.AssociatedPair in project BoofCV by lessthanoptimal.
the class ExampleImageStitching method computeTransform.
/**
* Using abstracted code, find a transform which minimizes the difference between corresponding features
* in both images. This code is completely model independent and is the core algorithms.
*/
public static <T extends ImageGray<T>, FD extends TupleDesc> Homography2D_F64 computeTransform(T imageA, T imageB, DetectDescribePoint<T, FD> detDesc, AssociateDescription<FD> associate, ModelMatcher<Homography2D_F64, AssociatedPair> modelMatcher) {
// get the length of the description
List<Point2D_F64> pointsA = new ArrayList<>();
FastQueue<FD> descA = UtilFeature.createQueue(detDesc, 100);
List<Point2D_F64> pointsB = new ArrayList<>();
FastQueue<FD> descB = UtilFeature.createQueue(detDesc, 100);
// extract feature locations and descriptions from each image
describeImage(imageA, detDesc, pointsA, descA);
describeImage(imageB, detDesc, pointsB, descB);
// Associate features between the two images
associate.setSource(descA);
associate.setDestination(descB);
associate.associate();
// create a list of AssociatedPairs that tell the model matcher how a feature moved
FastQueue<AssociatedIndex> matches = associate.getMatches();
List<AssociatedPair> pairs = new ArrayList<>();
for (int i = 0; i < matches.size(); i++) {
AssociatedIndex match = matches.get(i);
Point2D_F64 a = pointsA.get(match.src);
Point2D_F64 b = pointsB.get(match.dst);
pairs.add(new AssociatedPair(a, b, false));
}
// find the best fit model to describe the change between these images
if (!modelMatcher.process(pairs))
throw new RuntimeException("Model Matcher failed!");
// return the found image transform
return modelMatcher.getModelParameters().copy();
}
use of boofcv.struct.geo.AssociatedPair in project BoofCV by lessthanoptimal.
the class FundamentalLinear method createA.
/**
* Reorganizes the epipolar constraint equation (x<sup>T</sup><sub>2</sub>*F*x<sub>1</sub> = 0) such that it
* is formulated as a standard linear system of the form Ax=0. Where A contains the pixel locations and x is
* the reformatted fundamental matrix.
*
* @param points Set of associated points in left and right images.
* @param A Matrix where the reformatted points are written to.
*/
protected void createA(List<AssociatedPair> points, DMatrixRMaj A) {
A.reshape(points.size(), 9, false);
A.zero();
Point2D_F64 f_norm = new Point2D_F64();
Point2D_F64 s_norm = new Point2D_F64();
final int size = points.size();
for (int i = 0; i < size; i++) {
AssociatedPair p = points.get(i);
Point2D_F64 f = p.p1;
Point2D_F64 s = p.p2;
// normalize the points
N1.apply(f, f_norm);
N2.apply(s, s_norm);
// perform the Kronecker product with the two points being in
// homogeneous coordinates (z=1)
A.unsafe_set(i, 0, s_norm.x * f_norm.x);
A.unsafe_set(i, 1, s_norm.x * f_norm.y);
A.unsafe_set(i, 2, s_norm.x);
A.unsafe_set(i, 3, s_norm.y * f_norm.x);
A.unsafe_set(i, 4, s_norm.y * f_norm.y);
A.unsafe_set(i, 5, s_norm.y);
A.unsafe_set(i, 6, f_norm.x);
A.unsafe_set(i, 7, f_norm.y);
A.unsafe_set(i, 8, 1);
}
}
use of boofcv.struct.geo.AssociatedPair in project BoofCV by lessthanoptimal.
the class PerspectiveOps method splitAssociated.
/**
* Takes a list of {@link AssociatedPair} as input and breaks it up into two lists for each view.
*
* @param pairs Input: List of associated pairs.
* @param view1 Output: List of observations from view 1
* @param view2 Output: List of observations from view 2
*/
public static void splitAssociated(List<AssociatedPair> pairs, List<Point2D_F64> view1, List<Point2D_F64> view2) {
for (AssociatedPair p : pairs) {
view1.add(p.p1);
view2.add(p.p2);
}
}
use of boofcv.struct.geo.AssociatedPair in project BoofCV by lessthanoptimal.
the class LowLevelMultiViewOps method computeNormalization.
/**
* <p>
* Computes two normalization matrices for each set of point correspondences in the list of
* {@link boofcv.struct.geo.AssociatedPair}. Same as {@link #computeNormalization(java.util.List, NormalizationPoint2D)},
* but for two views.
* </p>
*
* @param points Input: List of observed points that are to be normalized. Not modified.
* @param N1 Output: 3x3 normalization matrix for first set of points. Modified.
* @param N2 Output: 3x3 normalization matrix for second set of points. Modified.
*/
public static void computeNormalization(List<AssociatedPair> points, NormalizationPoint2D N1, NormalizationPoint2D N2) {
double meanX1 = 0;
double meanY1 = 0;
double meanX2 = 0;
double meanY2 = 0;
for (AssociatedPair p : points) {
meanX1 += p.p1.x;
meanY1 += p.p1.y;
meanX2 += p.p2.x;
meanY2 += p.p2.y;
}
meanX1 /= points.size();
meanY1 /= points.size();
meanX2 /= points.size();
meanY2 /= points.size();
double stdX1 = 0;
double stdY1 = 0;
double stdX2 = 0;
double stdY2 = 0;
for (AssociatedPair p : points) {
double dx = p.p1.x - meanX1;
double dy = p.p1.y - meanY1;
stdX1 += dx * dx;
stdY1 += dy * dy;
dx = p.p2.x - meanX2;
dy = p.p2.y - meanY2;
stdX2 += dx * dx;
stdY2 += dy * dy;
}
N1.meanX = meanX1;
N1.meanY = meanY1;
N2.meanX = meanX2;
N2.meanY = meanY2;
N1.stdX = Math.sqrt(stdX1 / points.size());
N1.stdY = Math.sqrt(stdY1 / points.size());
N2.stdX = Math.sqrt(stdX2 / points.size());
N2.stdY = Math.sqrt(stdY2 / points.size());
}
use of boofcv.struct.geo.AssociatedPair in project BoofCV by lessthanoptimal.
the class TestLowLevelMultiViewOps method computeNormalization_two.
/**
* Compare to single list function
*/
@Test
public void computeNormalization_two() {
List<AssociatedPair> list = new ArrayList<>();
for (int i = 0; i < 12; i++) {
AssociatedPair p = new AssociatedPair();
p.p2.set(rand.nextDouble() * 5, rand.nextDouble() * 5);
p.p1.set(rand.nextDouble() * 5, rand.nextDouble() * 5);
list.add(p);
}
List<Point2D_F64> list1 = new ArrayList<>();
List<Point2D_F64> list2 = new ArrayList<>();
PerspectiveOps.splitAssociated(list, list1, list2);
NormalizationPoint2D expected1 = new NormalizationPoint2D();
NormalizationPoint2D expected2 = new NormalizationPoint2D();
LowLevelMultiViewOps.computeNormalization(list1, expected1);
LowLevelMultiViewOps.computeNormalization(list2, expected2);
NormalizationPoint2D found1 = new NormalizationPoint2D();
NormalizationPoint2D found2 = new NormalizationPoint2D();
LowLevelMultiViewOps.computeNormalization(list, found1, found2);
assertTrue(expected1.isEquals(found1, 1e-8));
assertTrue(expected2.isEquals(found2, 1e-8));
}
Aggregations