7. API reference¶
Everything below is importable from nanofractal (import nanofractal as nf).
FractalDetector¶
FractalDetector(config, marker_size=-1.0, params=None)
config—"FRACTAL_2L_6","FRACTAL_3L_6","FRACTAL_4L_6"or"FRACTAL_5L_6"; anything else raisesValueError.marker_size— side of the external marker's black square in your length unit; needed for a metric pose (-1: no scale).params— aDetectorParams(copied; read and change it via.params).
| method | returns |
|---|---|
detect(image, with_inner_points=False, roi=None, all_instances=False, prior=None) |
DetectionResult; with all_instances=True every copy of the marker, see instances; prior = the last detection, see Video |
diagnose(image, roi=None) |
Diagnosis(result, n_contours, n_not_quad, quads, second_pass) — see Troubleshooting |
detect_batch(images, num_threads=0, roi=None) |
list[DetectionResult] (no inner points, no prior; cell_px / contrast / bit_errors are None) |
estimate_pose(result, camera_matrix, dist_coeffs, fisheye=False, full=False) |
(rvec, tvec, reproj_err), a Pose with full=True, or None |
draw(image, result, camera_matrix=None, dist_coeffs=None, rvec=None, tvec=None, axis_length=None, inplace=True) |
the image drawn on |
image:uint8C-contiguous(H,W),(H,W,1)or(H,W,3)BGR.roi:(x, y, width, height)inside the image; results are in full-image coordinates.prior: aDetectionResultof this marker from a moment ago (full-image coordinates); quads where its levels were are read with a few wrong cells allowed (grids of 10+ cells). Used for this call only.expected_side_px:(lo, hi), the outer level's side in pixels (from the height); quads of a level's expected size are read with a looser tolerance, andres.lookalikeslistsLookalike(corners, centre, level, border_errors, bit_errors, contrast)for those that still do not read (Nonewithout the hint). See Video.num_threads=0: all cores.estimate_pose:camera_matrix3×3,dist_coeffsof length 4/5/8/12/14 (exactly 4 withfisheye=True); uses inner points when the result has ≥ 4, else the outer corners of every detected level; one outlier pass with ≥ 8 points;full=TruereturnsPose(rvec, tvec, reproj_err, method, n_points, n_inliers, reproj_err_rel, cov, rvec_alt, tvec_alt, reproj_err_alt); propertiessd_tvec,sd_t,sd_rot_degfromcov.drawneeds a writable contiguous image wheninplace=True;axis_lengthdefaults to halfmarker_size.
Attributes: config, marker_size, params.
FractalTracker¶
FractalTracker(detector, margin=0.25, pad=16, auto_scale=False, scale_target_px=400, use_prior=False, prior_max_age=5, capture_frames=0)
auto_scale=True shrinks the searched region (detection_scale, 1 down to
0.35) so the largest level of the previous frame is about scale_target_px
wide; only when the detector's own detection_scale is 1. use_prior=True
passes the last non-empty result (at most prior_max_age frames old) as
prior to detect. capture_frames=N (0 = off, else ≥ 2; implies
use_prior): while there is no track, a quad within that tolerance of a
level's code that stays in place for N - 1 frames is read with it as
prior in the next one, see
Video.
| member | |
|---|---|
detect(image, with_inner_points=False, expected_side_px=None) |
like detector.detect, searching near the previous result |
reset() |
forget the previous result |
full_frame_detections |
how many frames needed a whole-frame search |
DetectionResult¶
| attribute | type |
|---|---|
ids |
int32 (N,) — level ids, 0 = external |
corners |
float32 (N, 4, 2) — marker TL, TR, BR, BL in pixels |
points_2d |
float32 (M, 2) or None — inner+outer image points |
points_3d |
float32 (M, 3) or None — matching marker points, z = 0 |
points_level |
int32 (M,) or None — level id of each point |
instances |
int32 (N,) or None — copy of each level (all_instances=True; 0 = the largest copy) |
points_instance |
int32 (M,) or None — copy of each inner point |
multiple_instances |
bool — a level was seen in two separate places (two copies of the marker); only the largest of each level is returned |
inconsistent_ids |
int32 (K,) — levels dropped because they are not where the other levels put them |
cell_px |
float32 (N,) — pixels per cell of each level |
contrast |
float32 (N,) — mean bright minus mean dark cell, grey levels |
bit_errors |
int32 (N,) — cells read wrong; > 0 only for levels accepted through prior |
len(r), bool(r), for level_id, corners in r, readable repr;
r.n_instances, r.instance(k) (copy k as its own DetectionResult).
estimate_pose refuses a result with several copies — pass r.instance(k).
Diagnosis¶
| attribute | type |
|---|---|
result |
the DetectionResult (same as detect) |
n_contours |
contours traced (at least min_contour_size long) |
n_not_quad |
of those, not a convex quadrilateral |
quads |
list[QuadInfo] |
second_pass |
True when the detection came from the second pass (params.close_pass); quads are then those of that pass |
QuadInfo(corners, reason, cells, nearest_id, border_errors, bit_errors,
contrast): corners float32 (4, 2) before sub-pixel refinement; reason
one of "accepted", "duplicate", "border", "bits", "inconsistent"; cells the grid
size (border included) and nearest_id the code it came closest to;
border_errors frame cells read white; bit_errors inner bits that differ
from nearest_id; contrast mean bright minus mean dark cell (grey levels).
DetectorParams¶
Fields min_contour_size, adaptive_block_size, adaptive_c,
approx_poly_rate, subpix_win_size, kfilter_min_dist,
detection_scale, close_pass — see Tuning.
Functions¶
| function | |
|---|---|
generate_fractal(config, size_px=400, nested=True) |
uint8 (size_px, size_px) marker image |
refine_corners(image, corners, win_size=5) |
float32 (N, 4, 2) refined corners |
set_num_threads(n) / get_num_threads() |
threads per detect() call (n <= 0: all cores) |
PoseSmoother(process_noise=1e-4, measurement_noise=1e-2, mode="kalman", gate=None, max_rejects=3) |
.update(rvec, tvec, t=None, reproj_err=None, n_points=None) -> (rvec, tvec), .reset(), .last_rejected; mode="ema" for a fixed gain |
nanofractal.__version__ is the package version.
Command line¶
python -m nanofractal.bench [--resolution WxH] [--scene clean|perspective|clutter]
[--mode detect|inner|scale05] [--config FRACTAL_5L_6] [--frames N]