2828import org .opencv .core .MatOfPoint2f ;
2929
3030public class MrCalJNI {
31+ public static enum CameraLensModel {
32+ LENSMODEL_OPENCV5 ,
33+ LENSMODEL_OPENCV8 ,
34+ LENSMODEL_STEREOGRAPHIC ,
35+ LENSMODEL_SPLINED_STEREOGRAPHIC ;
36+ }
37+
3138 public static class MrCalResult {
3239 public boolean success ;
3340 public double [] intrinsics ;
@@ -121,6 +128,29 @@ public String toString() {
121128 }
122129 }
123130
131+ /**
132+ * Performs camera calibration using [mrcal](https://mrcal.secretsauce.net/formulation.html)
133+ *
134+ * @param observations_board a packed double array containing all observations across all frames.
135+ * The array is structured as a flattened list where each observation consists of 3
136+ * consecutive doubles: [x, y, level] for each corner of each board in each frame. Structure:
137+ * For N frames, each observing a boardWidth×boardHeight checkerboard, the array has length N
138+ * × boardWidth × boardHeight × 3. The level value (0-based) represents detection quality and
139+ * will be converted to a weight using weight = 0.5^level. A negative level indicates the
140+ * corner was not detected (will be marked as an outlier).
141+ * @param boardWidth the number of internal corners in the horizontal direction of the calibration
142+ * board
143+ * @param boardHeight the number of internal corners in the vertical direction of the calibration
144+ * board
145+ * @param boardSpacing the physical distance (in arbitrary but consistent units) between adjacent
146+ * corners on the calibration board. PhotonVision uses meters.
147+ * @param imageWidth the width in pixels of the images used for calibration
148+ * @param imageHeight the height in pixels of the images used for calibration
149+ * @param focalLen an initial guess for the focal length in pixels, used to seed the optimization
150+ * @return an {@link MrCalResult} object containing the calibration results, including optimized
151+ * intrinsics, board poses, RMS error, per-observation residuals, detected outliers, and a
152+ * boolean mask indicating which corners were actually used in the final optimization
153+ */
124154 public static native MrCalResult mrcal_calibrate_camera (
125155 double [] observations_board ,
126156 int boardWidth ,
@@ -130,8 +160,34 @@ public static native MrCalResult mrcal_calibrate_camera(
130160 int imageHeight ,
131161 double focalLen );
132162
163+ /**
164+ * Applies mrcal lens distortion correction to undistort pixel coordinates.
165+ *
166+ * <p>This method takes distorted pixel coordinates and applies the inverse of mrcal's lens
167+ * distortion model to produce undistorted (corrected) coordinates. The input coordinates are
168+ * unprojected through the specified lens model to 3D ray vectors, then reprojected through a
169+ * pinhole model.
170+ *
171+ * @param dstMat a pointer to a cv::Mat containing distorted pixel coordinates (passed as a long
172+ * representing the memory address). Must be a CV_64FC2 continuous matrix where each row
173+ * contains one (x, y) coordinate pair. The matrix is modified in-place with the undistorted
174+ * coordinates as output.
175+ * @param cameraMat a pointer to the camera calibration matrix cv::Mat (3×3, opencv format).
176+ * @param distCoeffsMat a pointer to the distortion coefficients cv::Mat. The interpretation of
177+ * these coefficients depends on the specified lens model.
178+ * @param lensModelOrdinal the ordinal value of the {@link CameraLensModel} enum indicating which
179+ * lens distortion model to use for undistortion
180+ * @param order the spline interpolation order to use when warping pixels, if the lensmodel is
181+ * splined. Unused otherwise
182+ * @param Nx the number of control points in the x-direction for the distortion spline model.
183+ * Unused otherwise
184+ * @param Ny the number of control points in the y-direction for the distortion spline model.
185+ * Unused otherwise
186+ * @param fov_x_deg the horizontal field of view in degrees used for certain lens model, if
187+ * splined. Unused otherwise calculations
188+ * @return true if the undistortion was successful, false otherwise
189+ */
133190 public static native boolean undistort_mrcal (
134- long srcMat ,
135191 long dstMat ,
136192 long cameraMat ,
137193 long distCoeffsMat ,
@@ -141,6 +197,44 @@ public static native boolean undistort_mrcal(
141197 int Ny ,
142198 int fov_x_deg );
143199
200+ /**
201+ * Computes projection uncertainty for camera calibration across a grid of image points.
202+ *
203+ * <p>This method evaluates the uncertainty in 3D point projection due to calibration error. It
204+ * computes uncertainty at a regular grid of points across the image plane.
205+ *
206+ * @param observations_board a packed double array containing calibration observations with the
207+ * same structure as used in {@link #mrcal_calibrate_camera}. For N frames observing a
208+ * boardWidth×boardHeight checkerboard, the array has length N × boardWidth × boardHeight × 3,
209+ * where each triplet is [x, y, level].
210+ * @param intrinsics a double array containing the camera intrinsic parameters. The exact content
211+ * and length depend on the lens distortion model being used, but typically includes focal
212+ * length, principal point, and distortion coefficients.
213+ * @param rt_ref_frames a packed double array containing the poses (rotations and translations) of
214+ * the calibration board relative to the camera for each frame. The array is structured as N
215+ * consecutive 6-element groups, where each group represents one frame's pose: [rx, ry, rz,
216+ * tx, ty, tz]. The rotation components (rx, ry, rz) form a rotation vector (axis-angle
217+ * representation), and (tx, ty, tz) represent the translation. Total array length is N × 6,
218+ * where N is the number of observed frames.
219+ * @param boardWidth the number of internal corners in the horizontal direction of the calibration
220+ * board
221+ * @param boardHeight the number of internal corners in the vertical direction of the calibration
222+ * board
223+ * @param boardSpacing the physical distance between adjacent corners on the calibration board
224+ * (must match the value used in calibration). PhotonVision uses meters.
225+ * @param imageWidth the width in pixels of the camera imager at this particular VideoMode
226+ * @param imageHeight the height in pixels of the camera imager at this particular VideoMode
227+ * @param sampleGridWidth the number of sample points in the horizontal direction for uncertainty
228+ * computation
229+ * @param sampleGridHeight the number of sample points in the vertical direction for uncertainty
230+ * computation
231+ * @param warpX the x-component of lens distortion warp, or zero if no warp was estimated.
232+ * @param warpY the y-component of lens distortion warp
233+ * @return a packed double array containing uncertainty values at each sampled grid point. The
234+ * array is structured as a sequence of 3D points (mrcal_point3_t), representing [u, v,
235+ * uncertainty] for each point we sampled. Total array length is sampleGridWidth ×
236+ * sampleGridHeight × 3. Returns null if computation fails.
237+ */
144238 public static native double [] compute_uncertainty (
145239 double [] observations_board ,
146240 double [] intrinsics ,
@@ -155,7 +249,14 @@ public static native double[] compute_uncertainty(
155249 double warpX ,
156250 double warpY );
157251
158- public static double [] makeObservations (
252+ /**
253+ * Convert a list of board-pixel-corners and detection levels for each snapshot of a chessboard
254+ * boardWidth x boardHeight to a packed double[] suitable to pass to
255+ * MrCalJni::mrcal_calibrate_camera. Levels will be converted to weights using weight = 0.5^level,
256+ * as explained
257+ * [here](https://github.com/dkogan/mrcal/blob/7cd9ac4c854a4b244a35f554c9ebd0464d59e9ff/mrcal-calibrate-cameras#L152)
258+ */
259+ private static double [] makeObservations (
159260 List <MatOfPoint2f > board_corners ,
160261 List <MatOfFloat > board_corner_levels ,
161262 int boardWidth ,
@@ -192,6 +293,23 @@ public static double[] makeObservations(
192293 return observations ;
193294 }
194295
296+ /**
297+ * High-level wrapper for camera calibration using mrcal.
298+ *
299+ * <p>Converts detected chessboard corners and their detection levels into a packed double array,
300+ * then calls {@link #mrcal_calibrate_camera} to perform calibration. Each corner's detection
301+ * level is converted to a weight (0.5^level), and negative levels indicate undetected corners.
302+ *
303+ * @param board_corners List of detected chessboard corners for each frame
304+ * @param board_corner_levels List of detection levels for each corner in each frame. Point weight is calculated as weight = 0.5^level. Negative weight will ignore this observation
305+ * @param boardWidth Number of internal corners horizontally
306+ * @param boardHeight Number of internal corners vertically
307+ * @param boardSpacing Physical spacing between corners (meters)
308+ * @param imageWidth Image width in pixels
309+ * @param imageHeight Image height in pixels
310+ * @param focalLen Initial guess for focal length (pixels)
311+ * @return Calibration result with optimized intrinsics, poses, and error metrics
312+ */
195313 public static MrCalResult calibrateCamera (
196314 List <MatOfPoint2f > board_corners ,
197315 List <MatOfFloat > board_corner_levels ,
0 commit comments