Skip to main content
Version: 0.9.x [Latest Beta]

Changelog

0.9.0

See the Migration guide for an action-oriented checklist.

  • ConstTensorNode removed: Constant values are no longer provided by dedicated pipeline nodes. Set them on topics before initialize() instead.
    • Python: Pipeline.set_constant_value(topic, array) and Pipeline.remove_constant_value(topic) — constant topics must use the /port_name form (empty node name). Pipeline.get_constant_values() returns a dict[str, np.ndarray] of default constant values before initialization.
    • C: denkflow_pipeline_set_constant_value, denkflow_pipeline_remove_constant_value, and denkflow_pipeline_get_constant_values (returns DenkflowConstantValueArray with topic_name, tensor_type, shape, typed data buffer, and DenkflowArrayDataType; free with denkflow_constant_value_array_free).
    • Removed: Pipeline.add_const_tensor_node(...), denkflow_pipeline_add_const_tensor_node_int/uint/float, DenkflowConstTensorNodeReference.
  • get_topics_for_pipeline_input/output removed: Replaced by a unified topic inspection API that returns rich metadata.
    • Python: Pipeline.get_topics() → list of TopicDescription with topic_name, topic_type (ExternalInput, ExternalOutput, InternalConnection), tensor_type, and is_constant.
    • C: denkflow_initialized_pipeline_get_topicsDenkflowTopicDescriptionArray.
    • Removed: get_topics_for_pipeline_input(), get_topics_for_pipeline_output(), and their C-API equivalents.
  • Pipeline input and constant topic naming: .denkflow files exported from version 0.9.0 onward use an empty node_name for boundary inputs and constants — for example /image instead of camera/image, and /image_size or /iou_threshold for graph constants. Older exports may still use the previous node_name/port_name form; call get_topics() after initialize() to discover the correct names. For more information, see this example on runtime parameters on exported pipelines.
  • C data_type is now DenkflowArrayDataType: denkflow_base_tensor_from_buffer and denkflow_image_tensor_from_buffer take a DenkflowArrayDataType enum instead of a const char* dtype string. Build tensors with those helpers, then pass handles to denkflow_pipeline_set_constant_value or denkflow_initialized_pipeline_publish_tensor.
  • C publish unified: denkflow_initialized_pipeline_publish_image_tensor was replaced by denkflow_initialized_pipeline_publish_tensor, which accepts any tensor type via a void** handle (cast typed pointers such as DenkflowImageTensor**).
  • SegmentationObject renamed to Segmentation: Aligns with the BoundingBox naming pattern.
    • Python: denkflow.SegmentationObjectdenkflow.Segmentation
    • C: DenkflowSegmentationObjectDenkflowSegmentation; on DenkflowSegmentationBatchElement, segmentation_objectssegmentations (and _length)
  • PipelineWrapper: High-level inference on exported .denkflow graphs. Returns structured results in absolute pixel coordinates without manual subscribe/receive or tensor decoding.
    • Python: PipelineWrapper(pipeline), run(image_tensor, confidence_threshold=...)
    • C: denkflow_pipeline_wrapper_new, denkflow_pipeline_wrapper_run, denkflow_inference_results_free
    • Optional overrides when the graph exposes the constants: set_image_size, set_iou_threshold, set_score_threshold
  • Annotated images: Draw boxes, segmentations, and optional labels on the input image.
    • Python: ImageTensor.to_images_with_annotations(image_results, segmentation_fill_alpha=None, annotation_label_font_size=None, ...)
    • C: denkflow_image_tensor_to_images_with_inference_results (free the buffer with denkflow_image_buffer_free)
    • segmentation_fill_alpha: Python None or C 0.0 for outline segmentations; a value in (0, 1] fills at that opacity
    • annotation_label_font_size: Python None or C 0.0 to skip labels; otherwise a size relative to a 1080px-tall reference image
    • Example: Object detection with PipelineWrapper

0.8.0

