Tags | Description |
Fixed | Fixed a crash in DefaultAlgorithmController when the focus widget got destroyed during reconfiguration of the Controller |
Fixed | Fixed that EnumParamControl was not updating the ComboBox items when the parameter values deriving from its attributes had changed. Before only a change in the number of ComboBox items was triggering its update. |
Changed API-Break Added | Added class TrackerID for tracking instrument identification. TrackingInstrument holds a member TrackerID that replaces members id, name, modelNum now. |
Added | Added GlVolumeView::RenderBufferWrapper to allow surrounding the entire rendering pipeline with a custom render buffer and thus modifying the rendering output before visualization with a custom shader. |
Fixed | Fixed dense pointcloud storage to be able to correctly load pixel-to-index maps again. |
Fixed Added Changed | Fixed mesh not updating in view after certain postprocessing tasks. Added an overload to MeshPostProcessingAlgorithm::setDecimationParam that allow specifying the maximum surface error Changed the default maximum surface error in the legacy implementation to something less prohibitive (now depends on maxEdgeLength) |
Fixed | Fixed crash in TrackingSequenceIO::configure when location ends in ".csv". |
Tags | Description |
Added | Added ConnectionFactory.h and moved the ConnectionBase.h , ClientConnectionBase.h , ServerConnectionBase.h ,
files to a dedicated Network folder (under ImFusionLib/Source/Stream/). Updated the includes in the WebsocketConnection.h . Added a ConnectionFactory.cpp file that creates, manages available connection protocols and allows for the creation of connections.
Updated the CMakeList.txt with the new entries. |
Changed | Members m_state, m_nextRequestedStateChange, and m_workContinuation of Stream have been made private to make the behavior of the state machine and streaming loop more explicit. |
Added Changed | Moved kind() method of various images streams to base class, and added a signal for the case that the stream's dimensionality changes. This allows stream controllers to update stream visibility in compatible views. |
Removed | Removed finalizeRecording from Stream . Finalization of recordings should be implemented in the recorder itself. |
Tags | Description |
Added Changed | After upgrading pytorch to 2.2, many previously unsupported pytorch operations are now supported in float16 on the CPU. However, due to various reasons, the performance is much worse than in float32. Therefore, casting to float32 for CPU inference is introduced if the dtype of any layer of the module is in float16 or bfloat16. This also fixes float16 CPU inference for pytorch 1.13. This does not affect model weights in float64, or any other dtypes, such as int8, int4, etc. |
API-Break | ML::ApplyTopDownFlagOperation sets topDown=true as opposed to topDown=false now. This is to be consistent with the rest of the framework.
ApplyTopDownFlagOperation sets topDown=true as opposed to topDown=false now. This is to be consistent with the rest of the framework.
|
Changed | Changed random distribution of RandomChoiceOperation implementation to avoid compiler / platform dependent results. |
Added Changed | Defined more clearly the difference between ML::VectorElement and ML::ImageElement: VectorElements can only be created from 1x1x1 images, all other images should be ImageElements. An exception is raised if this is not the case. Added some helper methods to convert these elements to/from torch tensors. |
Added | Renamed parameter reload of ML::PersistentCacheDataLoader to reload_from_disk to make it less ambiguous. reload is deprecated but should still work. Renamed parameter reload of PersistentCacheDataLoader to reload_from_disk to make it less ambiguous. reload is deprecated but should still work. |
Tags | Description |
Fixed | Fixed a bug in the dependent shader includes if multiple multi includes use a dependent include of the same type but each yields different shader code. |
Added | Introduced GL::LineRenderer, a helper class dedicated for high-quality thick and stippled line rendering. Its functionality partially overlaps with the line rendering feature of GL::FixedFunctionPipeline, however they have slightly different use cases:
- FixedFunctionPipeline is general purpose and allows for directly rendering any vertex buffer. However, it requires geometry shader support which is absent in OpenGL ES environments.
- LineRenderer also works in OpenGL ES contexts since it only uses basic vertex and fragment shaders. However, therefore it requires some preprocessing of the input vertices on the CPU.
|
Added | Migrated GL::ProgramCache, a base version of GlProgramIncludeManager, from ImFusionLib to ImFusionGL. |
Changed Depreaction | Migrated GL::ObjectPicking from ImFusionLib to ImFusionGL. The functionality has essentially remained the same. Instead of using GlObject pointers to identify object it now uses plain void pointers. GlObjectPicking has become deprecated. |
Tags | Description |
Fixed | Fixed serialization of std::vector<Filesystem::Path> and std::vector<Filesystem::Url> to and from Properties instances. |
Fixed API-Break | Fixed a potential race condition in Threading::ThreadPool::enqueueSignaled() where the signal callback function could be called before the result of enqueueSignaled() was assigned to the future. The new version of the function no longer returns a std::future but instead has the callback function consume the return value of the asynchonous operation. |
Changed API-Break | In PropertiesIO, extended Xml1_1WithAttributes format to also store a "type" attribute for the parameters. Introduced the new formats Json2_0 and Json2_0NoPreamble , which also maintain type information except for the ParamTypes Vector and Matrix (due to lost information about their dimensions after serialization). The type information is then reloaded when the appropriate PropertiesIO's load functions are called.
Breaking changes:
- The PropertiesIO::saveToXML() and PropertiesIO::saveToJSON() have been refactored to accept the format as third parameter instead than as forth parameter. Also, this format parameter does not receive a default argument anymore.
JsonNoPreamble has been renamed as Json1_0NoPreamble .
|
Added Changed | Added convenience functions for Properties:
|
Added | Added Container::LRUCache::extract() member function. Allow a maximum cost of 0 for Container::LRUCache to disable caching. |
Tags | Description |
Added | Added new machine learning inference engine pycoreml using the Python engine interface. CoreML is Apple's framework for accelerated machine learning utilizing CPU, GPU, & Neural Engine on Apple platforms. As of now, model conversion is not included to allow fast cold starts and avoid dependencies to pytorch. |
Added | Added functionality for Graph based pipelines with multiple sources. With this change, DataLoaders now can have multiple sources, and data loader specs have an inputs and output field to construct the graphs This is backwards compatible with regular DataLoader flows. |
Added | Added hasNoZeroInputImage function, and registered 'has_zero_input_image' filter. Can be used to filter out input images that only contain zeroes by providing 'has_zero_input_image' as a 'filter_function_key' to a FilterDataLoader. |
Added Changed | Added ML::BakeDeformationOperation to apply the deformation to the input images. Changed ML::DeformationOperation to not attach anymore a deformation to the input images. |
Changed | Added ML::RandomSmoothOperation. Allow smoothOperation parametrization in mm and anisotropism. |
Changed Fixed | Changed ML::ArgMaxOperation to select the first channel in case of a tie instead of the last. Fix to ImageResamplingAlgorithm when resampling outside the reference image on the CPU. |
API-Break | DataItem::Elements is changed to OrderedMap instead of std::map for now. You can rely now on insertion ordering. |
Tags | Description |
Added API-Break Changed | Added free functions GlUtils::shiftScaleStorageToNormalized and GlUtils::shiftScaleOrignalToNormalized to retrieve storage and normalization constants. Added CPU cross correlation function for 3D images. Changed return type of Math::crossCorrelation to std::unique_ptr<TypedImage<float>> . Adapted GlConvolutionFilter to support 1D kernels for 3D images and signed input and output types. |
Changed | Changed behavior of GlSliceRendererImage to always use blending for all images. Previously blending was used for all but the first image. |
Changed | A volume view's clipping plane is by default automatically applied to applicable GlObjects rendered in it, most notably meshes. Any clipping planes set to meshes rendered in a 3D view before will thus be overwritten. This behavior may be turned off by via GlVolumeView::setApplyClipPlaneToGlObjects(). |
Changed | ImageResamplingAlgorithm skips the computation if no resampling is necessary. If the algorithm is configured not to work in place, then a simple copy of the input image will still be created. |
Fixed | Fixed a bug in ImageResamplingAlgorithm which was padding images with a signed type with non-zero values. The issue only appeared when resampling an image on the GPU, with a reference image. |
Fixed | Fixed a potential driver timeout/crash in the GPU path of MeshToLabelMapAlgorithm in cases where the dataset/output volume resolution becomes too large. |
Changed | Add the DefaultAlgorithmController::setAddAlgorithmToHistory() parameter allowing to enable/disable algorithm workspace registration on compute. This is needed when an algorithm is added as a SubProperties in another algorithm controller, where it would otherwise create a redundant entry in the configurable properties with empty algorithm name. |
Added Changed Deprecation |
- Introduced unique IDs for algorithms independent of their GUI names.
- Deprecated and replaced large portions of AlgorithmFactory, and FactoryRegistry interfaces.
- Deprecated IoAlgorithmFactory. To update plugins:
- Update your Factory registration to use IDs in addition to GUI names.
- If you have an IOAlgorithmFactory, merge it into your AlgorithmFactory.
- Update all calls to createAlgorithm(), createIoAlgorithm(), and compatibleAlgorithms() to the new API.
|
Tags | Description |
Changed Fixed | By default AdvancedDicomSCP does not offer all possible transfer syntaxes, but only JPEG2000Lossless (if available) and the default uncompressed formats. This avoids situations where a PACS server would send datasets that then cannot be decoded correctly. It also avoids the unlikely case that a PACS would send lossless data with a lossy compression. The old behavior can be restored by supplying a configuration file for pacsClientConfiguration in DicomPluginSettings. |
API-Break | Some members of RTStructureDataComponent have been changed. The color attribute is now part of the RTStructureDataComponent and no longer of the individual contours. Even before, only the color of the first contour was used, so there is no functional difference in the new version. The referencedFrameOfReferenceUIDs member has been changed to referencedFrameOfReferenceUID. Each RTStructureDataComponent therefore only references one dataset now. This reflects how datasets are referenced in DICOM: each ROI (i.e. PointCloud with RTStructureDataComponent) has exactly one ReferencedFrameOfReferenceUID. The ReferencedFrameOfReferenceSequence, that was used before, is optional in DICOM and its absence would have broken the rendering of the RTStructs. |
Changed Fixed | The location URL used by DicomIoAlgorithm now also supports a 'study' query that should contain a StudyInstanceUID. This query is now always set when a PACS URL is created. The StudyInstanceUID will be added to any SERIES or IMAGE level C-FIND and C-MOVE request, as required by the standard. This change improves interoperability with different PACS vendors. |
Tags | Description |
Deprecated | Deprecated GenerateNetworkTrainingDataAlgorithm, LandmarkAnnotationAlgorithm, ObjectDetectionAlgorithm. |
Changed | Renamed "greedy" flag of the cache data loaders into "lazy" to make it more understandable. |
Added | Added operationWeights parameter for non uniformly sampled RandomChoiceOperation. |
Added | Added GPU recombination mode for MachineLearningModel, for increased performance. Added GPU recombination mode for MachineLearningModel, for increased performance |
Added API-Break | Python interoperability for ML::Engine. It is now possible to implement a new Engine from Python. An example using the OpenVino framework can be found in imfusion.machinelearning.openvino_engine .
Breaking change: ML::EngineInterface is now renamed ML::Engine.
|
Tags | Description |
Removed | Removed deprecated class PointCorrUS . Use PointsStorageComponent and PointsOnImage to store point correspondences on image sets, and the US::SweepGlobalInitAlgorithm for 3D pose initialization of an ultrasound sweep wrt. a volume. |
Added | Added GPU implementation of 3D Scan Conversion, which is active by default. |
Added | It is now possible to specify a calibration to be used as a default for any UltrasoundSweep acquired with a given LiveTrackingStream. This calibration should be contained in the InstrumentCalibrationDataComponent with a name in the format *-TrackingInstrumentName , and it will be used by the SweepCalibrator instance when a calibration with the exactly matching name ImagingProbeName-TrackingInstrumentName is not found. |
Deprecation API-Break | Moved all classes of the module into the ImFusion::US namespace, and renamed the classes listed below. If there are forward declarations to classes from the US module, it is required to either change the forward declaration to the namespace ImFusion::US, or remove it and include the class header instead. Example compiler message for that situation: ‘error C2371: 'ImFusion::UltrasoundSweep’: redefinition; different basic types`.
Renamed classes:
- UltrasoundBackwardCompounding renamed to BackwardCompounding
- UltrasoundBoneLabelingAlgorithm renamed to BoneLabelingAlgorithm
- UltrasoundBoneSegmentationAlgorithm renamed to BoneSegmentationAlgorithm
- UltrasoundBoneSegmentationBaseAlgorithm renamed to BoneSegmentationBaseAlgorithm
- UltrasoundBoneSegmentationController renamed to BoneSegmentationController
- UltrasoundFrameGrabbingConfigComponent renamed to FrameGrabbingConfigComponent
- UltrasoundFrameGrabbingPresets renamed to FrameGrabbingPresets
- UltrasoundGeometryDetection renamed to GeometryDetection
- UltrasoundGeometryDetectionAlgorithm renamed to GeometryDetectionAlgorithm
- UltrasoundGeometryDetectionController renamed to GeometryDetectionController
- UltrasoundRawDataAlgorithm renamed to RawDataAlgorithm
- UltrasoundRawDataController renamed to RawDataController
- UltrasoundSimDataPrepareAlgorithm renamed to SimulationDataPreparationAlgorithm
- UltrasoundSimDataPrepareController renamed to SimulationDataPreparationController
- UltrasoundSimOptAlgorithm renamed to SimulationOptimizationAlgorithm
- UltrasoundSimOptController renamed to SimulationOptimizationController
- UltrasoundSweepToMeshAlgorithm renamed to SweepToMeshAlgorithm
- UltrasoundTrackingEvaluation renamed to TrackingEvaluation
- US2D3DReconstructionAlgorithm renamed to Reconstruction2D3DAlgorithm
- US2D3DReconstructionController renamed to Reconstruction2D3DController
- USCalibrationInit renamed to UltrasoundCalibrationInit
- USConfidenceMapAlgorithm renamed to ConfidenceMapAlgorithm
- USRFProcessingAlgorithm renamed to RFProcessingAlgorithm
- USSweepCalibrator renamed to SweepCalibrator
- Original names outside of the namespace are preserved but are marked as deprecated
|
Tags | Description |
Changed Deprecated Added | Added TotalSegmentator v2.0.5 models. TotalSegmentatorAlgorithm : renamed the 3mm model to 3mm-V1.5.6 . Deprecated the specialized v1 models: TotalSegmentator-1.5mm-Vertebrae-Torch.yaml , TotalSegmentator-1.5mm-Muscles-Torch.yaml , TotalSegmentator-1.5mm-Ribs-Torch.yaml in favor of the updated V2.0.5 models. Specialized V2.0.5 models are available in ImFusion Labels. Note that the classes have changed. New labels in V2.0.5 are: Thyroid Gland , Prostate , Kidney Cyst Left , Kidney Cyst Right , Vertebra S1 , Heart , Pulmonary Vein , Brachiocephalic Trunk , Subclavian Artery Right , Subclavian Artery Left , Common Carotid Artery Right , Common Carotid Artery Left , Brachiocephalic Vein Left , Brachiocephalic Vein Right , Atrial Appendage Left , Superior Vena Cava , Spinal Cord , Gluteus Minimus Right , Autochthon Left , Autochthon Right , Skull , Sternum , Costal Cartilages . Labels removed: Heart Myocardium , Heart Atrium Left , Heart Ventricle Left , Heart Atrium Right , Heart Ventricle Right , Pulmonary Artery , Face , Autochton Left , Autochton Right . |
Tags | Description |
Changed | DataSourceComponent is now non-permanent and will not accumulate filename information over multiple saves and loads. |
Added | Added SelectionWidget::setLockMode interface for setting selection lock. |
Added | Added new readImage and writeImage functions to the corresponding JpegIO file. The functions overload the initial implementation and allow reading (and writing) JPEG images from (to) memory via the ByteBuffer class. Added the corresponding unit test function to the JpegTest.cpp file. |
Added | Added support for more pixel types in NrrdIoAlgorithm. |
Added Changed | Added class GlIntensityNormalizedSmoothedGradient to compute smoothed gradient in single shader. GlSpline now has a mode to visualize as a tube with custom radius. Added class GlOutlineRenderer, a wrapper for arbitrary GlObjects rendering a colored outline. |
Changed API-Break | Introduced SelectionWidget::setInputMode() to allow for configuring the behavior of the SelectionWidget through the API. SelectionWidget::updateData() was split into two functions SelectionWidget::setInputData() and SelectionWidget::update(). |
Fixed | Fixed a potential OpenGL driver timemout if a TransferFunction has a very large size: The resolution of TransferFunction::preIntTexture() is now clamped to 2048^2, which should still provide enough precision for all use cases. |
Fixed Changed | Fixed a bug where BakeTransformationAlgorithm would pad an image with a signed type with large values. Now the images will always be padded with zeroes by default. This default behaviour can now be overriden via the borderColor parameter. |
Tags | Description |
Added Removed |
- Added DataGroupingModel to the model hierarchy. This model can group Data displayed in the DataWidget according to their Patient/Study-IDs. The groups are internal to the DataGroupingModel and are not added to the general DataModel. The grouping modality ("None", "Patient ID", "Study ID") can be changed via the options of the DataWidget.
- Removed obsolete grouping functionality in Dicom-Browser and DicomIoAlgorithm
|
Changed API-Break | Changed the rendering behavior of masked images from per-view settings to per-dataset settings. It is now configured through DisplayOptions2d::maskingMode() and DisplayOptions3d::maskingMode(), respectively. Their boolean useMask setting has been superseeded by the more powerful MaskingMode enumeration. The MaskRenderingDecorator interface as well as the maskRenderingMode/maskRenderingColor member functions from ImageView2D/ImageView3D and related classes have been removed. Use the new corresponding member functions in the DisplayOptions classes instead. |
Fixed | Fixed the jumping of subproperty widgets inside a PropertiesWidget upon reconfiguration. |
Added | Added support for displaying Deformations to GlVolumeRendererGlobalIllum. This feature is off by default due to the high computational complexity. Use GlVolumeRendererGlobalIllum::setShowDeformations() to enable it. |
Added | Added a new modality (Data::Modality::DISTANCE) for distance maps, i.e. images representing the distance to some nearest obstacle (e.g. a boundary pixel in a binary image or the surface of a mesh). New algorithms that take a distance map as input should check for this modality. |
Added | Added LinkSelection class allowing for linking the Selection of multiple dataset implementing the Selectable interface. |
Changed | SelectionWidget now can handle selections of multiple Selectable Data at the same time provided they have the same size. Playback and selection are seperated in UI within the SelectionWidget. |
Tags | Description |
Added | Added CombineIntoTrackedSharedImageSetAlgorithm for creating a TrackedSharedImageSet from a SharedImageSet and a TrackingSequence. |
Fixed Changed | Fixed ImageSetIoAlgorithm to also number the first image in a set when exporting more than one image. Changed ImageSetIoAlgorithm to create separate directories for each image set when exporting more than one set. Changed ImageSetIoAlgorithm to load images in the natural sorting order rather than alphanumeric sorting order. |
Changed API-Break | Refactored our Animations Framework to no longer have a hard dependency on Qt:
- The Animations::Animation class no longer inherits from
QPropertyAnimation . Therefore, it's interface has changed to some extent. However, the majority of the original functionality is still available. The support for a dedicated finalization function has been removed. However, you can check for t = 1.0 in your update function, since the backend guarantees that this is always called at the very end of an animation unless canceled.
- You can now choose between different backends depending on the GUI/event loop framework that you use in your application.
- The animationsEnabled() state is now considered when running a new animation: if you run a new animation while the backend is disabled, it will not dispatch the animation but only call its update function once right away with
t = 1.0 . This should simplify client-side code significantly, since you no longer need to check the enabled state yourself.
- The new Animations::UniqueId interface can help you reducing bookkeeping efforts on the client-side.
|
Added | Added CompoundData interface to enable Data to expose internal datasets to the outside in a generic fashion. The interface is used by DataItemModel and DataWidget. TrackedSharedImageSet implements the interface to optionally expose the internal TrackingSequences, cf. TrackedSharedImageSet::setExposeTrackingAsChildren(). |
Fixed | Fixed MeshProcessing::Geometry::findDominantPlane using all faces for plane fitting instead of the ones provided by RANSAC scheme, fixed incorrect normal check and other issues. |
Fixed | Added more generic version of PythonInterpreter::eval function to execute Python code from C++. |
Tags | Description |
Changed Removed | The update to the new major version 3.0 of the SDK removes the majority of deprecation layers and brings a couple of additional changes:
- TrackingStream was renamed to TrackingSequence to make it clear that is has nothing to do with the ImFusionStream Module. A deprecation layer is in place so that code using TrackingStream still works. As a corollary, all related classes (such as GlTrackingStream) as well as functions, members, and factory names have been renamed as well.
- The old Geometry interface from ImFusionLib has been renamed to GeometryLegacy and will continue to exist for a few months. The new Geometry Library in ImFusionCore has been renamed to Geometry.
- The set of
clone2() member functions have been renamed to clone() .
- Many left-over headers in ImFusionLib forwarding to the actual implementation in ImFusionCore have been removed, e.g.
ImFusion/Base/Signal.h , ImFusion/Base/Configurable.h , etc.
Data::nameChanged was renamed to signalNameChanged for consistency.
|
Fixed | Fixed Mesh::Geometry::intersection, which was wrongly generating the polygons in some edge cases |
Added | Added DataComponentWithParentInterface for DataComponents which need access to their parent data. |
Added | Added a modality override to SharedImageSet. |
Added | Added possibility to set custom widgets for SubProperties in PropertiesWidget |
Deprecation | Marked redundant ImageProcessing::Padding enum alias as deprecated. Use ImFusion::PaddingMode instead. Similarly, added a note to Image::Type that is is redundant to ImFusion::PixelType may become deprecated eventually. Prefer using ImFusion::PixelType for new code. |
Fixed | Fixed a bug where the IoAlgorithm interface did not work with the ParameterMixin interface. |
Changed Depreaction | Modernized the public interface of ImFusionFile: member functions passing ownership through raw pointers have been deprecated and replaced by the std::unqiue_ptr/OwningDataList counterpart. |
Changed | ImageView2D: Move-image highlighting is off by default and can be switched on via the context menu of the view. |
Added | Added Python bindings for Mask and all derived classes. |
Fixed | Fixed potential nullptr access in SettingsDialog. |
Changed | Changed default compression mode of ImFusionFileIoAlgorithm to zstd. The default compression mode of the underlying ImFusionFile class remains unchanged. |
Tags | Description |
Added | New major release of ImFusionCore removing all deprecated interfaces. Furthermore, the Geometry API was moved from the Geometry2 namespace to the Geometry namespace, and some of the particularly verbose geometry class names where shortened such as from RectangleAxisAligned2D to RectangleAA2D . |
Added Changed | Added Utils::Variant, a specialization of std::variant offering additional convenience member functions for functionality that the standard library only provides in the form of free functions. Changed the return value of the set of Geometry::intersection() functions to Utils::Variant where applicable. |
Added | Added Encoding::base64Encode() and Encoding::base64Decode() to ImFusionCore replacing the Utils::Base64 infrastructure in ImFusionLib. |
Added | Added Container::enumerate() helper function to conveniently iterate over collections and have access to both the index and the value at the same time, similar to Python's enumerate() ; |
Added | Added Utils::Overloaded helper for easier implementation of visitors of a std::variant. |
Tags | Description |
Changed Deprecated Removed | Renamed ambiguous "Label" concept to "Target", in order to better differentiate between a "learning target" and a "labelmap/segmentation map". This change affects the DataComponent LabelTag -> TargetTag and all related functions (i.e. isLabel(), tagAsLabel(), etc. are now isTarget(), tagAsTarget(), etc.). A deprecation layer for the old naming is introduced. Following this change, the Operation::ProcessingPolicy has now more readable fields ['Inputs', 'Targets', 'Everything']. Compatibility with the older naming is provided in order not to break existing yaml configuration files. Support of the deprecated Operation configuration field "process_label: True/False" is discontinued. Please specify "processing_policy: Inputs/Target/Everything" instead. |
Fixed Changed | Fixed OrientedROISampler not taking into account the padding_mode parameter. Note that this sampler used to always pad with zero, so be aware that the behaviour might change if you specified another value. |
Added Deprecated | Added RunMLModelOperation to run an ML model on the input DataItem and add the prediction as extra fields in the item. The operation AddPixelwisePredictionChannelOperation is deprecated. Please use RunMLModelOperation instead, and then merge the fields with MergeAsChannelsOperation . |
Changed | CutOutOperation and RandomCutOutOperation support for physical units. This change affects the behavior of both operations due to differences in rounding and seeding. Added support for Operations to throw an error instead of warning on unexpected behavior. |
Changed | FileReader::configure: changed the expected structure of passed in Properties to support indexing individual SIS within a single .imf file. |
Added | OrientedROISampler can now directly sample from keypoints. Added random_jitter_range to OrientedROISampler, allowing to add random displacement to the sampled crops. |
Tags | Description |
Fixed | Fixed an issue where the results from HoughTransformAlgorithm where not propagated to the GUI if used from the controller. |
Changed | If DataComponents cannot be restored when loading an ImFusionFile (e.g. because the required plugins are not loaded), those components are still saved and will be written unchanged when the dataset gets saved to an ImFusionFile again. This bahaviour can be controller with the "saveUnrestoredDataComponents" parameter of ImFusionFileIoAlgorithm. |
Changed | Deprecated Base/Utils/Strings.h header; parseAlgorithmName() and sortAlgorithmNames() have been moved to AlgorithmUtils namespace. |
Changed Deprecation | The GlImage(unsigned int, ...) constructor overload was deprecated in favor of the more typesafe GlImage(Image::Type, ...) overload. Image::type() now returns the Image::Type enumeration instead of an unsigned int . |
Changed | TrackingStreams now support interaction through the SelectionWidget. The selection also affects the DataController visualization. |
Changed | DefaultAlgorithmController now calls setSplitCamelCase(true) on the PropertiesWidget by default. Introduced DefaultAlgorithmController::setSplitCamelCase to change this behavior. |
Changed Deprecation | Overhauled and modernized ApplicationController interface:
|
API-Break | RealWorldMappingDataComponent supports multiple mappings now. The mappings can be accessed through the getMappings method. As part of this change, the mapping to Standardized Uptake Values is loaded from PET DICOMs if available. |
Added | Added implementation of Broyden–Fletcher–Goldfarb–Shanno (BFGS) optimizer. |
Added | Added BayerPattern decoding to BasicImageProcessing algorithm. |
Fixed | Importing a TrackingStream from CSV could swap rows and columns of the parsed transformation matrices. The import UI and visualization were also overhauled. |
Changed Fixed | OptimizingAlgorithm::setOptimizer() emits signalParametersChanged . This fixes an issue where the GUI of the DefaultAlgorithmController was not updated. |
Fixed Added | Fixed a bug of GlVolumeCompounding when "reference" mode was enabled, where it would create empty images as result. Added GlVolumeCompounding::setInterpolationMode() enabling you to choose between the default linear interpolation or nearest-neighbor interpolation. The latter is particularly useful when compounding label maps. |
Tags | Description |
Fixed API-Break | Unified conversion texture <-> image coords of the masks in Xray2D3DRegistrationAlgorithm and EOS2D3DRegistrationTest . In particular the z-axis is now also w.r.t. image coordinates, i.e. the z component of min needs to be -0.5 while the one of max needs to be 0.5. We also added a WorkspaceConversion for Workspace files stored prior to this change. |
Fixed | Fixed issues relating to the loading of the configuration of X-Ray 2D-3D registration algorithm from workspace files. |
Changed API-Break | ConeBeamData is now topDown by default, i.e. they have the property "topDown" set to true. The projections are defined from the perspective of the source. I.e. the x-coordinate of the image is pointing to the right while the y-coordinate points down. For a regular AP X-ray this means that the patients left is on the right side of the image. The projection matrices are defined in standard OpenCV OR OpenGL convention. ConeBeamGeometry::matrix() provides the OpenGL matrix, i.e. world to normalized (OpenGL) image coordinates ([-1,1] and -1,-1 corresponds to the bottom-left corner of the image). Please not the flip in y which is due to the OpenGL convention. Should you need a matrix which directly maps to normalized image coordinates you can use the new ConeBeamGeometry::matrixWorldToNormalizedImage() method. For ImFusionFiles stored prior to this change we added a conversion. The same is the case for Workspace files, for which we added a WorkspaceConversion. |
Deprecation API-Break | Deprecation of the major parts of ConeBeamData as it will soon be removed. Instead we will use a SharedImageSet accompanied by a ConeBeamMetadata DataComponent in future. Instead of the deprecated functions you need to get the ConeBeamMetadata and use the corresponding method from there. We also added several utility functions to CT/Utils.h. I.e. CT::Utils::isConeBeamData() , CT::Utils::makeConeBeamData() , and CT::Utils::getConeBeamMetadata() . All matrix related methods from ConeBeamData have been deprecated and will log a "ConeBeamData::* called" error message. In particular ConeBeamData::matrix() will no longer provide you with the projective matrix. Instead you need to query the ConeBeamGeometry from ConeBeamMetadata . E.g. CT::Utils::getConeBeamMetadata(cbd).geometry().matrix(0, cbd.size()) . |
Deprecation API-Break | Moved all old/deprecated parts of the CT plugin to a "Legacy" folder. All corresponding algorithms have also been moved in the algorithm context menu in the Suite. They can be found in the "Legacy" submenu. All corresponding parts will be removed in a future version of the Suite. |
Added | Added GeometrySelfCalibration for auto-calibration of ConeBeamGeometry via optimization over metrics of the reconstruction. |
Changed | Changed MetalArtifactReduction to use AlgorithmReconstructionDecorator. |
Added | Added AlgorithmReconstructionDecorator and AlgorithmReconstructionDecoratorController which offer a decorator for algorithms that need a ReconstructionAlgorithm. |
Tags | Description |
Fixed | GammaCorrectionOperation: fix intensity range computation on GPU. This only affects multi-channel images. |
Fixed | GammaCorrectionOperation: fix intensity range computation on GPU. This only affects multi-channel images. |
Changed API-Break Added | DataItem and Operation now use shared_ptr instead than unique_ptr. The breaking change consists mainly in the return type of Operation::process and related function, which is now shared_ptr<SharedImageSet> process(shared_ptr<SharedImageSet> input) . If this change breaks your code, i.e. because you were assigning the result of a call to Operation::process to a unique_ptr, you can fix it by performing a shallow clone of the result, i.e. add ->clone2(SharedImageSet::ShallowImageCopy) . Furthermore, DataElements and DataItem are now using shared_ptrs as holder types, thus they don't directly manage the lifetime of the wrapped types anymore. List of breaking changes:
- Operation::process and Operation::process<Images/Vectors/Points/Boxes> now take and return shared_ptr instead than unique_ptr.
- DataItem::getAll now returns an unordered_set instead than a vector.
- DataElement::takeContent() was removed, as DataElement is now holding shared_ptr, please use DataElement::content() instead.
- OperationsSequence::execute which required being ported (deprecated on 2022-10-27) were removed, please use the respective OperationsSequence::process instead. Added: ML::KeypointSet and ML::BoundingBoxSet were introduced, which replace ML::Points and ML::Boxes respectively
|
Added Changed | Added PaddingMode parameter to Sampling parameters of ML::ModelConfiguration, deprecated previous MirrorPadding parameter. |
Tags | Description |
Fixed | Fixed a numerical precision issue in SplitImagesAlgorithm that caused individual zero value voxels at the edge of the FOV. |
Changed | RealWorldMappingDataComponent::originalToRealWorld now returns the unchanged value instead of 0 if there is no real-world mapping. This way the method can be used without manually checking hasRealWorldValueMapping before. |
Fixed | Fixed ImageResamplingAlgorithm and the underlying resample functions in ImageProcessing: Previously, they occasionally computed NaN values at the image border if the keep zeros/zeroMask option was enabled. |
Fixed | Fixed an issue where GlReduction would yield wrong argmin/argmax results on certain Intel GPU/driver combinations. |
Fixed | Fixed PropertiesWidget not maintaining the parameter ordering in a configuration()/configure() round-trip. |
Changed API-Break | Improved the move-image feature of ImageView2D/InteractionView2D:
- The moved images are no longer automatically determined from the set of currently visible images but instead must be specified explicitly. Therefore, ImageView2D::setMoveImage() has been removed and replaced by the ImageView2D::addMoveImage() and ImageView2D::removeMoveImage() pair of functions.
- InteractionView2D also has new functions addMoveImage() and removeMoveImage().
- The images selected for the move image feature are now highlighted with an overlay color using the GlImageHighlighter class. The setColor() member function allows to select the color for the overlay (set the color with a null vector to have a transparent overlay).
In case you need to migrate from the old behavior, this used to be the logic for determining which images were moved:
- There is exactly one visible image: move image applies to that image.
- There is more than one visible image: move image applies to all but the first image.
|
Added Deprecation | Added new functions to the ImageProcessing namespace:
The related member functions of MemImage and TypedImage have been marked as deprecated.
|
Changed Deprecation | Deprecated Utils::swapEndianness() in Base/Utils/Platform.h . Use the new Platform::swapEndianness() in Core/Platform.h instead. |
Changed API-Break | Fixed the ApplyWindowLevelAlgorithm and updated its interface. The algorithm is now also available in the ImFusion Suite. |
Changed | Sliders for IntAdjusterWidget now behave in the same way as DoubleAdjusterWidget, respecting the actual chosen step while dragging the slider. Other values can still be input directly in the respective QSpinBox. |
Tags | Description |
Added Depreaction | Added ML::MRIBiasFieldCorrectionAlgorithm, a neural network-based MRI bias field correction algorithm based on Simko et al. MIDL 2022. The MRIBiasFieldRemovalAlgorithm in Base/ was deprecated as a result. |
Added | Added ClusterMergingMode option to the KeypointExtractionAlgorithm that controls the merging behaviour. |
Changed | Updated LocalizeSegmentAlgorithm and changed parameter names to camel case. |
Added | Added new operation ML::CropAroundLabelMapOperation to crop an image around an object represented by a label map. |
Changed | LandmarkPredictionAlgorithm now uses camel case parameter names. A workspace conversion function is added. The factory name of the algorithm is changed from "Machine Learning;Landmark Prediction Algorithm" to "Machine Learning;Landmark Prediction". |
Added | Added new operation ML::SetMatrixToIdentity to set all matrices of the input to the Identity. |
Added | Added new operation ML::EnsureOneToOneMatrixMappingOperation to make sure TrackedSharedImageSets are properly handled by matrix-based operations. |
Tags | Description |
Added | Added an option to rotate stream output in VideoCameraStreamIDS. |
Changed | Extracted camera calibration paramaters from CameraCalibrationAlgorithm into CameraCalibrationSettings and created a standalone widget for it (CameraCalibrationSettingsController). |
Changed | Extracted camera calibration paramaters from CameraCalibrationAlgorithm into CameraCalibrationSettings and created a standalone widget for it (CameraCalibrationSettingsController) |
Added | Added an option to export/import marker configurations to the marker configuration controller. |
Added | Added an option to export/import marker configurations to the marker configuration controller. |
Changed | Checked the modality of input data to most algorithms in the Vision module, so that they no longer show up for data that do not have either Video or unspecified modality. |
Changed | Checked the modality of input data to most algorithms in the Vision module, so that they no longer show up for data that do not have either Video or unspecified modality. |
Tags | Description |
Changed Deprecation API-Break | Major refactoring of the DataModel API and related classes:
- Changes of DataModel:
- Merged the functionality of
take() into remove() which now return a std::unqiue_ptr with the removed/taken Data so that you can keep it alive.
- Several redundant member functions have been consolidated or deprecated to make the interface more lean.
- Consolidated the set of signals to notify about added/moved/removed datasets and data links and made them consistent.
- Changes of DataItemModel:
- DataItemModel no longer inherits from DataModel but uses composition instead. Therefore, it also no longer implements the full DataModel interface anymore but only the interface needed for
QAbstractItemModel . Use DataItemModel::parentModel() to access the underlying data model.
- The
AttachmentsRole was merged into the AttributesRole and therefore removed.
- Changes of DataWidget:
- Extracted some of the existing functionality into dedicated classes: The DefaultDataWidgetItemDelegate implements the default appearance of the DataWidget as you know it from the ImFusion Suite. The DataModelAutoLinking class implements the automatic link pose/link windowing functionality.
- When disabling thumbnails DataWidget will still use the custom UI from the item delegate, just with per-data type icons instead of thumbnails. The corresponding member functions and global setting was renamed.
See Data Model for the new concept overview page.
|
Changed Deprecation | Refactored DataGroup interface:
- Removed the non-owning mode, a DataGroup now always owns its nested Data instances.
- The optional "main data" pointer was renamed to DataGroup::proxyChild() to clarify its semantics.
- The set of member functions to modify the list of children has been refactored and moved from the protected to the public interface. These function now only apply to the direct children and no longer to multiple levels of nested children.
- A large number of member functions has been deprecated. These were mostly redundant and can be replaced with the corresponding DataList member functions of the return value of
children() and childrenRecursive() .
- Renamed the set of signals and removed
signalDataAboutToBeTaken completely - use signalChildAboutToBeRemoved instead; DataGroup::remove() now returns the data as std::unique_ptr so that the user can use the same function for both extraction and erasure.
|
Added | Added VolumeBasedMeshCurvatureAlgorithm for distance-volume-based computation of mesh curvatures (mean curvature, Gaussian curvature, curvedness and shape index). |
Fixed | Fixed serialization of Settings::Setting where the payload type is a vector. |
Added | Added MeshProcessing::Geometry::isPointInsideMesh for determining whether a point is inside or outside of mesh |
Tags | Description |
Added | Added Workspace::setSelectedDataComponents() member function as well as a new function argument to ApplicationController::saveWorkspace() to configure which DataComponents are exported when saving a workspace. |
Changed Deprecation | Some member functions of DataList have been renamed: get(Data::Kind) has been renamed to getFirst(Data::Kind) and getType<T>(Data::Kind) has been renamed to getAll<T>(Data::Kind) . The original member functions have been marked as deprecated. |
Added | Added DataLicenseComponent to store license information of datasets. |
Changed API-Break | Added synchronous method for BackgroundExporter class. Previous (async) methods were renamed to saveAsync for clarity. |
Changed Deprecation | Cleaned-up API of GlHistogram and GlJointHistogram and made them consistent. Removed deprecated functionality from GlReduction. |
Deprecation | Deprecated the majority of free functions in Base/Utils/Strings.h and Base/Utils/Containers.h from the Utils namespace that have been moved to the Container, String, and Platform namespaces, respectively. |
Changed | Machine Learning Operations have been moved in separate files under the folder ML/Operations . |
Tags | Description |
Changed Deprecation API-Break | Major overhaul of the Controller interface:
|
Changed | Matrices are no longer burnt-in when saving PointClouds in ImFusionFile format. |
Changed | Refactored SplitImagesAlgorithm to now uses Parameters for easier configuration from code. The names of configuration parameters were changed to be in camelCase as per convention. Old names are still working but will give a deprecation warning. |
Added | Added ImageView2D::ZoomMode::OriginalPixelSize option where a zoom factor of 1 will always show 1 image pixel per viewport pixel. |
Changed Deprecation | Added support for order-independent transparency to GlSliceView. Due to the computational complexity and its rare use cases in 2D visualization it is disabled by default. The corresponding GlView::orderIndependentTransparency() interface is now present in the base interface, which also offers an optional GlView::sharedOitInstance() to be used internally. Some getter member functions of GlVolumeView have been renamed to follow naming guidelines. |
Added API-Break | Added Slice::AnatomicalPlane enumeration to allow for more expressive code when referring to anatomical planes for slice-based visualization. Member functions of ImageView2D, GlSliceView and GlSlice have been changed to take this enum instead of a plain int . |
Changed API-Break | Changed GlSliceRenderer interface: The virtual center() function was replaced by the more general defaultPose() function that can indicate both the orientation and the center of the default pose. This interface function is available to the outside through GlSlice::defaultPose() dispatching to the renderer instance correponding to the given data type. ImageView2D::reset() will use this new interface to determine the view matrix after reset. |
Changed | Added RemoveUnlabelledImagesAlgorithm, which was moved over from the ML module |
Changed | Added LandmarksToImageAlgorithm, previously known as GenerateLandmarkLearningDataAlgorithm in the ML module |
Changed Deprecation | InteractiveView now supports multiple ViewInteraction instances, so it becomes possible to add custom ones in addition to the default one. The order of view interactions is important: Events are forwarded to them in sequence, and the first one accepting it will consume it. For dealing with the default interactions, it may be useful to use the convenience functions ImageView3D::interaction3D() and ImageView2D::interaction2D() to be independent of the order. Also see InteractiveView::addInteraction(). The old single-instance interfaces setInteraction() and interaction() have been deprecated as a result. |
Tags | Description |
Added | Added the classes VideoFileRecorder and BackgroundVideoFileRecorder for converting sequences of images into video files. Added the algorithm DisplayRecorderAlgorithm for recording the content of DisplayWidget into a video. |
Changed Deprecation | Changed TiffIO to support reading multiple images from a single TIFF file. The TiffIO::readImage(const std::string&, MemImage*&) function overload has been deprecated in favor of TiffIO::readImage(const std::string&). |
Fixed | Fixed DisplayWidget::mapFromOpenGL() returning a wrong Y coordinate if the screen's device pixel ratio is not 1 (e.g on High DPI screens). |
Changed API-Break Deprecation | Extensive overhaul of the Configurable and Properties interfaces for serialization. The whole component has been moved to ImFusionCore and several API changes have been performed in the process. See Configurable/Properties API Migration Guide for a detailed overview of the changes and guidelines for migration. |
Changed API-Break Fixed | Removed parameter requiresNoCleanup from MeshIO::load and MeshIO::loadFromPLY. MeshIoAlgorithm now performs duplicated vertex merge regardless of "comment ImFusionNiceMesh" in PLY file and depends only on m_mergeDuplicateVertices flag. Removed parameter requiresNoCleanup from MeshIO::load and MeshIO::loadFromPLY. MeshIoAlgorithm now performs duplicated vertex merge regardless of "comment ImFusionNiceMesh" in PLY file and depends only on m_mergeDuplicateVertices flag |
Fixed Changed | MeshProcessing::Cleaning::mergeCloseVertices now adds halfedge properties for color, texture, and normal if the vertex properties can not be merged consistently. The vertex properties are removed in this case. |
Changed Deprecation | Moved header files of several mesh-related algorithms and structures from ImFusion/Base/ to ImFusion/Mesh/ :
- CombineMeshesAlgorithm.h
- InteractiveMeshEditingAlgorithm.h
- Mesh.h
- MeshBooleanOperationsAlgorithm.h
- MeshCreator.h
- MeshCreatorAlgorithm.h
- MeshCustomProperties.h
- MeshDistanceAlgorithm.h
- MeshIterators.h
- MeshMaskAlgorithm.h
- MeshOctree.h
- MeshPostProcessingAlgorithm.h
- MeshProcessing.h (this is also renamed to /Mesh/Processing.h)
- PoissonReconstruction.h
- TriMesh.h Additionally the whole
ImFusion/Base/MeshProcessing/ subfolder was moved to ImFusion/Mesh/Processing/ .
Added forwarding headers for compatibility.
|
Tags | Description |
Fixed | Fixed GlOrientationMeshOverlay not supporting showing the vertex colors of the assigned mesh. |
Changed Fixed | Changed/Fixed the behavior of firstHitpointLocation and the depth computation of the DRR and MIP volume rendering. For DRR the center of mass of the intensity distribution is used from now on. For MIP the depth of the pixel with the maximum intensity will be used. |
Added | Added a pose-linking feature to AnnotationModel (and AnnotationWidget), where the link is between a point-based annotation and its parent dataset. This uses the new class AnnotationPoseLink, which creates a link between a point-based annotation and a dataset, making the annotation points follow the dataset (matrix and deformation). Moving the annotation itself doesn't move the dataset. |
Added | Added "actions" to algorithms that can be registered for automatic creation of bindings and controllers. |
Added | Added AlgorithmFactory::setAlgorithmAsExperimental() function to mark individual algorithms as being of experimental/research nature. Such algorithms will be shown with a beaker icon in the GUI. |
Added | Added ReorderLabelValuesAlgorithm for conversion of fragmented label values into a consecutive range. This makes it possible to convert UShort images to label maps even if they have values over 255 but less than 256 different label values in total. |
Changed | Made the behavior of MainWindowBase::postLoad() configurable through MainWindowBase::setPostLoadActions(). Removed the pure virtual MainWindowBase::postLoad(SharedImageSet*) overload. If you want to customize this functionality implement postLoad(Data*) instead and perform the dynamic_cast if needed. Make sure to call the base class version as well. |
Tags | Description |
Changed API-Break Removed Deprecation | Introduced MachineLearningModel based on ML::DataItem, which allows multiple-input/multiple-output predictions on heterogeneous types.
- PixelwiseLearningModel and ImagewiseLearningModel were removed. Instead, MachineLearningModel can be used by specifying in the Yaml configuration file the 'PredictionOutput' parameter. Possible output types are [Image, Vector, PointCloud]. Use 'Image' for the old Pixelwise models, and 'Vector' for the old Imagewise models.
- PixelwiseLearningAlgorithm and ImagewiseLearningAlgorithm are deprecated and kept it only for running models in the Suite that don't specify the 'PredictionOutput' parameter. For updating the model, simply add a 'PredictionOutput' parameter to its configuration file.
- A new MachineLearningModelAlgorithm/MachineLearningModelController pair was added.
- Removed BUILD_ML_LEGACY and all related Legacy code.
- ImagePredictorInterface was replaced by EngineInterface, which abstracts deserializing and running a model generated by a particular third-party framework (i.e. Torch, Onxx, ...)
- ImagePredictionExecutor was removed as not needed anymore.
|
Changed Removed API-Break | Turned all ImageROISamplers into Operations. Removed ImageROISamplerSet (use RandomChoiceOperation instead). |
Added | Added RandomChoiceOperation to execute randomly one operation from a set of given operations |
Tags | Description |
Changed Deprecation | Improved the performance of MeshProcessing::Cleaning::mergeCloseVertices, which now contains removeDuplicateVertices as a special case with tolerance 0.0; deprecated removeDuplicateVertices. |
Changed | Mesh loading is now more robust to invalid vertex, color, normal or texture coordinate indices in the source file. |
Added Changed | Added support for L2 distances in MorphologicalOperationsAlgorithm. Renamed the parameters of this algorithm to camel case (In Place -> inPlace , Operation -> opMode , Pixel Size -> opSize ). |
Added Changed | Structures View:
- A new context menu opens when right-clicking on a structure in the Structures-View Widget. This context-menu gives the possibility of editing the selected structure, deleting it (moved functionality from the widget to this menu), or computing and showing its statistics. The computed statistics are: voxel count, volume in mm^3, bounding box center and extent, as well as the number of connected components.
- The "Delete Selected Structure" button on the bottom right of the list of structures was replaced with the "Create New Label Map" button: this button creates a new label map for the selected data-set. If the AnnotationPlugin is present, the Segmentation Toolbox of this plugin is started, otherwise the standard Labeling functionality of the Suite is triggered.
|
Changed | Reverted correction of triangle orientation in MeshProcessing::removeDuplicateVertices introduced in version 2.35. The correction is now optional and deactivated by default. |
Changed | Changed GlProgramIncludeManager's implementation to use an LRU cache (the size of which is now a constructor parameter). This means it no longer holds every created program indefinitely. |
Added | Added generic IO::FileLoader class for loading files. |
Changed API-Break | Changed implementation of RANSAC generalizing input type, adding support for weights and refinement of solution. |
Added | Added finite-difference mode to Levenberg-Marquardt algorithm. |
API-Break | Removed ImageSamplingAlgorithm, use OrientedROISampler in ML/ImageSamplers.h instead. |
Changed | Make DistanceTransformAlgorithm configurable (inner vs outer vs both vs signed distances). |
Changed Deprecated | Major refactoring of MeshProcessing functions including change of function names, parameters, reorganization into sub-namespaces, minor implementation details. Changes are made to the functions related to Mesh smoothing, simplification, subdivision, statistics and other miscellaneous operations |
Added Changed | Major overhaul/generalization to support generic visualization of Data in InteractiveViews:
See also Rendering Custom Data in Views.
|
API-Break Removed | The family of setVisibleData()/showData()/hideData() functions of DisplayWidgetMulti has been refactored so that their behavior (append vs. replace) matches the functions of InteractiveView:
- DisplayWidgetMulti::showData() will now add/append Data instance to the set of already visible data.
- DisplayWidgetMulti::setVisibleData() will replace the set of visible data. Furthermore, we removed the
InteractiveView::ViewOptionsSource interface, also known as "store view settings per dataset", as it has been become obsolete since the support of per-data display options.
|
Added | Added/restored ability to set thickness in curved slice view. |
Tags | Description |
Changed Deprecated | Major refactoring of MeshProcessing functions. |
Added Changed Deprecation | Implemented new hole filling, which adapts tessellation to the existing mesh characteristics (used in MeshProcessing::Cleaning::cropMesh). Added new cropMesh overload for cropping with planes and deprecated the old one. Added progress handling for cropMesh functions. |
Changed | Added support for arbitrary many AbstractIncludes in GlProgramIncludeManager. |
Added | Introducing GlScreenSpaceAmbientOcclusion post-processing filter implementing Screen Space Ambient Occlusion and made it an optional feature of GlVolumeRenderer. SSAO is a post-processing effect providing an approximation of global illumination and improving depth perception for opaque scenes. You can enable the filter through GlVolumeView::setSsaoMode(). |
Added | Added MeshPickingManipulator and PointCloudPickingManipulator which can be used to obtain indices of selected faces/vertices/edges from a Mesh or selected vertices from a PointCloud. Added MeshPickingManipulator and PointCloudPickingManipulator which can be used to obtain indices of selected faces/vertices/edges from a Mesh or selected vertices from a PointCloud |
Changed | Extended the GlVolumeRendererGlobalIllum renderer so that shadows are also casted onto the geometry-pass (non-DVR) scene. |
Added | It is now possible to configure a semitransparent background for the text label of GlAnnotations. |
Added | The imfusion_generate_VS_user_file() macro defined in ImFusionLibConfig.cmake now accepts the PATH_DEBUG and PATH_RELEASE arguments. They allow to inject a list of directories into the generated .vcxproj.user file, in addition to the path to the ImFusion SDK. |
Changed | Added GPU implementation to MeshToLabelMapAlgorithm, which will be the new default choice in case OpenGL 4.3 is available. Also modernized the API and offer a Parameter-based interface for the algorithm's configuration. |
Tags | Description |
Changed API-Break | Major overhaul of the Progress interface:
See also Progress Reporting.
|
Removed Added | Removed Mesh::setFromArrays, added Mesh::createFromArrays as replacement. |
Removed Changed | Split MeshProcessing functions across multiple namespaces and files. |
Added | Added support for serializing Utils::Optional in Properties. |
Removed Changed | Removed several ImFusion Suite-specific and obsolete functions from MainWindowBase. Renamed MainWindowBase::finishProcessing() to processEvents() . |
Added Changed | Added GlSlice::setBlendingColors() property to make tint colors used for color blending configurable. Added SingleColor and DualColor values to GlSlice::BlendingMode enumeration to optionally disable automatic color blending based on modality. Changed the way the Checkerboard blending mode works: The checkerboard fields are no longer placed at fully customizable locations but are now homogeneously distributed according to a uniform field size. On the API side this means that the GlSlice::checkerboardLocations() property was replaced by the newly introduced GlSlice::checkerboardFieldSize() property. |
Added Changed Removed API-Break | Complete refactor of the MetaImage class. The new version has a simpler syntax, is better documented and fails more gracefully. In contrast to the previous behaviour, non-CT 2D image sets are treated as 4D data. |
Changed | Restricted the file formats supported by QtImageIO, which is now a namespace. |
Changed | Improved MeshProcessing::removeDuplicateVertices. It now allows for fixing wrong winding order of the face vertices. |
Added | Added method for cropping of the mesh with a set of planes (MeshProcessing). Added optional capping of the holes which result from mesh cropping. |
Added | Added a GPU version of Viterbi algorithm (ClMarkovChain). |
Added | Added a possibility to visualize point IDs in GlPointCloud. |
Fixed | Fixed visualization of a GlPointCloud with lines. |
Fixed | Fixed a bug in the CPU path of GlHistogram when using images with more than one channel. |
Tags | Description |
Added | GlScalarBarOverlay now allows to show the input value in the original domain, rather than the normalized value. |
Changed Deprecation | Overhauled interfaces for SDK initialization to make them more explicit and configurable: We introduced the new Framework::InitConfig enabling you to see the different steps that can happen during SDK initialization and what the defaults are. You can customize an instance of this and pass it to Framework::init() in order configure the SDK initialization. Furthermore, the ApplicationController, MainWindowBase, and ConsoleController constructors now also accept this InitConfig in case you are using one of these interfaces and want to delegate framework initialization to them. |
Changed API-Break | The QtAppender interface was completely removed from MainWindowBase. Use the new LogViewerWidget as replacement if you want to show a log window in your Qt-based application. |
Changed | Fixed a text alignment issue with GlTextOverlay when using a vertical alignment of GL::TextRenderer::Bottom, where the bottom part of the text might be cropped. Rendered text may now appear a couple of pixel more to the top than before. |
Added | ApplyMaskAlgorithm now also supports sequential processing of multiple images via the SequentialImageProcessor interface. |
Added | Added new SharedImageSet::CloneOptions::NoSelection flag that will make the cloned SharedImageSet now have an empty default Selection instead of the original one. This can prevent inconsistencies and potential crashes if the original Selection was referring to images that are not present in the cloned SharedImageSet, for instance if you are using it together with SharedImageSet::CloneOptions::NoImageData. |
Added | Added Mesh iterators. |
Added | Added support for set and unordered_set serialization in Properties. |
Added Deprecation | Added DataSourceComponent to store information on the source of the data. You should use this data component instead of the parameter "filename" in the Properties of a SharedImageSet which is now considered deprecated. |
Added | Added method registerAlgorithm to ApplicationController that allows to register an algorithm before the controller is closed, and added field keepControllerOpen to workspace files to specify if the algorithm controller should be closed after executing the algorithm. This allows streaming algorithms to be properly saved and loaded from workspace files. In order to make a streaming algorithm work you should add m_main->registerAlgorithm(*m_algorithm) after calling compute(). |
Changed | Consolidated all Machine Learning algorithms in the context menu under 'Machine Learning'. The 'Deep Learning' entry is now removed. |
Added | Added support for loading and saving 3MF meshes. |
Changed API-Break | Updated ClProgram to also use the ImFusion::Resource infrastructure instead of the DeviceCodeRepository interface for loading OpenCL kernel source code to be in line with what GL::Program does. See also Loading Shader Source Code. |
Tags | Description |
Added | Added InteractiveLiftChartOverlay, GlLiftChartOverlay, and LiftChartOverlayController. Created a basic rendering of a lift chart, with colored bars and a slice indicator, as an overlay. The bars are set by the controller, which lists all the current annotations. |
Fixed | Fixed several issues with the mask support of GlReduction:
- The support for IntensityMask was broken.
- The support for CroppingMasks had an issue where pixel at the border of the Mask could be handled wrongly.
- If a mask was used once the mask never got disabled such that any following reduction got corrupted.
- Fixed several issues for the average reduction and average of absolute reduction in combination with Masks. Due to multiple issue the accumulated number of pixel which are not masked was corrupted.
|
Fixed | Fixed an issue in the CPU path of the CroppingMask where a half-pixel shift was missing. This could cause maskValue() to return wrong values for pixel at the border of the mask. |
Fixed | Fixed IntensityMask for signed integer images. The range as well as the image values got scaled with respect to the unsigned counterpart instead of the actual signed type. |
Fixed | Fixed a compilation issue of the MedianFilter when the filter gets initialized. |
Added | Added options to GlTextOverlay to draw a background below the text |
Changed | In applications which subclass from MainWindowBase views are no longer hidden automatically when they become empty after the displayed images are deleted. This behaviour has been moved to ImFusionSuite only. If the subclasses require this behaviuor they can implement it by overriding the MainWindowBase::onDataDeleted method. |
API-Break Changed Removed | General overhaul of the DataComponent API. The base interface is now called DataComponentBase and with pure virtual methods only. We introduced new derived interfaces as replacement:
- DataComponent<T> using
operator==() , operator=() , and the copy constructor from T to implement the DataComponentBase interface
- TemporaryDataComponent providing empty implementations for non-serializable non-copyable DataComponents
- LegacyDataComponent using the Configurable interface to implement clone/assign/equals (i.e. provide old behavior)
Furthermore, the support for DataComponent inheritance (as in, subclassing a subclass of one of the base DataComponent types) has been removed. If you need to create multiple DataComponent types with overlapping members, consider making use of composition instead.
See the updated documentation on DataComponents for more detailed information.
|
Deprecation API-Break | All low-level OpenGL wrapper classes and interfaces have been moved to the new ImFusionGL library. The original classes in ImFusionLib have been deprecated. See the ImFusionGL Migration Guide for more information. |
Added | Added a class Anatomy and corresponding data component AnatomyDataComponent to allow to keep track of contained anatomy in our image and data classes. |
Tags | Description |
Fixed | Fixed a potential bug when copying SharedImages with more than 4 channels and an up-to-date GL representation, which was leading to the last channels being discarded. |
Added | DisplayWidgetMulti::showData() and DisplayWidgetMulti::visibleData() now take an optional argument to filter out algorithm views. |
Added | Added ProjectiveGeometry::backproject(). |
Added | Added ImageTemplateMatchingAlgorithm and ImageTemplateMatchingController, for matching regions of images to a stream. |
Added | Added the ImFusion::Random namespace in ImFusionLib (mirroring Core) for complex random generators (for example random unit vectors and random rotation matrices). |
Fixed | Fixed a bug in the GaussianFilter where only one half of the filter got computed, resulting in wrong filtered images. This also corrupted the results of Filters::laplacianFilter3d() and Filters::guidedFilter3d(). |
Changed | The crash handler is now installed during the Framework initialization, and it's reset during Framework deinitialization. |
Tags | Description |
Deprecation | Deprecated Mesh::moveToCenter(), Mesh::offset(), Mesh::setOffset(), PointCloud::moveToCenter(). |
Removed | Mesh::uniteIndices() and Mesh::hasUnitedIndices() have been removed. |
Changed Deprecation | Added Mesh::boundsLocal() that returns the bounds of the mesh in a local coordinate system. Deprecated computeBoundingBox(), computeBoundingBoxWithMatrix(), boundingBox(), center(), extent(), origin(). Use boundsLocal() or bounds() instead. |
Added | Added a mechanism to create prismatic annotations, using a polygonal or freeform line as the base of the prism and a line segment for the height of the prism and its skew direction. The option is available through the UI by selecting a closed line and a line segment annotation together. |
Added Fixed | Added cloneDeformation parameter to ImageResamplingAlgorithm together with support for copying/cloning deformations. |
Added | A setting was added to change the behavior upon double-click on the 3D view. The standard one is to translate the MPR slice views to the point on the surface that is below the pointer. If the new "orientViewsToNormal" setting is enabled (or the respective API is called), the views will also be aligned to the normal to the surface at that point. |
Deprecation | Deprecated the DeformationListener interface. Use the Deformation::signalChanged signal instead. |
Added | GlMesh's projective rendering mode in MPR views now smoothly fades out when the mesh no longer intersects with the MPR plane. This can be configured through the newly introduced GlMesh::projectiveFadeoutRange and corresponding MeshDisplayOptions::p_projectiveFadeoutRange properties. |
Added | TransferFunction has now a look-up-table (LUT) mode as alternative to defining it via keypoints. GlColormap::PET20Step uses this functionality now, so no keypoints can be defined in the TransferfunctionWidget for this colormap anymore. |
Changed Depreaction | Added GlImageProgram::setClearOutputEnabled() that allows for setting a custom clear color. The original GlImageProgram::enableClearOutput() function has been deprecated. You can simply replace any calls to it with a call to setClearOutputEnabled(). |
Changed API-Break | Changed return type of GlVolumeRenderer::data() to be consistent with the corresponding setter. |
Added | Introducing Zstandard compression for the ImFusionFile, as compressionMode: 65. This allows for fast compression for all image datatypes. |
Tags | Description |
Removed Added Changed API-Break | Removed XRayCTRegistrationAlgorithm and XRayCTRegistrationAlgorithmController and added XRay2D3DRegistrationAlgorithm and XRay2D3DRegistrationController to replace them. Eos2D3DRegistrationAlgorithm now has XRay2D3DRegistrationAlgorithm as its parent class, Eos2D3DRegistrationController replaced by XRay2D3DRegistrationController. |
Added Changed API-Break | Added view() and optDialog() getter functions to Gl2D3DRegistrationController Gl2D3DRegistrationController now opens an algorithm view. Changed signature of setSlice() function in GlProjectionAnnotation and added m_isFocus member to specify whether a shot has focus. Added support in ConeBeamDisplayDataController for display in a different view. |
Added Changed API-Break | Refactored Eos2D3DRegistrationAlgorithm: added preprocessEosShots function, renamed takeShotsWithGeom to takeOwnedShots, added getter function ownedShots, added const qualifier to constructor, renamed m_regAlg to m_nestedRegAlg. Added m_annotationsVisible member. Refactored Eos2D3DRegistrationAlgorithmController: renamed m_regAlgCtrl to m_nestedRegAlgCtrl, added m_shotsView, m_regViewGroup and m_cbDisplayCtrl members. |
Added | Added class ConeBeamMetadata to act as a DataComponent for Cone-Beam projections to replace metadata members of ConeBeamData. |
Tags | Description |
Added | Added Filesystem::File::isExecutable. On Windows, thas means the file is a 32- or 64-bit "Windows-based" application. On Unix, that means it grants the executable permission. Added Filesystem::Directory::isWritable, which checks whether the user can create a file in the directory. On Windows, that requires being the correct user or having privileges. On Unix, that means it grants the write permission. |
Changed | Moved installCrashHandler and resetCrashHandler from Log namespace to Platform. The program is not anymore aborted on Windows when the fatal exception is caught. The crash handler is not installed anymore during the Log initialization. |
Added Changed | Enhanced Threading::ThreadPool class:
- Added several new convenience functions such as waitUntilFinished() and isFinished().
- Added option to query the current number of currently active threads.
- Renamed requestStop() to cancelTasks() and clarified its semantics.
Also added Threading::setCurrentThreadName() and Threading::ThreadPool::setThreadNames() functions so that the underlying OS/debugger may show them as description.
|
Added API-Break | Extended the Resource::Repository interface so that it must provide a contains() predicate function checking whether the repository can provide a given resource. This allows to introduce the new Resource::locate() function enabling you to check whether a certain resource is available without actually loading it. |
Added | Added extra functions to the Compression::zstd namespace to give users more control. |
Tags | Description |
Fixed | Fixed a bug where ImFusion files were not able to store if the ImageDescriptor::isMetric flag is false and the image has a Z-spacing != 1.0. |
Added | Locale is now set to locale::classic() in Framework::init(), and parameter conversion in Properties is made locale independent. |
Changed | PointCorrAlgorithm can now configure which input image should be modified. |
Added | Added inverse transformation, interpolation mode, and support for angles bigger than 180 degrees to GlPolarToCartesian. |
Added | Added forward and backward differences to GlGradient. |
Added | Introducing the new ColorPickerWidget as convenience widget for letting the user choose a color. It consists of a HsvColorPicker2d, HsvHueSlider, and an optional opacity slider. |
Fixed | Fixed Spline::getUniformSamples which wasn't always computing the uniform samples correctly |
Added | Added LicenseManagerDialog, a QWidget which can be used to activate a LicenseKey. |
Added Changed | Added BallPivotingSurfaceReconstructionAlgorithm, adapted VISION to Open3D 0.12.0 api changes |
Added | Added MeshProcessing::lineIntersection() utility function to compute a sorted list of intersections between a Mesh and a Geometry::Line. |
Fixed | Fixed Geometry::Line::intersectsTriangle() not considering the isFinite state of the line. The function would always compute the intersection of an infinite line even if it was finite. |
Fixed | The handling of arrays while converting between PropertyFile and JSON has been reworked. Now the round-trip conversion is lossless. A Param<std::vector<T>> will be correctly represented as a JSON array. Due to JSON limitations, T may be different than the original after converting back (it will be either integer, double, bool or string). |
Added | Added support for loading Machine Learning Models from an included Resource (directly from the library dll/so). |
Tags | Description |
Changed API-Break | Introduced ML namespace: most of the machine learning-related classes are now under the ML namespace. MLConfiguration has been renamed to ML::ModelConfiguration. MLParameter has been renamed to ML::AdvancedParameter. |
Removed | Removed unused MLPluginSettings class. |
Added Changed | Changed seeding to be recurrent in DataLoader and added a method for seeding on Dataset and the corresponding python binding. Added a seeding method to OperationsSequence. |
Added Changed | Added new PersistentCacheDataLoader to cache data on the disk. Renamed standard disk cache from cache to memory_cache . |
Added Deprecation | Separated DataReader from DataLoader and added functionality to configure Readers from config. Old configs still work but will give a DeprecationWarning, prompting the user to use the new config layout in the future. |
Added | Added operation to add random noise to an image. |
Changed | Pixelwise models now return a SharedImageSet with the very same type (potentially a derived class) as the input. |
Changed | Changed implementation and add support for GPU computation of several Operations. |
Changed Deprecation | Removed support of outlier estimation in NormalizePercentileOperation. Please use the legacy version NormalizePercentileLegacyOperation if you really need the old behaviour. |
Added | Added Operations for free-form deformation of images. There is a deterministic (DeformationOperation) and a random version (RandomDeformationOperation). |
Tags | Description |
Changed | The HDF5 IO algorithm now reads and writes spacing, shift, and scale values for each dataset, instead of one global set of values for all datasets. Old files with such a global set of values will still get loaded the same way as previously. |
Changed API-Break | Changed color types in LabelDataComponent from vec3f to vec4f. The transparency of each label can now be changed individually. |
Changed API-Break | Split the original ObjectRenderModes enumeration of GlSlice up into GlSlice::ObjectRenderMode and GlSlice::CrosssectionRenderMode as it was describing different rendering concepts. The original enum has been removed. New getters/setters for the cross-section render mode have been added. |
Added Deprecation | Made DisplayWidgetMulti and its overlays easier to configure from the outside: Added DisplayWidgetMulti::DefaultOverlays enumeration that can be used with the new DisplayWidgetMulti::addDefaultOverlays() overload. The original overload taking 6 bools has been deprecated. Added InteractiveViewOptionsOverlay::setVisibleDisplayOptions2dSections() and InteractiveViewOptionsOverlay::setVisibleDisplayOptions3dSections() functions to configure what parts of the view- and display option overlays shall be shown. |
Added | Added ApplicationController::signalAlgorithmRemoved that is emitted when an Algorithm is about to be removed. |
Added | Added alternative constructor overload to Settings::Setting that allows for lazy-evaluating the setting's default value. |
Fixed | The LicenseManager doesn't crash any more if the program exits before the license update process has ended. This was a rare occurrence for very short-lived tasks. |
Fixed | The Qt TouchEvents forwarded from the DisplayWidget to each View's sceneEvent() are now in OpenGL coordinates, as it was already the case for MouseEvents and HoverEvents. Previously needed workarounds where the incoming event's y coordinate needed to be inverted are no longer necessary. |
Added | Added CliqueLookupTable class to identify point constellations in larger pointclouds. |
Fixed | Fixed the computation of the level/window in HistogramDataComponent::computeAutoWindowing() and the computation of the percentils based on window level in HistogramDataComponent::computeAutoWindowingParameters(). Previously there have been issues with shifts of half a bin and wrong border handling. Furthermore, fixed an issue in HistogramDataComponent where the auto windowing would return wrong results if one bin contains more than 2^24 values. |
Deprecation API-Break | Deprecated all function of the legacy Image and Algorithm API, such as:
In a very few occasions it would have been too complex to introduce a deprecation layer for owning raw pointer overloads. There, we function signature was changed directly to use unique_ptr, which may yield a compilation error on consuming code.
|
Tags | Description |
Changed | The default implementation of DataComponent::equals() will no longer compare parameter types and attributes of the two DataComponent instances. Both properties are only intended for display/UI aspects and should not affect the comparison result. |
Fixed | Fixed MemImage copy constructor and assignment operator that were accidentally defaulted instead of deleted. |
Removed | Removed MeshCenteringAlgorithm, use Mesh::moveToCenter instead. |
Fixed | Fixed GlPointBasedAnnotation::renderPoint and GlPointBasedAnnotation::renderLabel not considering matrix |
Fixed | Fixed bug with multi-file MetaImage export (.mhd/.raw) where every other image slice appeared to be a composite of half of the previous and half of the subsequent image. The bug was introduced on 14 May 2020. |
Fixed | Fixed incorrect channels bug in QtImageIO when loading and saving bmp images with 32 bits and alpha channel. |
Added | Added a constructor to DataWidget taking the necessary references. The previous constructor now forwards values to it. Added ApplicationController::canBeDeleted as a virtual function that MainWindowBase::canBeDeleted now overrides. |
Fixed | The Level of Detail of a 3D View is now adjusted when dragging via touch input for increased performance, as was already the case for mouse input. |
Fixed | Fixed a bug in SharedImageSet::swapWith() and TrackedSharedImageSet::swapWithImageSet() interfaces if their ownership flag differs. Calling those functions in this cases will fail, as it can not be supported. |
Changed Deprecation | Migrated the DataModel class to smart pointers:
|
Removed | The Settings::storeViewSettingsPerDataset setting will no longer store InteractiveOverlay visibility status as part of the per-data view options. |
Fixed | Fixed the mask support in GlReduction in case of an average reduction of a 3D volume. If the volume has a size greater than 64 in both x and y direction, the returned values were invalid. |
Added | Added DataModel::linkData() and DataModel::unlinkData() convenience functions. |
Changed | Move workspace serialization logic of DataLinks from DataWidget to the Workspace class. This allows for saving/restoring this information also without MainWindowBase. The Workspace format has been slightly changed as a result. |
Changed API-Break | Renamed the PropertyLink interface to DataLink for increased naming consistency. The corresponding header file has been renamed as well. |
Tags | Description |
Changed API-Break | PlaybackTrackingStream now accepting vector of multiple TrackingStreams as input. |
Changed | Complete refactoring of US frame (fan) geometries. Previously, there were two different places to store the geometry of an US frame: UltrasoundMetadata ([mm], assumption that the fan spans the whole image) and UltrasoundGeometry ([px], incomplete support for linear frames). Now, the US::FrameGeometry and derived classes are used for describing the geometry of a frame. A FrameGeometry is now contained in a FrameGeometryMetadata, and that is the only storage location. UltrasoundSweeps don't have a UltrasoundGeometry anymore, but quick accessors to the geometry contained in the metadata. UltrasoundSweep::frameGeometry() is guaranteed to create a geometery if none exists so far. UltrasoundMetadata were stripped of content describing the frame geometry. There are conversion methods to the UltrasoundGeometry class, if needed, but they are deprecated. |
Changed | Complete refactoring of US frame (fan) geometries. Previously, there were two different places to store the geometry of an US frame: UltrasoundMetadata ([mm], assumption that the fan spans the whole image) and UltrasoundGeometry ([px], incomplete support for linear frames). Now, the US::FrameGeometry and derived classes are used for describing the geometry of a frame. A FrameGeometry is now contained in a FrameGeometryMetadata, and that is the only storage location. UltrasoundSweeps don't have a UltrasoundGeometry anymore, but quick accessors to the geometry contained in the metadata. UltrasoundSweep::frameGeometry() is guaranteed to create a geometery if none exists so far. UltrasoundMetadata were stripped of content describing the frame geometry. There are conversion methods to the UltrasoundGeometry class, if needed, but they are deprecated. |
Changed API-Break | Updated UltrasoundSweepRingBuffer::insert() member function to use std::shared_ptr<SharedImage> as parameter type. |
Changed API-Break | Updated UltrasoundSweepRingBuffer::insert() member function to use std::shared_ptr<SharedImage> as parameter type. |
Tags | Description |
Changed Deprecation | Deprecated the Utils/Algorithms.h header and its helper functions such as executeAlgorithm() et al. All this functionality has been migrated to the new smart pointer-based Algorithm/Image API and moved to the Utils/AlgorithmUtils.h header file. Furthermore, these functions have been put into the AlgorithmUtils namespace, e.g. AlgorithmUtils::execute(). |
Added Changed Deprecation | Added OwningDataList::extractFirst() and OwningDataList::extractFirstImage() member functions and renamed several other member functions for increased consistency and readability:
|
Changed | Introduced convention of ultrasound images to be stored so that pixel (0,0) is in the upper left corner. For most image formats, this is the default anyway. ImFusionFile will flip US images if they are not and update calibration and metadata accordingly. This behavior can be turned off either by calling ImFusionFile::setEnsureTopLeftOriginOnLoad or globally by setting the IMFUSION_LEGACY_IMAGE_ORIENTATION environment variable. See Coordinate Systems for more information. |
Fixed | Fixed Geometry::fitPlane(). The plane offset computation was recently broken (on 2020.07.21) and returned the inverse of the offset instead. |
Fixed | Fixed an issue in the PCA class where the covariance matrix was not properly normalized w.r.t. the number of samples. |
Added Deprecation | Added GaussianFilter class, deprecating Filters::gaussianFilter2D/3D. |
Fixed | Fixed invisible MPR intersection lines still triggering SliceManipulator. Fixed GlSlice::drawOtherSlice() evaluating the wrong GlSlice::objectRenderMode. |
Fixed | Added mode INCREASE_BIT_DEPTH for increasing bit depth from 8-bit to 16-bit to BasicImageProcessing. |
Added | Added support for annotation per frame on 2D data. |
Added | Added Auto view layout configuration. Modifies the views layout automatically to adapt to the number of views, in the way that we believe data is best visualized. |
Fixed | Fixed a bug in MemImage::rotate(const mat3&, bool, double) when applied to multi-channel images. |
Added | Added support for multi-channel NIFTI images (RGB24 and RGBA32). |
Added | Added SharedImage::assign(std::shared_ptr<Image>) function to move/sink in images into a SharedImage without copying. Added SharedImage::descriptor() convenience function. |
Added | Added interfaces to ImageProcessing for applying processing to user provided output images avoiding extra allocations. Performance improvement of flip and rotate. |
Added | Added experimental chroma-depth rendering mode to GlVolumeRendererGlobalIllum, which encodes distance from the camera by applying a warm-cold color gradient to the volume rendering. This can be particularly useful for low-contrast data such as ultrasound volumes. You control this setting through the GlVolumeRendererGlobalIllum::RenderOptions DataComponent of each data set. |
Added Deprecation | Introducing the new PropertyLink interface providing functionality to keep certain aspects of Data (e.g. windowing information) in sync across multiple Data instances. Added LinkWindowing and LinkPose classes as initial demonstrations of this concept. The DataModel class was extended to also manage PropertyLinks. Added options to DataWidget to autmatically link windowing per modality and/or link pose on grouping of Data.
The global per-modality DisplayOptions2d concept has been deprecated and removed from the UI. Use the LinkWindowing interface instead to model such behavior.
|
Tags | Description |
Added | Added VolumeFreeformCroppingAlgorithm. Allows the user to select a freehand cropping volume from the point of view of the camera. Works on both 3D and MPR views. |
Changed | Changed the behavior of SharedImage when syncing images with more than 4 channels. Since OpenGL can not handle more than 4 channels, a synchronization MemImage -> GlImage will discard any additional channels. If this happens the corresponding GL representation can no longer be marked as dirty to avoid accidental data loss when syncing the GlImage back to a MemImage. SharedImage::setDirtyGl() will log a warning in this case and return false . |
Changed | Changed the behavior of MergeChannelsAlgorithm. Now the matrix of the different images is taken into account during the potential resampling. Moreover, the images are not necessarily converted to float: if all images have the same type, then the output image will also have this type. |
Fixed | Fixed an issue where a AlgorithmListener was not added to Algorithm::m_listeners. |
Changed API-Break | Refactoring MeshIO and MeshIO tests:
- MeshIO changed from class to namespace
- flipYZ boolean flag removed from MeshIO functions
- Added function that creats hardcoded reference meshes with texture, colors, and halfedges
- Modified fileLoadingTest() to test all combinations of reference mesh
- Removed loadFromPLY() and renamed loadFromPLY2()
|
Added Deprecation | Added the functionality to save and load MetaImage files (.mhd, .mha) with compressed image data. Added the MetaImage::SaveOptions struct for passing various optional parameters to MetaImage::save(). Deprecated versions of MetaImage::save() taking boolean arguments as optional parameter arguments. |
Fixed | Fixed MeshProcessing::pointToSurfaceDistance(). Before, the distances could be slightly off from the true values |
Added | Added DisplayOptions2d::useMask and DisplayOptions3d::useMask interface to configure whether a 2D/3D view shall consider the mask of an individual data set of not. This is useful in scenarios where you want to use masks to support certain algorithms (e.g. Image Registration) but still want to render the entire image or if you want to use a mask to cut away parts of the 3D visualization but still show the entire image in 2D. |
Fixed | Fixed a potential crash in GlObjectPicking if OpenGL 4.4 was not available. |
Tags | Description |
Changed Deprecation API-Break | General overhaul and modernization of the Image API:
- Usage of the Image base class as image descriptor has been deprecated. Use the new ImageDescriptor struct instead. This avoid ambiguous function overloads taking an Image as polymorphic argument.
- Member functions of Image, SharedImage, and SharedImageSet that use owning raw pointers have been deprecated. The new overloads with std::unique_ptr or std::shared_ptr should be used instead.
- SharedImageSet has been refactored to hold its SharedImages in a std::shared_ptr. This makes the previous container mode (
own flag) obsolete and deprecated. Copy the std::shared_ptr directly to model 'container' SharedImageSets providing a view onto images. You can access the std::shared_ptrs via SharedImageSet::getShared() and SharedImageSet::images().
- The SharedImageSetIterator has been deprecated because of confusing semantics. In the near future, SharedImageSet will no longer be iterable. Use the new SharedImageSet::selectedImages() member function to get a temporary std::vector of the selected images to iterate over instead.
- As a corollary, the interface to clone a SharedImageSet has been overhauled as well:
clone() and nonOwningClone() have been deprecated, use the new SharedImageSet::clone2() member function instead (clone2() will be renamed to clone() once the old deprecated functions have been removed completely).
- The majority of basic image processing functions in MemImage / TypedImage has been deprecated. Use the new free functions in the ImageProcessing namespace instead. These functions will always create a new Image instance if the image descriptor changes. You can use move assignment or std::swap to mimic an in-place processing operation.
- The ImageListener interface has been deprecated. There is no planned replacement. Use the shared ownership models of SharedImage/SharedImageSet if you want to implement shared ownership of image data.
Have a look at the updated documentation in Using Image Data and Algorithm/Image API Migration Guide for details and usage examples.
|
Added | Added TransferFunctionFactory::createCtSkinSoftTissueBonePreset() for a new transfer function present for showing skin, soft tissue, and bone in CT image data. |
Added | Point clouds can be exported to PLY and OBJ file formats. |
Added | Added functionality to GlFixedFunctionPipeline to optionally use the order-independent transparency feature of the SDK. In order to activate this feature, pass the GlOrderIndependentTransparency instance to the enable() call. |
Changed | GlStateGuard::DepthTest will also store and restore the state of the glDepthMask() setting. |
Fixed | Proxy server set during license activation is remembered on next start. |
Added | Added GlPlane for plane annotations. |
Changed | ImageView2D ignores the image matrix if contains a 3D rotation. If multiple images are selected, matrices are ignored it at least one contains a 3D rotation. |
Fixed | Fixed potential crash when loading corrupt JPEG files on Windows. |
Changed Deprecation | Removed the optional matrix interface from SharedImage. A SharedImage will now always have a matrix. SharedImage::hasMatrix() was deprecated and will always return true. |
Fixed | Fixed ImageComparison returning Algorithm::Success status only if the input images were equal. Use ImageComparison::imagesAreEqual() to check for equality using the API. |
Added Fixed | Fixed a couple of bugs in the InteractivePixelInfoOverlay class that shows the pixel intensities under the current mouse position as view overlay. This class is now also exported to the SDK and thus available to be used directly. Added new functionality to the underlying GlTextOverlay. You can now set a custom hinting text that is used instead of the current text to calculate the required overlay space. This can avoid the constant resizing of the overlay in case of continuously changing text. |
Fixed | Fixed BilateralFilterAlgorithm not preserving image transformation matrix in all configurations. |
Tags | Description |
Changed Deprecation API-Break | General overhaul of the Algorithm interface:
- Algorithm::output(DataList&) was declared deprecated, use the new Algorithm::takeOutput() instead. The default implementation of these two member functions forward to the repsective other to maintain compatibility of existing code.
- Introduce Algorithm::FactoryInfo struct with corresponding getters/setters to store information about how an Algorithm was created by the factory. Naming is explicit to make intentions clear.
- Algorithm::input(), Algorithm::setName(), and Algorithm::name() are deprecated. Use the FactoryInfo struct instead. Algorithm::setInput() has been removed completely because of its highly confusing semantics.
- Removed unused
Algorithm::categories() interface.
- The AlgorithmListener interface was deprecated and replaced by dedicated signals Algorithm::signalParametersChanged and Algorithm::signalOutputChanged. AlgorithmController now inherits from SignalReceiver and will connect to these signals on construction.
- Hints for migration:
- Calling
Algorithm::setInput() will yield a compiler error. Chances are quite high that you don't want to call it and should remove the call. Otherwise use Algorithm::setFactoryInfo().
- Using
Algorithm::m_input will yield a compiler error. Chances are high that you don't need it, otherwise use Algorithm::m_factoryInfo.input .
- There may be a compiler warning (in rare cases also a compiler error) in AlgorithmControllers if they now inherit twice from SignalReceiver. This should be resolved
- You no longer need to call Algorithm::addListener() in your AlgorithmController because the base class does it for you (same with
removeListener() ).
Have a look at Algorithm/Image API Migration Guide for details and usage examples.
|
Added | Introducing the new OwningDataList class, a DataList exhibiting ownership semantics. It is essentially a std::vector<std::unique_ptr<Data>> providing extra syntactic sugar in the form of convenience functions for filtering and extraction. |
Added | Added Controller::setTitle() as improved means to set a Controller name in the GUI (so far this could be achieved by an undocumented side effect of Algorithm::setName()). |
Fixed API-Break | Fixed a potential data race in the Octree class due to multi threading. As a result, the low-level Octree class now only accepts a std::shared_ptr<const MemImage> as input. There are no API changes if you use the high-level OctreeDataComponent interface. |
Fixed | Fixed saving and loading of texture images to/from PLY files |
Added | Added GlMesh::projectiveIntersectionTolerance() parameter to configure an optional tolerance during the computation whether a mesh intersects the MPR plane in projective renderin mode. |
Changed Deprecation | The screenshot functionality of DisplayWidget now uses rendering to a dedicated Framebuffer Object instead of directly reading from the windowing system's framebuffer. This avoids race conditions. The new DisplayWidget::captureScreenshot() method replaces the now deprecated DisplayWidget::getScreenshot() function. In addition, you can now create screenshots at custom resolution. |
Added | Added convenience comparison operator overloads for the Parameter class. Thus, oparator== and operator!= comparison of a Parameter<T> instance with an instance of type T does no longer require calling Parameter::value(). |
Added Deprecation | Introduced the Algorithm::takeOutput() member function as replacement for Algorithm::output(), which is now deprecated. The new function is easier to use and exhibits clear ownership semantics by returning an OwningDataList. This new class was added in order to mimic the already existing DataList in terms of convenience functions but explicitly model ownership of the held Data. |
Fixed | Fixed Workspace class not supporting placehoders for the execute flag of algorithms. |
Added | Added ImFusion file support for point clouds. |
Added | Added ImFusion file support for meshes without textures. |
Changed Fixed | Changes and fixes to the projective rendering modes of GlMesh in MPR views:
- fixed a bug where front/backside were flipped when GlSliceView::flip() was enabled
- normalize color gradient wrt. mesh depth projected onto view direction
- add new
ProjectiveWireframe render mode that shows frontside solid and backside in wireframe mode
- renamed GlMesh::RenderMode2d enum value
ProjectiveDepthEncoding to ProjectiveColorGradient
|
Fixed | Fixed a potential crash in JpegIO when reading corrupt files. |
Tags | Description |
Changed API-Break | We changed our logging framework and no longer rely on log4cxx. Instead we developed ImFusionLog, a very lightweight logger interface that allows for easy extension and integration into other 3rd-party logging frameworks that may be used by consumers of the ImFusion SDK.
Please refer to the corresponding Doxygen page for more detailed information.
|
Added Changed | Introduction of the new ImFusionCore module serving essential core core functionalty that is not specific to any business logic. This is the first step in an effort to reduce the complexity of the monolithic ImFusionLib module and split it up into individual parts.
The following functionality has been moved to ImFusionCore:
The new headers can be found in the ImFusion/Core include directory. Some namespace and function names have been changed for consistency. For now the corresponding headers in ImFusionLib (ImFusion/Base ) transparently forward to their new location and contain aliases in case of name changes. Future releases will deprecate this forwarding layer and eventually remove it as of Version 3.0
|
Changed API-Break | Updated all classes to follow the new coding guidelines wrt. the Parameter API: public class members of type Parameter now have a p_ prefix, e.g. Parameter<vec3> p_targetResolution . Amongst others, this affects the following SDK Algorithms: ImageResamplingAlgorithm, SharedImageArithmeticAlgorithm, LandmarkPredictionAlgorithm, LabelStatisticsAlgorithm, LineToIsosurfaceIntersectionAlgorithm, RemoveDuplicateFrames |
Changed API-Break | Various changes to ParameterMixin and Parameter API:
|
Fixed | Fixed writing and loading of the PCD point cloud colors. Added ImFusion versioning for PointCloudIoAlgorithm. |
Fixed | Fixed mesh cropping, which was occasionally giving wrong results. |
Fixed | Fixed bugs in Geometry::Triangle::intersectsPlane(), where not all intersection situations were taken into account. |
Deprecation | Deprecated MeshProcessing::triangleIntersectsPlane(). Use the more robust function Geometry::Triangle::intersectsPlane()instead. |
Fixed | Improved logic for automatically determining near/far clip planes in GlVolumeView to handle extremely small scenes correctly as well. |
Changed Removed | Changed default search paths of Framework::loadPlugins() and ApplicationController::loadPlugins(). They will now also search relative to the ImFusionLib shared library file. The obsolete IMFUSION_PLUGIN_PATH_32 environment variable is no longer considered. |
Added | Added ImageROISampler interface and several implementations in the ML plugin. |
Added | Added MeshCollisionDetectionAlgorithm to find if two Meshes are colliding, or are further away than a given safety distance. |
Added | Added ClSort class for OpenCL-based sorting of vectors. |
Added | Added algorithm SynchronizeMemGlAlgorithm in GL folder that allows manual CPU-OpenGL synchronization of a SharedImageSet. |
Tags | Description |
Deprecation | Deprecated the SelectionListener interface. Use the SharedImageSet::signalSelectionChanged signal directly instead. |
Changed Deprecation | Several improvements of the SharedImage API:
- The SharedImage(Image&) constructor has been deprecated due to unclear ownership semantics. Use one of the other overloads instead. Initialization can be done using a
std::unique_ptr<Image> or a std::shared_ptr<Image> . Furthermore, two new constructor overloads have been added that allow moving a TypedImage<T> and a GlImage into a SharedImage.
- The SharedImageListener interface has been deprecated. Use the corresponding signals directly.
- The
resize() and matrixPointer() member functions have been removed. If you need to resize a SharedImage call resize() on one of its representations and set it dirty.
|
Fixed | Fixed a bug where m_useContextMenu was not considered in all Interaction classes. |
Removed | Removed InteractionFilter class. |
Changed | GlSliceRenderer will no longer apply thick MPR rendering to label maps. |
Added | Added functionality to GlProgramIncludeManager to distinguish different sets of shader defines in addition to the abstract includes. |
Fixed | Fixed an issue which prevented a GlMesh to be rendered with shading if wrapped by a GlProjectiveObject. |
Added | Added GlVolumeView::setUseAutoClipDistance() property to allow users to configure whether the OpenGL near/far clipping planes shall be deduced automatically. You can disable this flag in order to set custom near/far clipping planes using GlVolumeView::setNearClipDistance() and GlVolumeView::setFarClipDistance(). |
Added | Added CSVParserDialog to parse CSV files into a Table. Added CSVTrackingStreamDialog to select appropiate headers for a Tracking Stream. |
Tags | Description |
Added | Added HistogramDataComponent::minmax() overloads accumulate the minimum/maximum values of all images contained by the SharedImageSet. |
Fixed | Fixed BasicImageProcessing default values for min/max thresholds not considering all images of a SharedImageSet. |
Fixed | Fixed an issue when rendering intersections of a GlMesh in a GlSliceView would not show all faces/lines. |
Changed | The picking for GlPointBasedAnnotation now takes point size and line size into account. |
Fixed | Fixed a bug where GlOrderIndependentTransparency might break the mesh rendering on certain Intel GPU/driver combinations due to a driver bug. |
Fixed | Fixed a bug where the sceneCenter was not considered in case of touch events in InteractionView3D. |
Fixed | Fixed a bug in slice-slice intersection code in Slice::intersect(). Due to numerical instability, certain combinations of slice orientations would yield false negatives in the finite mode. |
Changed | The CMake config for the ImFusionLib on unix systems only requires C++11 now instead of 14. This should work fine with the majority of SDK headers. If you encounter compile errors related to the C++11 version use CMAKE_CXX_STANDARD to an appropriate version. |
Added | Added an optional Mask for the LabelToMesh and MarchingCubes algorithms. The resulting mesh will only contain vertices that are within the provided mask. |
Changed | When saving snapshot workspaces (i.e. Workspace::Mode::Snapshot) all data will be written to a dedicated file stored next to the workspace file.
Previous versions would not write data that was originally loaded from disk. However, this could lead to bugs where in-place operations were not tracked correctly.
|
Tags | Description |
Changed | Fixed potential conflict of invariants between DataComponentList and LazyInstantiatedDataComponent: The assignment operator of DataComponentList would also delete held LazyInstantiatedDataComponents even though they are guaranteed to stay alive for the lifetime of the parent Data.
With this fix DataComponentList assignment will no longer delete LazyInstantiatedDataComponents but keep them alive. As a result, two DataComponentLists are not necessarily the same after assigning one to the other. To emphasize that they do not follow value type semantics, the assignment operator of DataComponentList has been removed and replaced with an explicit assign() function, analogous to DataComponent::assign().
|
Changed | Improved API for disconnecting using SignalConnection tokens. This is now to be done using the new SignalConnection::disconnect() interface, which does not require accessing the corresponding signal (which might already be dead). Furthermore, SignalConnections are now held in shared_ptrs as they exhibit have three-way lifetime dependencies. Therefore, Signal::connect() also returns a std::shared_ptr<SignalConnection> . |
Changed | Migration of the view- and overlay interfaces to std::unique_ptr where feasible. This breaks the API in cases where a function would take an owning pointer using a raw pointer as argument and installing a deprecation layer was not feasible. The following interfaces and classes are affected:
|
Added | Added GlView::ViewStateGuard utility class to temporarily change the GlViewState of a GlView. This allows for a better implementation of proxy GlObjects that render another GlObject with a different view state than the one of the view (e.g. GlProjectiveObject). |
Fixed | Fixed a bug where the HistogramOverlay would not update when the Image's window/level values change. |
Added | Added stable Geometric Mean calculation to Math.h |
Added | Updated the OptimizerXNES API, which now supports a sparse mode that can efficiently deal with large dimensional problems. |
Changed Removed | The deprecated compression options for exporting data into ImFusionFiles have been removed (RLE, 12-Bit Packed, Diff+Huffman). It is however still possible to open files that have been encoded in this way. FFV1 and H264 (lossy compression) are still supported, and they can now be also used for multi-channel images. |
Fixed | Fixed a bug where GlProjectiveObject was not properly working for GlMesh. |
Tags | Description |
Deprecation | Officially dropped support for Visual Studio 2013 and deprecated support for Visual Studio 2015. Future releases will require at least VC++ 14.10 (Visual Studio 2017). |
Added | Added a properties class which integrates with our Configurable while also providing setters and getters. Parameters should be defined in the public area of an ParameterMixin and directly initialize within the header. By doing so it is guaranteed that the variable name, the properties name, as well as the default value are visible to any SDK user.
Example: class MyAlgorithm : public ParameterMixin<Algorithm>
{
public:
...
Parameter<bool> inPlace = {"inPlace", false, *this};
...
}
|
Changed API-Break | Revamped OpenGL context handling infrastructure:
- Modernize GlContext interface and its concrete platform-specific subclasses to use unique_ptr as type for owning pointers. Removed unneeded parameters from GlContext::create() function.
- Export all platform-specific GlContext subclasses to the SDK.
- Renamed GlQtContext to GlContextQt for a more consistent naming scheme. GlContextQt::clone() will no longer create a new GlContextQt but an instance of the corresponding native type (e.g. GlContextWindows or GlContextGLX). Thus, a cloned GlContextQt can not be used to render onto a Qt surface. Use the constructor instead if you explicitly need this functionality.
- Added GlContextMananger::createContext() as convenience function to create a shared context for a new thread.
- Added GlContextMananger::ensureLocalContext() as utility function to create a shared context for the current thread if necessary.
|
Fixed | Fixed a half pixel shift issue in ProjectiveGeometry and Camera. Camera matrices obtained in OpenCV/computer vision format now project from world to pixel coordinates, with integer coordinates corresponding to the pixel center. This is commonly done in OpenCV/computer vision and also matches our image coordinate convention.
Previously the projection point (0,0) corresponded to the top-left corner of the image plane. Now (0,0) represents the center of the pixel in the top-left corner.
|
Fixed | Fixed ImFusionFileIoAlgorithm not setting the list of ignored DataComponents correctly on export. |
Added | Added MeshCenteringAlgorithm, which recenters a mesh's vertices, keeping its global transformation. |
Added | Added InteractionView2D::RotationReference option that allows for defining the center of rotation based on either the dataset, view, or MPR cross-section centers. |
Added | The ImageResamplingAlgorithm now also resamples the mask if possible. |
Added | Ctrl + click on the visibility check box of an annotation shows only that annotation, and hides the rest. |
Tags | Description |
Fixed | Fixed an issue where a GlImageProgram would trigger an OpenGL Framebuffer error where the number of slices of the ouput volume exceeds GL_MAX_FRAMEBUFFER_LAYERS . |
Fixed | Fixed an issue where NIFTI files that were stored in a left-handed coordinate system were not correctly transformed to the right-handed coordinate system in ImFusionLib. |
Fixed | Fixed an issue where panning a 2D view (i.e. changing the position of a GlSlice) would not emit GlSlice::signalMatrixChanged even though the matrix did change. |
Fixed | Fixed an issue where loading very large meshes would produce degenerate vertices. |
Changed | When computing per-vertex normals in Mesh, the algorithm now uses an angle-area-based weighting scheme instead of simple uniform weighting. This will make meshes of certain topology appear smoother. |
Added | Added support for orthographic projections in the Camera class.
As a byproduct the interface was refactored significantly. It now exhibits a cleaner separation of the camera model itself and the OpenGL/Computer Vision conventions/matrices. The intrinsics are now stored as individual parameters instead of a single K-matrix while getters/setters allow for easy conversion between the different conventions. Some function names and/or function parameters have changed, however, all of the previously available functionality is still there.
|
Added | Added support for stencil buffers to various OpenGL wrapper classes:
- GlStateGuard will save and restore stencil enabled-state and stencil write mask state.
- GlFramebuffer supports attaching stencil and depth-stencil textures.
- GlImage supports stencil and depth-stencil internal image formats.
- Added GlUtils::isStencilFormat() and GlUtils::isDepthStencilFormat() functions.
|
Added | Added support for loading vertex-only meshes in .ply and .obj format in the MeshIO class. The result of such loading would be an object of a PointCloud type |
Added | We added a conditional shader include syntax which only includes a shader include if a specific pragma is set, e.g.: #pragma conditional_include INCLUDE_MACRO "shader_include.glh"
GlProgram only substitutes this line with the content of the file shader_include.glh if INCLUDE_MACRO is defined. This fixes an issue where version numbers where changed to the highest common version of the shader and all its includes even if the include is not compiled. |
Tags | Description |
Added | Added new class Table class which allows for more readable creation of algorithm statistics and export as CSV file. |
Added | Added support of order-independent transparency (OIT) rendering of semi-transparent meshes. This functionality is managed by the GlOrderIndependentTransparency class and every GlVolumeView holds an instance of it. If this feature is enabled, a semi-transparent GlMesh will render into an auxiliary buffer provided by the OIT interface and a subsequent pass will correctly blend the fragments for each pixel.
If combined with the GlVolumeRendererGlobalIllum, the individual fragments are also correctly sorted into the volume rendering. Due to being OpenGL 3.3-based the GlVolumeRendererBasic does not provide this functionality - it will correctly resolve the blending of all geometry first and then integrate the blended geometry as a whole with the volume rendering.
- Note
- This functionality requires at least OpenGL 4.4.
|
Added | LabelDataComponent instances are now also saved in workspace files in case display settings are to be stored. |
Fixed | Fixed an issue when combining thick MPR rendering with image masks: Now, the mask is applied before performing the thick MPR reduction. Thus, all masked pixels will not be visible in thick MPRs. |
Fixed | Pasting matrices with plain formatting (not Python formatting) is working again. |
Tags | Description |
Added | Added basic support for reading per-face color information from OBJ mesh files in MeshIO::loadFromOBJ(). |
Changed | Introduced Workspace class modelling the workspace file functionality previously implemented in ApplicationController.
The workspace format has changed as a result: Datasets are now loaded explicitly using IoAlgorithms in the Algorithms section instead of using the algorithm entry in the Data section. Furthermore, datasets can now be referenced using arbitrary strings as unique identifiers, which is more robust than the relative indices in the data model.
|
Changed API-Break | The LOG_XYZ macros have been changed to be enclosed by do { .. } while (false) instead of just plain scope braces for improved consistency. As a result, LOG_ macros now must be followed by a semi-colon. |
Added | Added support for saving and loading textures with PLY files in MeshIO. |
Changed | UltrasoundSweep and TrackedSharedImageSet properties now use the modular TransformationMatrixWidget to edit the calibration and registration matrices. This widget should be used whenever a pose matrix editor UI is needed. |
Removed | Removed TransferFunctionFactory::createLabelMapColormap(). Functionality for rendering label maps has been superseeded by the Modality::LABEL enumeration that is evaluated by the view framework to actiave a dedicated rendering path for label maps. |
Changed API-Break | The TransformationConvention enum was moved from the Data class to the Pose namespace and can be found in the new header Base/TransformationConvention.h . |
Changed Deprecation | Matrix interpolation via Pose::interpolate() now requires the TransformationConvention to be specified. If the convention is set to FROMWORLD, input matrices are inverted, interpolated, and the result inverted again. The old function overload without convention is deprecated. |
Added | The new Framework namespace contains some methods to initialize the ImFusionLib without creating an ApplicationController. |
Added Deprecation | Added new modes for GlSlice rendering in volume views:
- Introduced new centerlines and semi-transparent plane render modes.
- Refactored storage of render flags in GlSlice: Instead of one bool per option, they are now consolidated in a Flags<ObjectRenderMode> member. The old getter/setter functions have been marked deprecated.
- Slight refactoring of GlSlice: Use the new GlSlice::render() to render the actual image content only. The GlObject-related render logic is still in GlSlice::draw(). GlSlice::drawOtherSlice() has been made private and logic when to call this function has been moved from GlSliceView to GlSlice.
|
Tags | Description |
Fixed | Fixed alignment issues of Utils::Optional on Visual Studio platforms due to missing support of extended aligned storage. The new implementation can now be safely used with Eigen types or any other type that requires an alignment of more than 8 bytes. |
Fixed | Fixed a potential crash in SignalImpl when emiting the same signal recursively. Recursive emitting of the same signal is now disabled completely and observers will not be notified in such cases.
Furthermore, the member functions regarding blocking of signals have been renamed to improve consistency. The SignalImpl::SignalBlocker interface returned by SignalImpl::blockSignalGuarded() has been removed completely. You can use the more convenient SignalImpl::whileBlocked() interface instead.
|
Removed | Removed the GLPROGARG macros from GlProgram.h . These macros were already a no-op before and can be removed. For GLPROGARG3, a nullptr argument has to be added after the second argument, i.e.: GlProgram(GLPROGARG3("frag", "vert", "#define FOO")) → GlProgram("frag", "vert", nullptr, "#define FOO")
|
Changed | By default SplitChannelsAlgorithm now groups output by channels instead of by frame as previously |
Fixed | Fixed several issues regarding the cmake files shipped with the SDK for macOS. |
Changed Deprecation | Improved DataModel indexing. DataModel::indexOf now returns a linear index for all data including the data in sub-groups. The DataModel::at method was deprecated in favor of DataModel::get (which requires an explicit parent) and operator[] (which also returns data in sub-groups). |
Changed | Factored out common cropping functionality from MaskEditorController and BasicImageProcesssingController. Created new class InteractiveCroppingBox which derives from Interactive<GlBox, BoxAnnotationManipulator> and replaces the direct use of the class template in the Controllers. Removed the logic from GlBox calculating the crop parameters, which can now be found as static methods of the InteractiveCroppingBox class. As a consequence it is now possible to draw the crop region directly in Basic Imaging Processing. This removed the need to initialize the crop region from an existing Box annotation, so that behavior has been removed. |
Added | Added new PoseIO namespace consolidating functions for input/output serialization of pose matrices and affine transformation parameters. |
Added | Added InteractiveCroppingBox class, an interactive object to define crop parameters of a 2D or 3D image directly in the view. |
Added | Properties now support importing matrices from Python-style format. |
Added | Changed the implementation of SharedImageSet to always hold Properties. SharedImageSet::properties() will now always return a valid pointer. Also added new convenience function SharedImage::setSpacing(). |
Fixed | Fixed MeshProcessing::reduceToNumberOfComponents() not working properly. |
Tags | Description |
Changed API-Break | Changed the interface and implementation of animations. Animations are now implemented in terms of Qt animations and are run in the thread from which they are launched. Animations that modify UI widgets should be launched from the GUI thread (previously all animation logic was processed in a non-GUI thread, although most of them updated UI widgets). Also, there is no longer a single AnimationManager responsible for ensuring that only one animation at a time is running on a particular object. Animations can now either be created locally and and launched in a fire-and-forget fashion, or be launched and subsequently managed by whoever created them.
Especially the following has changed and may require according code changes:
- The
AnimationManager.h has been removed and replaced by Animations.h .
- All functions and classes related to animations are encapsulated in the namespace Animations. This partially replaces the AnimationsManager class.
- The Animation class now derives from QPropertyAnimation.
- Among others, the following methods of Animation have been changed/removed:
- Animation::setLoop() has been removed. Instead the QPropertyAnimation::setLoopCount() should be used. An infinite loop can be achieved by passing a -1 as argument.
- Animation::stopAnimation() has been renamed to Animation::cancel().
- SliceAnimation has been removed and its functionality has been moved to ImageView2D::setSliceCenter() and ImageView2D::setSliceMatrix().
- The properties "animateMatrixChange" and "animationsDuration" have been removed from Settings. Instead two new properties have been added:
- "animationsEnabled": En-/Disables all animations.
- "animationSpeed": Scales animation durations by a factor.
See the Animations page in the doxygen documentation for more details.
|
Added | Added ImFusion::Utils::kMeans() which computes a 1D k-Means algorithm on an arbitrary stl container. |
Added | Added highlight functionality to GlPlotView, added selection metaphor to InteractionPlotView to interactively define plot view highlight. You can enable a selection mode in InteractionPlotView that will allow the user to select a region of the plot using the left mouse button. Qt signals notify when the user has selected something. |
Fixed | Fixed an issue where GlFilterSet ignored settings passed via Properties for the XCLAHE and the bilateral filter. |
Added | Added an optional parameter to GlImage::makeCompatible() to specify the number of channels if it is supposed to be different from the reference image. |
Added | Added copy constructor and assignment operator to SharedImage so that it can be used as a regular copyable type. |
Added | Added a method addAlgorithmToHistory in GUI/MainWindowBase.h, allowing to keep track of executed algorithms (if not using the default algorithm controller). |
Tags | Description |
Changed API-Break | Image resampling methods for CPU and GPU have been harmonized and will now return the exact same result regardless of interpolation and smoothing/reduction options. In lieu of the old resample/resampleExact methods in TypedImage with lots of boolean flags, the following methods with named arguments are to be used:
const vec3& spacing,
bool zeroMask = false,
bool allowDimensionChange = false) override;
bool resample(const vec3i& dimensions,
bool zeroMask = false,
SpacingMode Mode for spacing adjustment, e.g. when the physical extent would change after resampling. Definition: Image.h:224
ReductionMode Mode for image reduction (e.g. downsampling, resampling, binning) Definition: Image.h:208
@ Average Average intensity within the reduction box.
InterpolationMode Mode for image interpolation. Definition: Image.h:217
@ Linear Linear interpolation.
Instead of the resampleExact calls, use something like this:
@ Exact A desired spacing is used as it, without any adjustment.
@ Lookup Nearest neighbor look-up, i.e. no reduction at all.
@ Nearest Nearest neighbor look-up, i.e. no interpolation.
The majority voting method in TypedImage::downsample (ill-defined in draw scenarios, e.g. 2:2) has been removed. Instead, all resampling/downsampling methods now support the following reduction modes: Lookup (no reduction at all, before called skipSmoothing), Average (remains the default value), Minimum and Maximum. The latter two were also added to the GPU implementation.
For masks or label maps, we advice to not use ReductionMode::Average, and recommend to utilize InterpolationMode::Nearest.
|
Added | Added a constructor to InvertDeformationAlgorithm in order to construct it from a pure deformation which is not required to be attached to a SharedImageSet yet. |
Added | Added method to sample uniform directions on the circle. |
Added | Added RQ decomposition to ImFusion::Math. |
Changed | Added more fine-grained control which DataComponents are stored in an ImFusionFile. The existing ImFusionFile::ignoreDisplayOptions property has been replaced with ImFusionFile::ignoredDataComponentIds. |
Changed | Changed OpenCV helpers from static class members to free functions in the ImFusion::OpenCV namespace. |
Added | Added conversion method to convert from OpenCV undistortMap to GlDenseDeformation. |
Fixed | Fixed minor bug in BakeDeformationAlgorithm where a matrix was also set on ConeBeamData. |
Fixed | Fixed a bug in FilterController which caused a random crash if the mode selection was changed. |
Fixed | Fixed wrong sign of the return value of Geometry::Plane::distanceTo(). |
Changed | All SDK headers have been reformatted using our company style guide. |
Tags | Description |
Changed API-Break | The copy consturctor of GlImage was refactored to perform a deep copy. Previously only a shallow copy was created and the caller had to call update() explicitly in order to get a deep copy. The descriptor() method was added to the GlImage class in order to make shallow copies more explicit.
GlImage image = {...};
GlImage imageClone{image};
imageClone.update();
GlImage imageClone{image};
GlImage compatibleImage{image};
GlImage compatibleImage{image.descriptor()};
|
Changed | Updated TypedImage and GlImage constructor and update()member functions to consistently update all the information from the image descriptor (i.e. including spacing, shift and scale). The only exception is GlImage::update(GlImage&) since the old API explicitly states that it does not do this. |
Changed | Moved Image::typeId<T>() to a free function Utils::imageTypeId<T>() |
Changed | Can now load meshes that are not 2-manifold. Mesh class will duplicate vertices as required to add the affected triangles. |
Added | Added visualization of mesh vertex normals. |
Added | Picking uniformly distributed unit vectors is not straightforward and we therefore added Geometry::uniformDistributedPointsOnSphere(int N) which picks N uniformly distributed unit vectors, i.e. points on the unit sphere. |
Fixed | Changed the 2D version of GlDenseDeformation::displacement() to act the same as the 3D version. The input is now expected to be world coordinated and the output will be provided in world coordinates as well.
The 2D version used to expect pixel coordinates and also returned the displacement in pixel while the 3D version always used the world coordinate system.
|
Fixed | Filters::boxFilter2D now produces the correct result. |
Changed | Improved ApplicationController interface for easier integration into standalone applications:
- Added empty default implementation to ApplicationController::updateProgress() so that the class is no longer pure virtual. As a result, API are no longer required to inherot from ApplicationController but can use it directly if they want.
- Moved ApplicationController::loadPlugins() interface to the public part so that it can be used from the outside.
- Added ApplicationController::loadPlugin() member function to load a plugin from a single DLL/so file. This enables users to more easily initialize and register plugins that are located outside of the plugins search folder.
|
Fixed | Fixed GlVolumeCompounding algorithm when using masked images as input. The algorithm now supports all combinations of masked images in both the CPU and GPU versions. |
Changed | Improved robustness and format support of NIFTI loader. |
Added | Added IMFUSION_ASSERT() assertion macro to replace the default assert() from the C stdlib in ImFusion code. The ImFusion assertion macro provides additional functionality in terms of allowing for custom error handlers, providing more detailed error messages, and other convenience features. |
Tags | Description |
Fixed | Fixed Properties assignment operator not properly clearing target before copying. Added move copy ctor and move assignment operator. |
Changed API-Break | Changed the internal implementation of ElementwiseDataComponent to perform proper copy-on-write. This fixes a potential bug where editing the components of one element could also change the components of others. To make the underlying semantics more explicit the non-const accessors have been renamed:
|
Changed | Added move semantics to ImFusion::Image class and its descendants, namely MemImage, TypedImage, and GlImage. This allows for using these types as regular value types. |
Removed | GlCircle and GlBall no longer have a setLabel() method. Use the base class' setLabelText() instead, which does the same. |
Added | Added GlLocalExtremalFilter which, for each pixel/voxel of an image, computes the percentage of neighboring pixel which are smaller or greater than the considered pixel. This can be used to detect local maxima with sub pixel accuracy. |
Added | Added options for stippled line rendering in GlLine and GlPolyLine annotations. |
Changed API-Break | Replaced glew with glad for loading OpenGL function pointers. OpenGL functions are now provided by the ImFusion/GL/glad.h header which only contains OpenGL 4.5 Core functions. Deprecated OpenGL functions can still be used through e.g. glew but glewInit has to called manually now.
Some deprecated methods in GlProgram and GlTextRenderer were removed as a result.
|
Tags | Description |
Added | Added 'hidden' attribute to Properties. Hidden parameters and sub properties are not shown in the automatically generated GUI from PropertiesWidget. |
Changed | The windowing configuration of a TransferFunction is now stored internally as window/level instead of min/max to match the design of the rest of the SDK. This avoid numerical precision issues when converting between the different representations. |
Changed | Extended the Camera API to store also the projection configuration. Getter and setter methods are provided for both OpenGL and Vision conventions of camera space. GlVolumeView now uses the Camera class to store projection and view matrix. |
Added | Plugins can now have a version number. The ImFusionLib will check whether all plugins loaded at runtime have the correct version with which it was built. Plugins without versions are excluded from the check. |
Added | The license manager supports proxies, both through the API and the ImFusion Suite application. |
Changed | If the license check fails, the ApplicationController will throw a MissingLicenseException instead of calling std::exit. |
Changed API-Break | The design of the LabelDataComponent has been cleaned up. The 2d/3d color map is now defined implicitly by combining a list of per-label colors with a list of per-label visibility flags. Also the 2d/3d visibility of labels is handled symmetricly. |
Added | Generalized implementation of distance-based blending in MPR views: Introduced the new GlSlice::BlendingMode::DistanceToBorder as first-class blending mode. As a result, the obsolete GlSliceRenderer::specialBlendingMode() interface and GlSliceRendererSweep::encodeDistToBorder property have been removed. An additional parameter has been introduced to GlSliceRenderer::render() to indicate that the renderer should render a distance map into a secondary texture attached to the FBO. Both GlSliceRendererImage and GlSliceRendererSweep support rendering this distance map.
Since US sweeps often have fan masks, GlSweepReconstruction supports computing the distance map based on the sweep mask for improved blending results.
|
Fixed | The DataComponentList equals operator now ignores the order of the DataComponents in the two lists. By definition a DataComponentList is unordered, thus the insertion order should not matter. |
Fixed | Fixed blurry rendering of GlSliceView if the evenness of view width/height does not match the evenness of the image width/height. GlSliceView will now apply an internal half-pixel offset if needed to allow for pixel-perfect lookup. |
Tags | Description |
Added | Signals can now be blocked/muted. Three related methods have been added:
bool SignalImpl<...>::blockSignal(bool) , which blocks or unblocks the signal depending on the argument and returns the previous state for cascading blocks.
SignalImpl<...>::SignalBlocker SignalImpl<...>::blockSignalGuarded(bool) , which blocks or unblocks the signal depending on the argument and returns a scope-guard which resets the state if its scope is left.
bool SignalImpl<...>::signalBlocked() , getter for the blocking flag.
|
Changed | LazyInstatiatedDataComponent no longer derives form DataComponent. In order to add lazy instantiation to your DataComponent you need to derive from DataComponent AND LazyInstatiatedDataComponent. |
Added | Added LazyInstantiatedElementwiseDataComponent which provides lazy instantiation for element-wise DataComponents. |
Added | Added MeshToVolumeRegistrationAlgorithm. |
Added | Improved support for handling and visualizing label maps. Introduces new Data::Modality::LABEL modality, as well as the LabelDataComponent. All default renderers will automatically select a special render path for images with the LABEL modality. The LabelDataComponent allows for storing meta data (e.g. label names) as well as for configuring the visual appearance of the data. |
Tags | Description |
Changed | The behavior of the ConnectedComponentsAlgorithm changed when the input has multiple images. Previously, it was only being computed only on one frame (the one with the focus). For the sake of consistency with most other algorithms, it is now being computed on all images of the input SharedImageSet (which means that it returns a SharedImageSet with the same number of images as the input) |
Changed | Fixed bug when calculating the gradient of an image: the number of channels of the gradient image was incorrectly set to the number of channels of the input image and not to the dimension (2D/3D) of the input image as it should have been. For example, the gradient image of a single channel 2D image should have 2 channels – one for the gradient in the x-direction and one for the gradient in the y-direction. Before the fix, only the gradient in the x-direction was displayed for the in-place and the 'Apply' workflows; the preview image was displayed correctly. |
Changed | The behavior of SharedImageSet::clone() for non-owning SharedImageSets has changed. Previously in this case a new non-owning SharedImageSet was created which contained the same SharedImages. There was no possibility to use this factory method in order to create a deep copy of non-owning SharedImageSets.
Now the SharedImageSet::clone() returns a owning deep copy no matter if the original SharedImageSet is owning or not. The wrapping behavior has been separated into the new method SharedImageSet::nonOwningClone(), which can also be used in order to create a wrapping SharedImageSet from an owning one.
|
Deprecation | The GlLineWidth utility class has been deprecated since glLineWidth() is no longer supported in OpenGL core contexts. You can use GlFixedFunctionPipeline as replacement for rendering wide and/or stippled lines |
Changed | The auto windowing functionality in HistogramDataComponent now uses continuous float computations instead of rounding to the nearest histogram bin. |
Changed | Added an Image Statistics algorithm which calculates the per-channel image statistics of either an entire image, or the image region under a rectangle, circle, or line. |
Added Deprecation | Added mask support to GlReduction. The old GlReduction::reduce() overload taking a GlFramebuffer pointer has been deprecated. |
Added | Added per-channel support to GlHistogram. |
Tags | Description |
Changed Deprecated API-Break | Migrated OpenGL rendering stack to use OpenGL 3.3 core only and deprecated support for compatibility contexts/legacy OpenGL. This brings the following changes to the API:
- Replaced GlState interface with GlViewState that is used to manage the projection and model-view matrix stack.
- Introducing GlFixedFunctionPipeline interface providing a shader mimicking the OpenGL fixed function pipeline with modern means.
- Changed the signature of several render calls to include information about the OpenGL scene state (i.e. a GlViewState or Viewport object). All render calls now use the explicit matrix state provided instead of the implicit state of OpenGL.
- GlProgram::compute() has been deprecated, use GlImageProgram::compute() instead. By default, ImFusionLib will create OpenGL core contexts and GlViews will no longer setup the legacy OpenGL matrix stack for the GlObjects they are hosting. You can enable a compatibility layer by defining the
IMFUSION_USE_OPENGL_COMPATIBILITY environment variable in your system.
|
Added | Inserted the new data type TrackedSharedImageSet into the class hierarchy between SharedImageSet and UltrasoundSweep. This effectively allows to have modality-independent image sets with TrackingStream instances. Most algorithms, which were previously exclusive to ultrasound data have been generalized and do not require the US module anymore. Yet, there are no renderers for visualization in MPR or 3D views due to the unknown nature of the image data (could be projective data). |
Changed API-Break | Elementwise DataComponents, for instance per-frame meta data, are no longer stored in special StreamRecordingDataComponents, which were removed. Instead, appropriate data classes (currently SharedImageSet and TrackingStream) contain an ElementwiseDataComponentList. Apart from accessing the list directly, method overloads allow direct access to the elementwise meta data:
- Note
- You must remove existing StreamRecordingDataComponents and the corresponding factory registrations from your stream plugin.
|
Changed | For SharedImages with only a GlImage representation (i.e. no internal MemImage ) SharedImage::clone() now copies the image data on the GPU instead of downloading it to the CPU. |
Fixed | Fixed const iterators for SharedImageSet. They now work properly with const SharedImageSets as well. |
Added | Added Tensor class. Tensors are a container for dense floating point data of arbitrary dimension that is not meant to be interpreted as an image. In particular, this allows adding 1D data sequences to the data model for the first time. |
Added | Added IO algorithm for the Tensor type and an algorithm for plotting Tensors of rank 1 (i.e. a regular line plot). |
Fixed | Fixed an issue for signed integer textures in combination with AMD graphics cards. Sync operations between host and device memory used to cause an intensity drift of one. This has been fixed. |
Added | Added non-const versions of SharedImage::hasGl, SharedImage::hasCl, SharedImage::hasMem. This enables thread save checking and using the corresponding image if it exists. |
Changed | Changed the default value of ApplicationController::m_prepareShiftOnly has been changed to true. As a result, images are no longer rescaled to fit into the entire data range in postLoad() by default. |
Changed | The behaviour of the ConnectedComponentsAlgorithm changed when the input has multiple images. |