webarkit / webarkit/jsfeatNext
feat(teblid): TEBLID binary descriptor module (p256, then p512)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 12
- Forks
- 4
- Avg merge
- 16h 24m
- Merged PRs (30d)
- 34
Description
Summary
Add src/teblid/teblid.ts — the TEBLID binary descriptor (Suárez et al.),
ported from OpenCV's xfeatures2d. Ship p256 first, then p512, in two pull
requests under this issue.
BEBLID is deliberately not included. See "Why not BEBLID" below.
Why
TEBLID is a learned binary descriptor built on box-average differences over an
integral image: each bit is a thresholded comparison of the mean grey level of
two square boxes, whose parameters are trained offline and baked into a table.
It is rotation-invariant through the detector's keypoint angle, arithmetic is
integer-only, and it consistently outperforms ORB/rBRIEF on matching accuracy at
comparable cost.
For jsfeatNext it is the single largest available quality step on the descriptor
side of the pipeline, and it is the descriptor #128 was designed to make
selectable.
Why not BEBLID
Verifying the upstream source: teblid.cpp does not exist. TEBLID is implemented
inside beblid.cpp as TEBLID_Impl, wrapping a BEBLID_Impl<ABWLParamsFloatTh>.
The two descriptors differ only in the weak-learner threshold type (integer vs
float) and in which trained tables are included.
Shipping both would mean four table sets (BEBLID and TEBLID × p256 and p512).
Extrapolating from src/orb/bit_pattern_31.ts — 18 KB of source for 2048
integers — that is roughly 100–130 KB of source added to a bundle currently at
57 KB (UMD) / 86 KB (ESM). Since the published benchmarks put TEBLID ahead of
BEBLID on both accuracy and speed, BEBLID would be carried purely for OpenCV API
symmetry.
Consequence for the implementation: with a single instantiation, the engine is
written concretely for TEBLID's float-threshold weak learner, not
generically over the weak-learner type as an earlier draft of this plan
proposed. If BEBLID is ever wanted, generalising is a mechanical refactor with
the tests already in place — which is the right moment to do it, not now.
Scope
rectifyABWL— affine transform of the box parameters from the keypoint's
position, scale and angle.computeABWLResponse— mean-grey difference between two square boxes,
evaluated on the integral image.- Threshold on the response → descriptor bit.
- Trained tables packed as base64, decoded once at module init into a typed
array. Roughly 55% smaller source and faster to parse than decimal array
literals. Honest caveat to record in the PR: after gzip this is close to a
wash, since small decimal integers compress very well and base64 does not — the
win is raw size and parse time, not transfer bytes. - Attached as
jsfeatNext.teblid.
imgproc.compute_integral_image already exists, so no enabling sub-issue is
needed — but see #131, which is a hard prerequisite:
the current implementation leaves the first column unwritten, and TEBLID reads
exactly that column for every box touching the left edge.
Two pull requests
- p256 (32 bytes, same width as ORB), plus the measured bundle delta
recorded in a comment on this issue. - p512 (64 bytes), once that number is known.
The split exists because the size estimate above is an extrapolation, not a
measurement. If the real number is worse than expected, it is discovered with
half the tables in and there is still freedom to act on it.
Acceptance criteria
- Descriptors bit-exact against OpenCV fixtures at both widths, computed
from the committed keypoint set (so a mismatch indicts the descriptor, not
the detector). - A test asserting known table entries after base64 decoding — otherwise the
packing becomes a blind spot where a corrupted table still "works". - Keypoints near all four image borders produce correct descriptors, or are
rejected explicitly. Silent contamination is the #110 failure mode and must
not be reintroduced. -
dist/size before and after recorded in this issue for both PRs. - Round-trips through
bfmatcherat 64 bytes per descriptor. - Shared-pool buffers balanced; no new
any(#85). - Covered by the API-shape test.
Out of scope
- BEBLID, and a generic engine over the weak-learner type.
- LATCH — evaluated and rejected: redundant against TEBLID, and roughly an order
of magnitude slower per keypoint. - Wiring into the
CvBackendadapter — see #136. - Bundle tree-shaking — see #137.
Dependencies
- #131 — integral-image first-column fix (hard).
- #132 — OpenCV ground-truth fixtures (hard).
- #130 — licence-header variant, since this is OpenCV-derived code (hard).
- #133 —
bfmatcher, for end-to-end matching tests only.
Related
- Descriptor selection contract: #128
- Sibling descriptor: #80 (FREAK)
- Plan:
docs/features2d-expansion-plan.md
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the prerequisites #131, #132, #130, and #133, then use src/teblid/teblid.ts and imgproc.compute_integral_image as the implementation entry points. Validate against the OpenCV fixtures at both widths, including border keypoints, table-decoding checks, API-shape coverage, bfmatcher round-trips, and recorded dist/size changes for p256 and p512.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- opencv, typescript
- Domain
- computer-vision
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100