See the Migration guide for an action-oriented checklist.

  • General changes:

    • New OCR Version: Added support for a new OCR version that uses a different decoding method.
    • Faster Image Conversion: Image conversion into the internal format should be much faster than before, but uses a different call structure (see below).
    • New BoundingBoxClassFilter node: Filter detection results down to a configurable allow-list of class indices.
      • C: denkflow_pipeline_add_bounding_box_class_filter_node
      • Python: Pipeline.add_bounding_box_class_filter_node(...)
    • Override the device of any node before initialization: Both exported .denkflow graphs and custom pipelines now support set_node_device / denkflow_pipeline_set_node_device to redirect a single node to a different execution provider before initialize() is called.
  • Breaking Changes:

    • Internal file format: Changes to *.denkmodel and *.denkflow files. Old files need to be re-exported.

    • C-API symbol prefix: All C-API functions, types, and global constants are now consistently namespaced to avoid collisions when integrating DENKflow alongside other shared libraries.

      • Functions are prefixed with denkflow_. For example, pipeline_new is now denkflow_pipeline_new, image_tensor_from_file is now denkflow_image_tensor_from_file, and so on.
      • Types are prefixed with Denkflow. For example, Pipeline is now DenkflowPipeline, ImageTensor is now DenkflowImageTensor, Point is now DenkflowPoint, Rect is now DenkflowRect, Receiver_Tensor is now DenkflowReceiverTensor, etc. Enum variants follow their type, e.g. DenkflowResizeMode_Stretch. DenkflowResult was already prefixed and is unchanged.
      • Global constants: ERROR_BUFFER_SIZE is now DENKFLOW_ERROR_BUFFER_SIZE; NULL_BYTE has been removed.
    • Optional C-API string arguments now accept NULL / nullptr: Functions that take an optional string (such as denkflow_hub_license_source_from_pat's endpoint) now follow the universal C convention and treat a NULL pointer as "argument absent". The previous workaround of passing a pointer to a single zero byte (NULL_BYTE) has been removed.

    • Unified resize mode for image resize and image patches: A single resize-mode enum (with variants CenterPadBlack, Stretch, CenterPadWhite) replaces the per-node enums in every binding. The new variant CenterPadWhite was added in this release.

      • C: DenkflowResizeMode is shared between denkflow_pipeline_add_image_resize_node and denkflow_pipeline_add_image_patches_node.
      • Python: Pipeline.add_image_resize_node, Pipeline.add_image_patches_node, and Pipeline.change_image_patches_node all take resize_mode as a string — one of "CenterPadBlack" (default), "Stretch", or "CenterPadWhite".
    • denkflow_pipeline_add_image_resize_node signature change: The bool keep_aspect_ratio parameter was replaced by DenkflowResizeMode resize_mode. The previous keep_aspect_ratio = true corresponds to DenkflowResizeMode_CenterPadBlack; keep_aspect_ratio = false corresponds to DenkflowResizeMode_Stretch.

    • Pipeline.add_image_resize_node signature change (Python): The keep_aspect_ratio: bool keyword argument was removed and replaced by resize_mode: str = "CenterPadBlack". Migrate keep_aspect_ratio=Trueresize_mode="CenterPadBlack" and keep_aspect_ratio=Falseresize_mode="Stretch".

    • Python device= keyword renamed to execution_provider=: All Python pipeline methods that previously accepted a device: str keyword (add_image_resize_node, add_object_detection_node, add_image_classification_node, add_bounding_box_filter_node, add_bounding_box_class_filter_node, add_image_patches_node, add_ocr_node, add_image_segmentation_node, add_image_instance_segmentation_node, add_image_anomaly_detection_node) now accept execution_provider: str instead, matching the C-API. The same applies to Pipeline.set_node_device(node_name, execution_provider, device_id). The device_id parameter is unchanged. Migrate device="cuda"execution_provider="cuda".

    • denkflow_pipeline_add_image_patches_node signature change: Two parameters were added between target_size_topic and execution_provider:

      • DenkflowResizeMode resize_mode (default in higher-level wrappers: CenterPadBlack)
      • DenkflowImagePatchesNodeResizeMethod resize_method (default: Bilinear; values Nearest, Bilinear, Bicubic, Area)

      In Python, Pipeline.add_image_patches_node and Pipeline.change_image_patches_node take resize_mode: str = "CenterPadBlack" (values "CenterPadBlack", "Stretch", "CenterPadWhite") and resize_method: str = "Bilinear" (values "Nearest", "Bilinear", "Bicubic", "Area"). The Python wrapper additionally exposes bounding_box_extend_ratio: float = 0.0.

    • New constructors for in-memory image tensors: The single old image_tensor_from_image_data / from_numpy family was replaced by a triple of constructors that make the data-conversion contract explicit. See Creating ImageTensors for the details.

      • C:
        • denkflow_image_tensor_from_buffer — generic constructor that accepts arbitrary data type, memory layout, and channel layout, and converts to the canonical inference format internally.
        • denkflow_image_tensor_from_buffer_raw — expects a buffer that is already BGR / BCHW / float32, performs no conversion but copies the buffer internally.
        • denkflow_image_tensor_from_buffer_unsafe — same input requirements as _raw, but does not copy the buffer; the caller must keep it alive (and untouched) until the pipeline run that consumes the tensor has returned.
        • The previous denkflow_image_tensor_from_image_data no longer exists.
      • Python:
        • ImageTensor.from_numpy — generic constructor that accepts arbitrary data type, memory layout, and channel layout, and converts to the canonical inference format internally.
        • ImageTensor.from_numpy_raw — expects a buffer that is already BGR / BCHW / float32, performs no conversion but copies the buffer internally.
        • ImageTensor.from_numpy_unsafe — same input requirements as _raw, but does not copy the buffer; the caller must keep it alive (and untouched) until the pipeline run that consumes the tensor has returned.
        • The previous ImageTensor.from_numpy_opencv(...) has been removed. Use from_numpy(..., memory_layout="HWC", channel_layout="BGR") instead.

0.7.0

  • General changes:
    • Super Sessions: Nodes are now automatically clustered by execution device in the background. This can improve performance in certain scenarios.
    • Customizable Channel Size: This allows for the creation of input data queues by publishing multiple times to the same topic.
    • Parallel Pipeline Runs: Added an alternative method to run a pipeline called start. This allows running the pipeline and publishing data in separate threads.
    • Add Nodes via C-API: The C-API now fully supports the addition of nodes to a pipeline.
  • Breaking Changes:
    • Subscribe / receive split: Previous versions had different subscribe_* methods for each tensor type but a single generic receive method. This was inverted: there is now a single subscribe(topic) method that returns a generic receiver, and the receiver exposes one typed receive_*_tensor() method per tensor type:

      • Python: receiver = pipeline.subscribe(topic)receiver.receive_bounding_box_tensor(), receiver.receive_image_tensor(), receiver.receive_scalar_tensor(), receiver.receive_ocr_tensor(), receiver.receive_segmentation_mask_tensor(), receiver.receive_instance_segmentation_mask_tensor().
      • C: denkflow_initialized_pipeline_subscribe(&receiver, initialized, topic)denkflow_receiver_receive_bounding_box_tensor(&tensor, receiver), etc.

      Calls to the old subscribe_bounding_box_tensor / subscribe_image_tensor / etc. methods no longer compile.

    • The C-API function denkflow_pipeline_from_denkflow now takes a single pointer to the license source instead of a double pointer.