Migration¶
1.0 to 1.1¶
Version 1.1 is source compatible with 1.0, but a few behaviours changed for camera streams and metadata.
Camera stream timeouts¶
A camera stream read that waits longer than wait_timeout now raises
TimeoutError instead of ending the stream as if no more frames would arrive. The default timeout is 3 s.
Iterating over a stream stops it on a timeout, while get_frame() leaves the stream
running so the call can be retried.
Code that treated an early end of the stream as “the camera stopped” should catch TimeoutError instead:
from qtec_hv_sdk import control
cam = control.Camera("<camera_ip>")
try:
for meta, frame in cam.to_hs_image().stream():
...
except TimeoutError:
print("The camera stopped delivering frames")
Camera stream buffering¶
In 1.0 the frame queue between the camera and the consumer was unbounded, so a slow consumer grew memory without
limit. Camera streams now buffer 20 frames and stall the camera when the buffer is full. Frames the camera drops while
stalled are reported in hs.FrameMeta.dropped, and counted by dropped().
Behaviour is unchanged when the consumer keeps up.
Buffering is configured on the camera with a hs.control.StreamOptions in
stream_options, and applies to streams started afterwards. Use on_full="evict" to
discard the oldest buffered frame instead of stalling the camera:
import datetime
from qtec_hv_sdk import control
cam = control.Camera("<camera_ip>")
cam.stream_options = control.StreamOptions(
capacity=50,
on_full="evict",
wait_timeout=datetime.timedelta(seconds=5),
)
Measurement units¶
Camera images now report hs.RadiometricMeta.unit as hs.MeasurementUnit.Dn instead of
hs.MeasurementUnit.Raw, and set hs.DataProductsMeta.output_data to
hs.OutputDataType.RawData. Code comparing the unit to Raw should check for
Dn instead.
ENVI files written from a camera therefore contain measurement units = DN, which 1.0 readers do not recognise.
hs.MeasurementUnit.Raw, hs.MeasurementUnit.Absorbance and hs.MeasurementUnit.Arbitrary are
deprecated, and assigning them to hs.RadiometricMeta.unit or hs.MeasurementInfo.unit raises a
DeprecationWarning:
Replace
RawwithDn, and set the processing level separately withhs.OutputDataType.RawData.Replace
AbsorbanceandArbitrarywithhs.MeasurementUnit.Unknown, and record the unit in the extra metadata.
Existing files using these units still load.
import qtec_hv_sdk as hs
meta = img.meta
meta.radiometric = hs.RadiometricMeta(unit=hs.MeasurementUnit.Dn)
meta.data_products = hs.DataProductsMeta(output_data=hs.OutputDataType.RawData)
Scale factor¶
hs.RadiometricMeta.scaling is deprecated in favour of hs.EncodingMeta.scale_factor:
# 1.0
scale = img.meta.radiometric.scaling
# 1.1
scale = img.meta.encoding.scale_factor
The ENVI reader still accepts the old measurement scaling key. The writer stores the value under the
reflectance scale factor key, so a header written by 1.1 stores it under a different key than 1.0 did.
ENVI metadata¶
The ENVI reader and writer now handle all metadata fields. In 1.0, many standard ENVI fields were only available
through the extra metadata, and some were lost when writing. Code that read standard fields with
hs.ImageMeta.extra() should use the corresponding typed metadata field instead.
0.10.2 to 1.0.0¶
Version 1.0.0 renames several public Python and C APIs to remove the
redundant HS and HSI prefixes and to make camera and stage-control
APIs explicit. Most image processing code keeps the same lazy execution model:
build pipelines first, then evaluate them with operations such as
hs.Image.to_numpy(), hs.Image.resolve(),
hs.Image.stream(), or hs.write().
Python package and type names¶
The Python package was imported as hsi in 0.10.2. It is now imported as qtec_hv_sdk:
# 0.10.2
import hsi
# 1.0.0
import qtec_hv_sdk as hs
img = hs.open("input.hdr")
result = img.ensure_dtype(hs.float32).to_numpy()
The v1 names are shorter and match the current documentation.
0.10.2 name |
1.0.0 name |
Notes |
|---|---|---|
|
Main image and pipeline type. |
|
|
In-memory image data. |
|
|
File-backed image data. |
|
|
Metadata now groups fields by topic, see Metadata. |
|
|
Now exposed from the control submodule. |
|
|
Now exposed from the control submodule. |
|
|
Now exposed from the control submodule. |
The old names are not available in 1.0.0, so imports and type annotations have to be updated.
Removed and added Python APIs¶
The write_header function was removed. Metadata should be carried by the
image object and written together with image data through hs.write().
Images now expose a deterministic structural UUID for pipeline nodes through
the hs.Image.uuid property:
import qtec_hv_sdk as hs
img = hs.open("input.hdr")
print(img.uuid)
The Python package also ships with .pyi type stubs. Type checkers and
editors can use these stubs to find old imports, old type names, and calls to
removed functions during migration.
Camera and stage control¶
Camera and stage APIs now live in the control submodule. Import the submodule from the package, since
qtec_hv_sdk.control cannot be imported directly:
# 0.10.2
from hsi import HSCamera, StageController
cam = HSCamera("<camera_ip>")
stage = StageController("<camera_ip>")
# 1.0.0
from qtec_hv_sdk import control
cam = control.Camera("<camera_ip>")
stage = control.StageController("<camera_ip>")
The stage-controller lens-size helper has been replaced by explicit optical parameters:
from qtec_hv_sdk import control
stage = control.StageController("<camera_ip>", fps=30.0, distance=150.0)
stage.focal_length = 12.0 # mm
stage.object_distance = 258.0 # mm
stage.pixel_pitch = 5.0 # um
stage.slit_width = 20.0 # um
These values are used to derive the pixel and slit field of view used by the stage controller. Code that relied on the old lens-size helper should set the explicit optical parameters instead.
Errors¶
Python code receives standard Python exceptions: ValueError for invalid input and processing errors,
IOError for camera and scanner errors such as a camera that cannot be found, and TimeoutError for
camera timeouts.
In Rust, the error types were renamed: HSIError is now Error, and CameraError is now ControlError to
cover both camera and stage failures. Missing camera controls report the ControlNotFound variant.
C FFI names¶
The C API follows the same v1 naming cleanup. Update public image and metadata types and function prefixes:
0.10.2 C API |
1.0.0 C API |
|---|---|
|
|
|
|
|
|
|
|
The v1 metadata struct groups public metadata fields by topic, including
camera, spectral, spatial, radiometric, temporal, calibration, sensor,
encoding, and display metadata. See the C metadata reference for the current
hv_image_meta_t layout.
Metadata¶
The image metadata is now read with hs.Image.meta instead of img.header, and its type is
hs.ImageMeta.
It keeps core shape and layout information directly and groups richer metadata into focused objects.
# 0.10.2
header = img.header
wavelengths = header.wavelength_info
byte_order = header.byte_order
# 1.0.0
meta = img.meta
wavelengths = meta.spectral.wavelengths
byte_order = meta.encoding.byte_order
The legacy accessors byte_order, capture,
default_bands, measurement_info and
wavelength_info are still available on hs.ImageMeta for older code. Prefer the grouped
metadata objects, such as spectral and encoding, in new code.
Versioned documentation¶
The documentation is now built for both current and previous SDK versions. Keep the 0.10.2 documentation available while migrating if you need to compare old examples with the v1 API.