Older Releases ============== 0.9.1 ----- - Fixed incompatibilities with numpy >= 2.0.0. - Fixed Visualizer (used in :meth:`~imfusion.show`) not using the dedicated GPU on Windows laptops. - Improved error messages when attempting to create :class:`~imfusion.MemImage`, :class:`~imfusion.SharedImage` or :class:`~imfusion.SharedImageSet` with unsupported numpy `dtypes`. **Breaking Changes:** - Fixed :class:`~imfusion.MemImage`/:class:`~imfusion.SharedImage`/:class:`~imfusion.SharedImageSet`'s :meth:`~imfusion.SharedImageSet.astype` such that `img.astype(type).numpy()` returns the same result as `img.numpy().astype(type)`. - :class:`~imfusion.MemImage` / :class:`~imfusion.SharedImage` / :class:`~imfusion.SharedImageSet`'s :meth:`~imfusion.SharedImageSet.astype` now always raises `TypeError` when receiving a numpy integer `dtype` with `itemsize > 4` (which was not the case on some platforms). 0.9.0 ----- - Fixed offline license activation and activation with proxy. Instructions are printed when the initial activation fails. - Global application settings are now saved in :code:`%APPDATA%\ImFusion\ImFusionLib\config.json` (Windows) or :code:`.config/ImFusion/ImFusionLib/config.json` (Linux) - Added :meth:`~imfusion.Data.world_to_image_matrix`, :meth:`~imfusion.Data.set_world_to_image_matrix`, :meth:`~imfusion.Data.world_from_image_matrix` and :meth:`~imfusion.Data.set_world_from_image_matrix`. - Added parameters to :class:`~imfusion.PointCloud` such that it can be constructed with points, colors and normals. - Added :attr:`~imfusion.PointCloud.normals` - Added :meth:`~imfusion.PointCloud.__len__`. - Fixed missing :attr:`~imfusion.DataComponent.id` property. - Added :meth:`~imfusion.show`, :meth:`~imfusion.close_viewers`, :meth:`~imfusion.list_viewers` and :class:`~imfusion.VisualizerHandle`. - Fixed interpreter crash when calling :meth:`~imfusion.SharedImageSet.descriptor` on an empty :class:`~imfusion.SharedImageSet`. - Changed/Fixed :meth:`~imfusion.Algorithm.configuration` which now accepts no arguments and returns the configuration instead of throwing an exception. - Fixed a runtime error when calling :meth:`~imfusion.save` with any :class:`~imfusion.Data` that was not a :class:`~imfusion.SharedImageSet`. - Fixed crashing :meth:`~imfusion.Annotation.on_points_changed` or :meth:`~imfusion.Annotation.on_editing_finished` when the set callback was raising an exception. - Fixed :class:`~imfusion.AlgorithmExecutionError` was not being correctly registered. - Added :class:`~imfusion.StringEnumParam` that can be assigned to :class:`~imfusion.Properties` to define a value among a list of string possibilities. **Breaking Changes:** - Changed API of :class:`~imfusion.reg.ImageRegistrationAlgorithm`: - Removed ``image1`` and ``image2`` properties. - Removed setters from ``moving`` and ``fixed`` properties. - Introduced new :meth:`~imfusion.reg.ImageRegistrationAlgorithm.swap_fixed_and_moving` method. - Removed ``image2_is_moving`` parameter from init and renamed ``image1``/``image2`` parameters to ``fixed``/``moving``. - Removed :code:`SharedImage.matrix` and :code:`SharedImageSet.matrix`. Use :code:`world_to_image_matrix` / :code:`world_to_image` instead. - Removed "copy constructor" from PointCloud and replaced it with :meth:`~imfusion.PointCloud.clone` and :meth:`~imfusion.PointCloud.__deepcopy__`. - :attr:`~imfusion.PointCloud.colors` and :attr:`~imfusion.PointCloud.normals` now raise a ``ValueError`` if the size of the passed in list does not match the stored points. It was returning ``False`` before. - Removed possibility to implicitly convert a numpy array to KeypointSet or BoundingBoxSet. - Fixed :class:`~imfusion.Properties` receiving a `dict` containing `None` was not raising a `TypeError` but it was doing an implicit type casting instead. 0.8.0 ----- - Added :attr:`SharedImage.world_to_image_matrix`, :attr:`SharedImage.image_to_world_matrix`, :meth:`SharedImage.world_to_image` and :meth:`SharedImage.image_to_world`. - Fixed discrepancy between configuration and attributes of PythonOperations constructed through :class:`~imfusion.machinelearning.OperationsSequence`. - Added repr for :class:`~imfusion.DatasetLicenseComponent`. - Fixed timing calculation when :class:`~imfusion.machinelearning.Dataset` is set to verbose. - Fixed verbosity setting in :class:`~imfusion.machinelearning.Dataset`. - Added new overloads for :meth:`~imfusion.machinelearning.Dataset.sample` and :meth:`~imfusion.machinelearning.Dataset.process` that directly accept Operations. - Added new arguments to ML Operations initializers that were previously only accessible through configure. - Removed bindings for ``Image``. Use :class:`~imfusion.ImageDescriptor` instead and :class:`~imfusion.PixelType` instead of ``Image.Type``. - Added min and max to :mod:`~imfusion.imagemath`. - Added bindings for imagemath module :mod:`~imfusion.imagemath` with the submodule :mod:`~imfusion.imagemath.lazy`. Some methods were also added to :class:`~imfusion.SharedImage` and :class:`~imfusion.SharedImageSet` besides :mod:`~imfusion.imagemath`. - Added basic bindings for :class:`.ImageRegistrationAlgorithm` and :class:`.RegistrationInitAlgorithm`. - Added function :meth:`~imfusion.open_in_suite` to start an ImFusion Suite instance with the provided data list. This method requires the ImFusion Suite executable to be installed and in the PATH. - Fixed a bug for which, after transferring logging to python, some logging was not occurring. - Fixed a bug for which the logging was directed to the stdout after transferring logging to python but before importing the logging module (which was not expected accordingly to the documentation). Hence, importing the imfusion python library does not implicitly import the python logging module anymore. Once the logging is imported after the call to transfer_logging_to_python, then the logs are directed to the stdout. - It is not possible anymore to revert the effect of transferring logging to python. - Fixed a bug for which assigning +/-sys.float_info.max value, or some close values to those, to :class:`Properties` was leading to a broken entry. - Support Properties params of type Path, by casting paths to or from pathlib.Path. - Fixed a :meth:`DataElement.clone` bug leading to the `with_data` argument being ignored. - When converting a :class:`MemImage` or a :class:`SharedImage` into a `numpy` array, shift and scale may determine a more complex change of pixel type. As an example, if a :class:`MemImage` is unsigned but the shift is such that it would be representing negative values as well, then the `numpy` type will be of signed type rather than unsigned. - When converting a :class:`SharedImageSet` into a `numpy` array, it now works likewise for :class:`MemImage` and :class:`SharedImage`: it now returns original values and, hence, shift and scale are considered. A more complex change of pixel type may occur such that all the :class:`SharedImage` instances can be represented without loss of information. **Breaking Changes**: - :attr:`MemImage.image_to_pixel_matrix` is now a read-only property, making it consistent with :attr:`MemImage.pixel_to_image_matrix`. - :attr:`SharedImage.matrix` has been removed, please use :attr:`SharedImage.world_to_image_matrix` instead. - The function :meth:`remove_loggers` is not available anymore. - The function :meth:`registerLogger` has been renamed as :meth:`transfer_logging_to_python`. However, it now cannot be reverted anymore as, after calling this function, `logging.getLogger("ImFusion")` becomes the logging interface. - The function :meth:`set_log_level` does not have any effect after calling :meth:`transfer_logging_to_python`, as `logging.getLogger("ImFusion").setLevel` becomes the interface for setting the log level. When this happens, a WARNING reminder is logged. - In the cases of `int`, `float`, `str`, `bool` and `list` values, :class:`.Properties` directly returns values with the original types. - Since the types do need to be specified, the enum `ParamCast` and the class `Param` have been removed. In the cast of vectors and matrices, `Properties.param()` function needs to be called with an argument of the required type, so that the desired type can be returned. Currently matrices and vectors will otherwise be returned in their internal string representation. - Subproperty keys now require the subproperty name, followed by a '/', and then followed by the index of that subproperty name at the given dictionary level. This syntax replaces lists of subproperties, which are no longer supported. - The Properties.params function only returns the list of parameters at the first dictionary level, instead than doing it recursively. In fact, it is no longer possible to get the nested list of parameters using the Properties.params function at the root Properties insteance: instead the Properties.params function will need to be called at the required dictionary level. Others -------------- February 2024 ~~~~~~~~~~~~~ **Breaking Changes**: - Changed API of image processing methods in MemImage (:meth:`~imfusion.MemImage.rotate`, :meth:`~imfusion.MemImage.threshold`, etc.): They no longer return bools as a status indicator but raise exceptions instead. The images are also no longer modified in-place and a clone is processed and returned instead (same as numpy or pandas). - Major refactoring of the Python API. Method, function and variable names are now all snake_case. Enum members are all UPPER_CASE_WITH_UNDERSCORES. Getter (and setter) methods have been converted to Python properties, which means that they can no longer be called like functions but return the values on attribute access. - :meth:`imfusion.init()` has been removed and is now called implicitly when the module is imported. Use `imfusion.info()` to get information about the OpenGL context and available plugins. - License check is now performed at import time of the :mod:`imfusion` package. You can activate it by running setting the ``IMFUSION_LICENSE_KEY`` environment variable (see :doc:`installing`). - :meth:`registerAlgorithm` now takes an algorithm ``id`` as well as ``name``. - :meth:`availableAlgorithms` now returns a list of ``id`` instead of ``name``. - :meth:`createAlgorithm` now takes an algorithm ``id`` instead of ``name``. - :meth:`executeAlgorithm` now takes an algorithm ``id`` instead of ``name``. - :meth:`algorithmProperties` now takes an algorithm ``id`` instead of ``name``. - SharedImage.numpy() has no copy argument anymore and it always returns a copy - SharedImage.numpy() returns the array already shifted, scaled and correctly typed. This should improve on usability since the user does not need to perform extra manual work anymore - Subproperties of Properties can now be accessed in a dictionary-like fashion (e.g. p['sub']['field']). However, for consistency reasons keys constructed using the '/' character (e.g. p['sub/field']), which are still returned by the params() function, cannot be used to access subproperties params anymore. - Dictionaries returned by Properties instances now contain Param instances instead of the corresponding string casts. - Added Python-based engines for ``torch``, ``onnxruntime`` and ``openvino`` to the ``imfusion.machinelearning`` module. August 2023 ~~~~~~~~~~~ **Breaking Changes**: - :mod:`numpy` is now a mandatory requirement - Dropped support for Python 3.6 and 3.7 March 2023 ~~~~~~~~~~ **Breaking Changes**: - The repr format of enums has changed. It now includes the underlying integer value. E.g. ``repr(Image.Type.UBYTE)`` now returns '' instead of 'Type.UBYTE'. - Dropped support for Python 3.5 November 2022 ~~~~~~~~~~~~~ **Breaking Changes**: - :class:`.DataGroup` has no more indexing methods for its children. Use :meth:`.DataGroup.children` or :meth:`.DataGroup.childrenRecursive` instead. October 2022 ~~~~~~~~~~~~ **Breaking Changes**: - Adding :class:`.Data` to the :class:`.DataModel` will now create a copy instead of transferring ownership. This should prevent common crashes related to the :class:`.DataModel`. - :meth:`.DataModel.add` now returns the copy and raises an exception if the given data could not be added. - :meth:`.DataModel.remove` now raises an exception if the given data could not be removed. July 2022 ~~~~~~~~~ - Deprecated :meth:`imfusion.open` in favor of newly added :meth:`imfusion.io.open`, added :meth:`imfusion.io.write`. September 2020 ~~~~~~~~~~~~~~ - :class:`SharedImage` is now allowed to have more than 4 channels August 2020 ~~~~~~~~~~~ - ``std::shared_ptr`` is used to track :class:`.MemImage` and :class:`.SharedImage` internally. This should have no effect on existing Python code but improves general memory safety. E.g. referencing a :class:`.SharedImage` after its parent :class:`.SharedImageSet` was deleted does not cause an access violation anymore. - Removed option to create non-owning :class:`.SharedImageSet`. Due to the ``std::shared_ptr`` change, these are not needed anymore. It's now perfectly valid to add a single :class:`.SharedImage` to two separate :class:`.SharedImageSet`. February 2020 ~~~~~~~~~~~~~ - Added bindings for :class:`.Display` and :class:`.Annotation`. November 2019 ~~~~~~~~~~~~~ **Breaking Changes**: - Removed previously deprecated functions in :class:`.ApplicationController` and :class:`.Properties` - Deprecated :class:`.DataList`. All function that used :class:`.DataList` before now use a regular Python ``list``. This especially affects :meth:`.Algorithm.convert_input`, since the `data` argument is now a ``list`` and you cannot call :meth:`.DataList.getImages` anymore. Instead you can use a list comprehension to filter all images: ``[i for i in data if isinstance(i, imfusion.SharedImageSet)]``. Also check the updated :doc:`algorithms` section. June 2019 ~~~~~~~~~ - Made :class:`.ApplicationController` mostly optional. The framework can now be initialized with :meth:`~imfusion.init`. - Added :meth:`~imfusion.open`, :meth:`~imfusion.executeAlgorithm` and :meth:`~imfusion.createAlgorithm`. - Moved :meth:`~imfusion.availableAlgorithms`, :meth:`~imfusion.algorithmProperties`, :meth:`~imfusion.registerAlgorithm` and :meth:`~imfusion.unregisterAlgorithm` to global :mod:`imfusion` namespace. The corresponding method in :class:`.ApplicationController` are deprecated.