All Downloads are FREE. Search and download functionalities are using the official Maven repository.

boofcv.alg.geo.bundle.cameras.BundlePinholeSimplified Maven / Gradle / Ivy

Go to download

BoofCV is an open source Java library for real-time computer vision and robotics applications.

There is a newer version: 1.1.7
Show newest version
/*
 * Copyright (c) 2023, Peter Abeles. All Rights Reserved.
 *
 * This file is part of BoofCV (http://boofcv.org).
 *
 * 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.
 */

package boofcv.alg.geo.bundle.cameras;

import boofcv.abst.geo.bundle.BundleAdjustmentCamera;
import georegression.struct.point.Point2D_F64;
import org.ejml.FancyPrint;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.HashMap;
import java.util.Map;

import static boofcv.misc.BoofMiscOps.getOrThrow;

/**
 * A pinhole camera with radial distortion that is fully described using three parameters. Focal length and two
 * radial distortion parameters.
 *
 * Assumptions:
 * 
    *
  • Zero skew
  • *
  • fx and fy is the same, e.g. square pixels
  • *
  • No tangential distortion
  • *
  • Image center is at coordinate (0,0)
  • *
* The image center being at (0,0) only matters if the camera's FOV is being enforced by filtering out pixels that * are outside the image. With this camera model pixels can have positive and negative values. * * @author Peter Abeles */ public class BundlePinholeSimplified implements BundleAdjustmentCamera { public final static String TYPE_NAME = "PinholeSimplified"; // focal length public double f; // radial distortion parameters public double k1, k2; public BundlePinholeSimplified() {} public BundlePinholeSimplified( double f, double k1, double k2 ) { this.f = f; this.k1 = k1; this.k2 = k2; } @Override public void setIntrinsic( double[] parameters, int offset ) { f = parameters[offset]; k1 = parameters[offset + 1]; k2 = parameters[offset + 2]; } @Override public void getIntrinsic( double[] parameters, int offset ) { parameters[offset] = f; parameters[offset + 1] = k1; parameters[offset + 2] = k2; } @Override public void project( double camX, double camY, double camZ, Point2D_F64 output ) { double normX = camX/camZ; double normY = camY/camZ; double n2 = normX*normX + normY*normY; double r = 1.0 + (k1 + k2*n2)*n2; output.x = f*r*normX; output.y = f*r*normY; } @Override public void jacobian( double X, double Y, double Z, double[] inputX, double[] inputY, boolean computeIntrinsic, @Nullable double[] calibX, @Nullable double[] calibY ) { double normX = X/Z; double normY = Y/Z; double n2 = normX*normX + normY*normY; double n2_X = 2*normX/Z; double n2_Y = 2*normY/Z; double n2_Z = -2*n2/Z; double r = 1.0 + (k1 + k2*n2)*n2; double kk = k1 + 2*k2*n2; double r_Z = n2_Z*kk; // partial X inputX[0] = (f/Z)*(r + 2*normX*normX*kk); inputY[0] = f*normY*n2_X*kk; // partial Y inputX[1] = f*normX*n2_Y*kk; inputY[1] = (f/Z)*(r + 2*normY*normY*kk); // partial Z inputX[2] = f*normX*(r_Z - r/Z); inputY[2] = f*normY*(r_Z - r/Z); if (!computeIntrinsic || calibX == null || calibY == null) return; // partial f calibX[0] = r*normX; calibY[0] = r*normY; // partial k1 calibX[1] = f*normX*n2; calibY[1] = f*normY*n2; // partial k2 calibX[2] = f*normX*n2*n2; calibY[2] = f*normY*n2*n2; } @Override public int getIntrinsicCount() { return 3; } @Override public BundleAdjustmentCamera setTo( Map src ) { try { f = getOrThrow(src, "f"); k1 = getOrThrow(src, "k1"); k2 = getOrThrow(src, "k2"); return this; } catch (IOException e) { throw new UncheckedIOException(e); } } @Override public Map toMap() { var map = new HashMap(); map.put("type", TYPE_NAME); map.put("f", f); map.put("k1", k1); map.put("k2", k2); return map; } @Override public String toString() { FancyPrint fp = new FancyPrint(); return "BundlePinholeSimplified{" + "f=" + fp.s(f) + ", k1=" + fp.s(k1) + ", k2=" + fp.s(k2) + '}'; } public void reset() { k1 = k2 = f = 0.0; } public void setTo( BundlePinholeSimplified c ) { this.f = c.f; this.k1 = c.k1; this.k2 = c.k2; } public BundlePinholeSimplified copy() { return new BundlePinholeSimplified(f, k1, k2); } public boolean isIdentical( BundlePinholeSimplified c, double tol ) { if (Math.abs(f - c.f) > tol) return false; if (Math.abs(k1 - c.k1) > tol) return false; if (Math.abs(k2 - c.k2) > tol) return false; return true; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy