use of georegression.struct.point.Point2D_F32 in project BoofCV by lessthanoptimal.
the class SfmTestHelper method renderPointPixel.
/**
* Renders a 3D point in the left and right camera views given the stereo parameters. Lens distortion
* is taken in account.
*
* @param param Stereo parameters
* @param X Point location in 3D space
* @param left location in pixels in left camera
* @param right location in pixels in right camera
*/
public static void renderPointPixel(StereoParameters param, Point3D_F64 X, Point2D_F64 left, Point2D_F64 right) {
// compute the location of X in the right camera's reference frame
Point3D_F64 rightX = new Point3D_F64();
SePointOps_F64.transform(param.getRightToLeft().invert(null), X, rightX);
// location of object in normalized image coordinates
Point2D_F64 normLeft = new Point2D_F64(X.x / X.z, X.y / X.z);
Point2D_F64 normRight = new Point2D_F64(rightX.x / rightX.z, rightX.y / rightX.z);
// convert into pixel coordinates
Point2D_F64 pixelLeft = PerspectiveOps.convertNormToPixel(param.left, normLeft.x, normLeft.y, null);
Point2D_F64 pixelRight = PerspectiveOps.convertNormToPixel(param.right, normRight.x, normRight.y, null);
// take in account lens distortion
Point2Transform2_F32 distLeft = LensDistortionOps.narrow(param.left).distort_F32(true, true);
Point2Transform2_F32 distRight = LensDistortionOps.narrow(param.right).distort_F32(true, true);
Point2D_F32 lensLeft = new Point2D_F32();
Point2D_F32 lensRight = new Point2D_F32();
distLeft.compute((float) pixelLeft.x, (float) pixelLeft.y, lensLeft);
distRight.compute((float) pixelRight.x, (float) pixelRight.y, lensRight);
// output solution
left.set(lensLeft.x, lensLeft.y);
right.set(lensRight.x, lensRight.y);
}
use of georegression.struct.point.Point2D_F32 in project BoofCV by lessthanoptimal.
the class TestCreateSyntheticOverheadView method checkPrecomputedTransform.
@Test
public void checkPrecomputedTransform() {
// Easier to make up a plane in this direction
Se3_F64 cameraToPlane = new Se3_F64();
ConvertRotation3D_F64.eulerToMatrix(EulerType.XYZ, UtilAngle.degreeToRadian(0), 0, 0, cameraToPlane.getR());
cameraToPlane.getT().set(0, -5, 0);
Se3_F64 planeToCamera = cameraToPlane.invert(null);
CreateSyntheticOverheadView alg = new CreateSyntheticOverheadView() {
@Override
public void process(ImageBase input, ImageBase output) {
}
};
int overheadW = 500;
int overheadH = 600;
double cellSize = 0.05;
double centerX = 1;
double centerY = overheadH * cellSize / 2.0;
alg.configure(param, planeToCamera, centerX, centerY, cellSize, overheadW, overheadH);
// directly below camera, should not be in view
assertTrue(null == alg.getOverheadToPixel(0, 300));
// point at the end of the map should be in view
assertTrue(null != alg.getOverheadToPixel(overheadW - 1, 300));
// check the value at one point by doing the reverse transform
Point2D_F32 found = alg.getOverheadToPixel(400, 320);
CameraPlaneProjection proj = new CameraPlaneProjection();
proj.setPlaneToCamera(planeToCamera, true);
proj.setIntrinsic(param);
Point2D_F64 expected = new Point2D_F64();
proj.pixelToPlane(found.x, found.y, expected);
// put into overhead pixels
expected.x = (expected.x + centerX) / cellSize;
expected.y = (expected.y + centerY) / cellSize;
assertEquals(400, expected.x, 1e-4);
assertEquals(320, expected.y, 1e-4);
}
use of georegression.struct.point.Point2D_F32 in project BoofCV by lessthanoptimal.
the class ChecksPointDeformKeyPoints method individualSrcSameAsAll.
/**
* Makes sure modifying a single points is the same as modifying all the points at once
*/
@Test
public void individualSrcSameAsAll() {
List<Point2D_F32> src = createTestPoints();
List<Point2D_F32> dst = createTestPoints();
PointDeformKeyPoints alg = createAlgorithm();
alg.setImageShape(80, 100);
alg.setSource(src);
alg.setSource(dst);
alg.setSource(1, 20, 25);
Point2D_F32 expected = new Point2D_F32();
alg.compute(12, 19.5f, expected);
src.get(1).set(20, 25);
Point2D_F32 found = new Point2D_F32();
alg.compute(12, 19.5f, found);
assertEquals(expected.x, found.x, GrlConstants.TEST_F32);
assertEquals(expected.y, found.y, GrlConstants.TEST_F32);
}
use of georegression.struct.point.Point2D_F32 in project BoofCV by lessthanoptimal.
the class BackgroundModelMoving method updateBackground.
/**
* Updates the background with new image information.
*
* @param homeToCurrent Transform from home image to the current image
* @param frame The current image in the sequence
*/
public void updateBackground(MotionModel homeToCurrent, T frame) {
worldToHome.concat(homeToCurrent, worldToCurrent);
worldToCurrent.invert(currentToWorld);
// find the distorted polygon of the current image in the "home" background reference frame
transform.setModel(currentToWorld);
transform.compute(0, 0, corners[0]);
transform.compute(frame.width - 1, 0, corners[1]);
transform.compute(frame.width - 1, frame.height - 1, corners[2]);
transform.compute(0, frame.height - 1, corners[3]);
// find the bounding box
int x0 = Integer.MAX_VALUE;
int y0 = Integer.MAX_VALUE;
int x1 = -Integer.MAX_VALUE;
int y1 = -Integer.MAX_VALUE;
for (int i = 0; i < 4; i++) {
Point2D_F32 p = corners[i];
int x = (int) p.x;
int y = (int) p.y;
if (x0 > x)
x0 = x;
if (y0 > y)
y0 = y;
if (x1 < x)
x1 = x;
if (y1 < y)
y1 = y;
}
x1++;
y1++;
if (x0 < 0)
x0 = 0;
if (x1 > backgroundWidth)
x1 = backgroundWidth;
if (y0 < 0)
y0 = 0;
if (y1 > backgroundHeight)
y1 = backgroundHeight;
updateBackground(x0, y0, x1, y1, frame);
}
use of georegression.struct.point.Point2D_F32 in project BoofCV by lessthanoptimal.
the class LineImageOps method pruneSimilarLines.
/**
* Prunes similar looking lines, but keeps the lines with the most intensity.
*
* @param lines
* @param intensity
* @param toleranceAngle
* @return
*/
public static List<LineParametric2D_F32> pruneSimilarLines(List<LineParametric2D_F32> lines, float[] intensity, float toleranceAngle, float toleranceDist, int imgWidth, int imgHeight) {
int[] indexSort = new int[intensity.length];
QuickSort_F32 sort = new QuickSort_F32();
sort.sort(intensity, 0, lines.size(), indexSort);
float[] theta = new float[lines.size()];
List<LineSegment2D_F32> segments = new ArrayList<>(lines.size());
for (int i = 0; i < lines.size(); i++) {
LineParametric2D_F32 l = lines.get(i);
theta[i] = UtilAngle.atanSafe(l.getSlopeY(), l.getSlopeX());
segments.add(convert(l, imgWidth, imgHeight));
}
for (int i = segments.size() - 1; i >= 0; i--) {
LineSegment2D_F32 a = segments.get(indexSort[i]);
if (a == null)
continue;
for (int j = i - 1; j >= 0; j--) {
LineSegment2D_F32 b = segments.get(indexSort[j]);
if (b == null)
continue;
if (UtilAngle.distHalf(theta[indexSort[i]], theta[indexSort[j]]) > toleranceAngle)
continue;
Point2D_F32 p = Intersection2D_F32.intersection(a, b, null);
if (p != null && p.x >= 0 && p.y >= 0 && p.x < imgWidth && p.y < imgHeight) {
segments.set(indexSort[j], null);
} else {
float distA = Distance2D_F32.distance(a, b.a);
float distB = Distance2D_F32.distance(a, b.b);
if (distA <= toleranceDist || distB < toleranceDist) {
segments.set(indexSort[j], null);
}
}
}
}
List<LineParametric2D_F32> ret = new ArrayList<>();
for (int i = 0; i < segments.size(); i++) {
if (segments.get(i) != null) {
ret.add(lines.get(i));
}
}
return ret;
}
Aggregations