Skip to content

sleap-io v0.2.0

Latest
Compare
Choose a tag to compare
@talmo talmo released this 04 Nov 22:53
· 1 commit to main since this release
53c1062

What's Changed

  • Update backend filename when backend isn't created on replace by @talmo in #127
  • Update labels videos list on replace by @talmo in #128
  • Add video writing by @talmo in #129
    • Add sio.VideoWriter: basic imageio-ffmpeg video writer with sensible H264 presets. This can be used as a context manager:
      with sio.VideoWriter("video.mp4") as vw:
          for frame in video:
              vw(frame)
    • Add sio.save_video: high-level video writing. This can be used to quickly write a set of frames or even a whole Video for easy (if inefficient) re-encoding:
      bad_video = sio.load_video("unseekable.avi")
      sio.save_video(bad_video, "seekable.mp4")
    • Added IndexError in VideoBackend to enable sequence protocol for iteration over Videos:
      for frame in video:
          pass
    • Refactored sio.io.video to sio.io.video_reading.
  • Fixes to get JABS export to work with new data by @talmo in #132
  • Make skeleton nodes mutable by @talmo in #135
  • Add skeleton manipulation utilities by @talmo in #136
    • Skeleton
      • __contains__(node: NodeOrIndex): Returns True if a node exists in the skeleton.
      • rebuild_cache(): Method allowing explicit regeneration of the caching attributes from the nodes.
      • Caching attributes are now named _name_to_node_cache and _node_to_ind_cache, better reflecting the mapping directionality.
      • require_node(node: NodeOrIndex, add_missing: bool = True): Returns a Node given a Node, int or str. If add_missing is True, the node is added or created, otherwise an IndexError is raised. This is helpful for flexibly converting between node representations with convenient existence handling.
      • add_nodes(list[Node | str]): Convenience method to add a list of nodes.
      • add_edges(edges: list[Edge | tuple[NodeOrIndex, NodeOrIndex]]): Convenience method to add a list of edges.
      • rename_nodes(name_map: dict[NodeOrIndex, str] | list[str]): Method to rename nodes either by specifying a potentially partial mapping from node(s) to new name(s), or a list of new names. Handles updating both the Node.name attributes and the cache.
      • rename_node(old_name: NodeOrIndex, new_name: str): Shorter syntax for renaming a single node.
      • remove_nodes(nodes: list[NodeOrIndex]): Method for removing nodes from the skeleton and updating caches. Does NOT update corresponding instances.
      • remove_node(node: NodeOrIndex): Shorter syntax for removing a single node.
      • reorder_nodes(new_order: list[NodeOrIndex]): Method for setting the order of the nodes within the skeleton with cache updating. Does NOT update corresponding instances.
    • Instance/PredictedInstance
      • update_skeleton(): Updates the points attribute on the instance to reflect changes in the associated skeleton (removed nodes and reordering). This is called internally after updating the skeleton from the Labels level, but also exposed for more complex data manipulation workflows.
      • replace_skeleton(new_skeleton: Skeleton, node_map: dict[NodeOrIndex, NodeOrIndex] | None = None, rev_node_map: dict[NodeOrIndex, NodeOrIndex] | None = None): Method to replace the skeleton on the instance with optional capability to specify a node mapping so that data stored in the points attribute is retained and associated with the right nodes in the new skeleton. Mapping is specified in node_map from old to new nodes and defaults to mapping between node objects with the same name. rev_node_map maps new nodes to old nodes and is used internally when calling from the Labels level as it bypasses validation.
    • Labels
      • instances: Convenience property that returns a generator that loops over all labeled frames and returns all instances. This can be lazily iterated over without having to construct a huge list of all the instances.
      • rename_nodes(name_map: dict[NodeOrIndex, str] | list[str], skeleton: Skeleton | None = None): Method to rename nodes in a specified skeleton within the labels.
      • remove_nodes(nodes: list[NodeOrIndex], skeleton: Skeleton | None = None): Method to remove nodes in a specified skeleton within the labels. This also updates all instances associated with the skeleton, removing point data for the removed nodes.
      • reorder_nodes(new_order: list[NodeOrIndex], skeleton: Skeleton | None = None): Method to reorder nodes in a specified skeleton within the labels. This also updates all instances associated with the skeleton, reordering point data for the nodes.
      • replace_skeleton(new_skeleton: Skeleton, old_skeleton: Skeleton | None = None, node_map: dict[NodeOrIndex, NodeOrIndex] | None = None): Method to replace a skeleton entirely within the labels, updating all instances associated with the old skeleton to use the new skeleton, optionally with node remapping to retain previous point data.
  • Add more checks for video seeking/reading failure by @talmo in #138
  • Fix HDF5Video edge cases by @talmo in #137
  • Docs changelog generation by @talmo in #130
  • Add Labels.extract, Labels.trim and Video.save by @talmo in #140
    • LabeledFrame.frame_idx: Now always converted to int type.
    • Video.close(): Now caches backend metadata to Video.backend_metadata to persist metadata on close.
    • copy.deepcopy() now works on Video objects even if backend is open.
    • Video.save(save_path: str | Path, frame_inds: list[int] | np.ndarray | None = None, video_kwargs: dict[str, Any] | None = None): Method to save a video file to an MP4 using VideoWriter with an optional subset of frames.
    • Labels.extract(inds: list[int] | list[tuple[Video, int]] | np.ndarray, copy: bool = True): Add method to extract a subset of frames from the labels, optionally making a copy, and return a new Labels object.
    • Labels.trim(save_path: str | Path, frame_inds: list[int] | np.ndarray, video: Video | int | None = None, video_kwargs: dict[str, Any] | None = None): Add method to extract a subset of the labels, write a video clip with the extracted friends, and adjust frame indices to match the clip.
  • Docs automation by @talmo in #141
  • Add more examples to docs by @talmo in #142

Full Changelog: v0.1.10...v0.2.0