Highlights
Fifth beta of NCore 20, deriving the validity of OpenCV pinhole projections from the camera's radial distortion instead of fixed limits, and adding write APIs to the storage package. Install with pip install --pre nvidia-ncore or nvidia-ncore==20.0.0b5. Compared to NCore 19.8, see the beta.4 release notes and the earlier pre-releases they link.
OpenCV pinhole projection validity (since beta.4)
OpenCVPinholeCameraModelpreviously invalidated rays whose rational radial distortion factordwas outside fixed limits(0.8, 1.2). These stand in for the distorted radiusr d(r)no longer being one-to-one inr, but don't follow from the coefficients: they rejected valid rays in the periphery of cameras with strong barrel distortion, cut off pincushion distortions, and could accept rays beyond the distortion's extremum.- Valid rays are now bounded by the first extremum of the distorted radius (or a pole of
d), derived from the radial coefficients by the new static methodOpenCVPinholeCameraModel.compute_max_normalized_radius_squared(radial_coeffs)(numpy only, also usable by other implementations of the model). Projections and unprojections of rays beyond it are invalid. - The new constructor argument
max_normalized_radius_squared(defaultNone: derived;math.inf: no bound) overrides the bound. It is a setting of the model instance, not part of the camera model parameters, so stored data is unchanged. Distortion-free models keep projecting like ideal pinholes. - Tangential and thin-prism distortions are not taken into account (as before).
Storage write and read APIs (since beta.4, ncore.data.stores)
All of them work the same with zarr-python 2 and 3 and both zarr formats, and write records byte-identical to Group.create_array.
Array.read(selection, *, out=None)/read_async(..., *, out=None)read into a preallocated buffer and return it (validated before any read: dtype and shape of the selection, C-contiguous, writeable). zarr-python 3 direct reads decode the chunks straight intoout.Group.create_empty_array(name, *, shape, dtype, chunks, compression, fill_value=None, attributes)creates an array with an explicit chunk grid and no stored chunks, written byArray.write(selection, data)(basic selections). Chunks never written are not stored and read as the fill value (default: the onecreate_arraywrites for the dtype). Indexed tar archives are write-once per chunk: rewrites raise the newRecordExistsError(aValueError).EncodedArray.encode(data, *, dtype, chunks="single", compression, zarr_format=2)encodes the chunk records of an array without a store (safe on worker threads, e.g. to compress the arrays of a group in parallel), stored byGroup.create_encoded_array(name, encoded, *, attributes).Store.open_root_group(consolidated="auto")opens from the consolidated metadata record if the store has one, and from the node metadata records otherwise (an index lookup for indexed tar archives).BloscCompression,EncodedArrayandRecordExistsErrorare exported fromncore.data.stores; fill values are typed asFillValue.
Upgrading from beta.4
- Valid flags of OpenCV pinhole projections change for rays between the former limits and the distortion's extremum (now valid) and for rays beyond the extremum but within the former limits (now invalid). Cameras with moderate distortion are typically unaffected within their images (e.g., no change for the Waymo camera of the tests); a camera with strong barrel distortion (
k1 = -0.1,f = 800 px, 1920x1280) gains valid rays in its periphery. Unprojections of image points whose rays lie beyond the extremum are invalid as well (previously only the convergence of the undistortion was checked). Passmax_normalized_radius_squaredto bound the rays explicitly. ncore.data.stores.is_consolidated_metadata_key(key)is nowStore.is_consolidated_metadata_key(key); the module-level function is removed.Store.open_root_group(consolidated=...)accepts onlyTrue,Falseand"auto"; other values, including integers andNone, raiseValueError(previously they were used for their truth value).- Writes through hierarchies opened for reading raise
ValueErrorwith both zarr-python versions: with zarr-python 3, hierarchies opened from consolidated metadata now use a read-only view of the store (as unconsolidated opens already did). Writable stores of types without read-only views raiseValueErrorwhen opened from consolidated metadata.
For upgrading from NCore 19.x, see the beta.3 release notes.
Changes since v20.0.0-beta.4
➕ Added
- (data) export BloscCompression and EncodedArray from ncore.data.stores (bb30302) - @janickm
- (data) open hierarchies from consolidated metadata if stored (f224965) - @janickm
- (data) create arrays from chunks encoded on other threads (8fc4f14) - @janickm
- (data) create fill-valued arrays and write selections of them (d4114e8) - @janickm
- (data) read arrays into preallocated output buffers (9dc561a) - @janickm
- BREAKING (sensors) derive the OpenCV pinhole projection validity from its radial distortion (ffad25e) - @janickm
🔄 Changed
All changes since v19.8.0
➕ Added
- (data) export BloscCompression and EncodedArray from ncore.data.stores (bb30302) - @janickm
- (data) open hierarchies from consolidated metadata if stored (f224965) - @janickm
- (data) create arrays from chunks encoded on other threads (8fc4f14) - @janickm
- (data) create fill-valued arrays and write selections of them (d4114e8) - @janickm
- (data) read arrays into preallocated output buffers (9dc561a) - @janickm
- BREAKING (sensors) derive the OpenCV pinhole projection validity from its radial distortion (ffad25e) - @janickm
- (sensors) add FTheta tangential distortion coefficients (b7a158d) - @janickm
- public storage and geometry packages, ray validity helpers (bcd3e49) - @janickm
- BREAKING (sensors) return validity flags from structured lidar ray generation (05e6e86) - @janickm
- BREAKING (sensors) return validity flags from camera ray generation (e1b44a8) - @janickm
- (data) open sequences asynchronously (dfe3729) - @janickm
- (data) asynchronous reads of SequenceLoaderV4 (d49ca46) - @janickm
- (data) asynchronous compat protocols (d97b7ce) - @janickm
- (data) range reads of remote archives for synchronous reads (1880cb6) - @janickm
- (data) asynchronous component reader API (f67caa3) - @janickm
- BREAKING (data) zarr format v3 stores (c5fce26) - @janickm
- BREAKING (data) support zarr-python 3 (2cee604) - @janickm
- BREAKING (data) typed node API for component groups (ff2eeb0) - @janickm
🪲 Fixed
- (sensors) keep projection valid indices 1-D for single valid points (b47c5a0) - @nlucas-nvidia
- (sensors) apply the converged Newton step in the bracketed fisheye inverse (16d2f65) - @janickm
- (sensors) bracket the OpenCV fisheye inverse to the monotonic branch (71a0602) - @janickm
- (data) read single poses with their stored dtype (1de0192) - @janickm
- type narrowing in ncore_export_ply and the argoverse2 converter test (348262a) - @janickm
- (kitti) keep lidar point timestamps integer (5bf8f9f) - @janickm
⚡ Performance
- (geometry) add an interpolated motion compensation method (84d965b) - @janickm
- (sensors) skip zero tangential and thin-prism terms in OpenCV pinhole (2419967) - @janickm
- (sensors) skip identity linear term in FTheta camera model (1c0c1bf) - @janickm
- (data) release index tail reads of opened archives (10c2609) - @janickm
- (data) open remote indexed tar archives with a single request (f57784c) - @janickm
- (data) direct chunk reads with zarr-python 3 (979882a) - @janickm
- (data) node cache for component readers (0d6c43d) - @janickm
- (data) cache decoded label types and schemas in CameraLabelDescriptor.from_dict (1813046) - @janickm
- (data) load label and point-cloud reader data on first use (fe6eaf2) - @janickm
🔄 Changed
- BREAKING (data) move is_consolidated_metadata_key to Store (5175459) - @janickm
- (sensors) construct sensor return types through their defining class (e7c26c3) - @janickm
- (data) restructure IndexedTarArchive (fd9a4f0) - @janickm
- BREAKING (data) implement IndexedTarArchive independently of zarr-python (cd3078f) - @janickm
📚 Documentation
- remove retired skill provenance (e0e7609) - @sanchitgarg
⚙️ CI
- release notes tool in Python, commit check in build-and-test (069aee8) - @janickm
- separate the changes since the previous pre-release in release notes (3c48a54) - @janickm
- publish the documentation built by build-and-test (ed2d016) - @janickm
- refresh the Bazel disk cache on every push (09a3665) - @janickm
- remove merge queue triggers (3f52089) - @janickm
- write release notes into the release commit body (ccc650a) - @janickm
- release from main and release branches when the version changes (e8aba41) - @janickm
🏗️ Build
- pinned cocogitto via rules_multitool (e5ca2c9) - @janickm
- don't compress the repacked patched torch wheel (dc91c12) - @janickm
- add python 3.12 / 3.13 test environments (5b5fc02) - @janickm
🎨 Style
🔧 Chore
🧪 Tests
- (sensors) check camera ray valid flags in the unprojection tests (22db77d) - @janickm
- (sensors) share the lidar model between tests of a parameterization (c490c63) - @janickm
- run tests with a single OpenMP thread (2d4263f) - @janickm
- make tests independent of scipy / numpy versions (f2d59b0) - @janickm
Changes since v20.0.0-beta.4: v20.0.0-beta.4...v20.0.0-beta.5
Full diff: v19.8.0...v20.0.0-beta.5