2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

genericimagerepresentationitk.h 13 KB
Newer Older
1
2
3
4
// ================================================================================================
// 
// This file is part of the CAMPVis Software Framework.
// 
5
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
6
7
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
//      Chair for Computer Aided Medical Procedures
8
9
//      Technische Universitaet Muenchen
//      Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
10
// 
11
12
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
// 
13
14
15
16
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 
// except in compliance with the License. You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
17
// 
18
19
20
21
// Unless required by applicable law or agreed to in writing, software distributed under the 
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
// either express or implied. See the License for the specific language governing permissions 
// and limitations under the License.
22
23
24
25
26
27
28
// 
// ================================================================================================

#ifndef GENERICIMAGEREPRESENTATIONITK_H__
#define GENERICIMAGEREPRESENTATIONITK_H__

#include "core/datastructures/abstractimagerepresentation.h"
29
#include "core/datastructures/imagedata.h"
30
#include "core/tools/weaklytypedpointer.h"
31
32
33
34
35
36
37
38
#include "modules/itk/core/itktypetraits.h"

#include <itkImage.h>
#include <itkImportImageFilter.h>

#include <cstring>  // needed for memcpy

namespace campvis {
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    /**
     * Non templated base class for GenericImageRepresentationItk for easier RTTI check during runtime.
     */
    class AbstractImageRepresentationItk : public AbstractImageRepresentation {
    public:
        /// Virtual destructor
        virtual ~AbstractImageRepresentationItk() {};

        /**
         * Returns a WeaklyTypedPointer to the image data.
         * \note    The pointer is still owned by this ImageRepresentationLocal. If you want a copy, use clone().
         *          Please make sure not to mess with the pointer even if it's not const for technical reasons...
         * \return  A WeaklyTypedPointer to the image data.
         */
        virtual WeaklyTypedPointer getWeaklyTypedPointer() const = 0;
54
55
56
57
58
59
60
61
62

    protected:
        /**
         * Creates a new AbstractImageRepresentationItk. Just calls the base constructor.
         * \param   parent  Parent image data of this representation.
         */
        AbstractImageRepresentationItk(ImageData* parent)
            : AbstractImageRepresentation(parent)
        {};
63
    };
64
65
66
67
68
69
70
71
72

    /**
     * Templated image representation to hold an ITK image.
     *
     * \sa      TypeTraits
     * \tparam  BASETYPE    Base type of the image data (type of a single channel of an image element)
     * \tparam  NUMCHANNELS Number of channels of the image data.
     */
    template<typename BASETYPE, size_t NUMCHANNELS, size_t DIMENSIONALITY>
73
    class GenericImageRepresentationItk : public AbstractImageRepresentationItk {
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
    public:
        /// Type of one single image element
        typedef typename TypeTraits<BASETYPE, NUMCHANNELS>::ElementType ElementType;
        /// Type of one single image element
        typedef typename ItkTypeTraits<BASETYPE, NUMCHANNELS>::ItkElementType ItkElementType;
        /// Type of this template instantiation
        typedef GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY> ThisType;
        /// Typedef for the itk image this representation stores
        typedef itk::Image<ItkElementType, DIMENSIONALITY> ItkImageType;

        /**
         * Template specialization of the ScopedRepresentation defined in GenericAbstractImageRepresentation<T>
         * since some compiler get confused by the nested templates.
         * \note    This is a simple copy and paste from GenericAbstractImageRepresentation<T> with
         *          explicitly named template parameter.
         */
        struct ScopedRepresentation {
            /**
             * Creates a new DataHandle to the data item with the key \a name in \a dc, that behaves like a const GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>*.
             * \param   dc      DataContainer to grab data from
             * \param   name    Key of the DataHandle to search for
             */
            ScopedRepresentation(const DataContainer& dc, const std::string& name)
                : dh(dc.getData(name))
                , data(0)
                , representation(0) 
            {
                if (dh.getData() != 0) {
                    data = dynamic_cast<const ImageData*>(dh.getData());
                    if (data != 0) {
                        representation = data->getRepresentation<ThisType>();
                    }
                }
            };
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
            
            /**
             * Creates a new ScopedRepresentation for the given DataHandle, that behaves like a T*.
             * \param   dh  Source DataHandle
             */
            ScopedRepresentation(DataHandle dataHandle)
                : dh(dataHandle)
                , data(0)
                , representation(0) 
            {
                if (dh.getData() != 0) {
                    data = dynamic_cast<const ImageData*>(dh.getData());
                    if (data != 0) {
                        representation = data->getRepresentation<ThisType>();
                    }
                }
            };
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

            /**
             * Implicit conversion operator to const GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>*.
             * \return  The image representation of the image in the DataHandle, may be 0 when no DataHandle was found,
             *           the data is of the wrong type, or no suitable representation was found.
             */
            operator const ThisType*() {
                return representation;
            }

            /**
             * Implicit arrow operator to const GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>*.
             * \return  The image representation of the image in the DataHandle, may be 0 when no DataHandle was found,
             *           the data is of the wrong type, or no suitable representation was found.
             */
            const ThisType* operator->() const {
                return representation;
            }

            /**
             * Gets the DataHandle.
             * \return dh
             */
            DataHandle getDataHandle() const {
                return dh;
            }

            /**
             * Returns the parent ImageData of this image representation.
             * \return data
             */
            const ImageData* getImageData() const {
                return data;
            }

        private:
            /// Not copy-constructable
            ScopedRepresentation(const ScopedRepresentation& rhs);
            /// Not assignable
            ScopedRepresentation& operator=(const ScopedRepresentation& rhs);

            DataHandle dh;                      ///< DataHandle
            const ImageData* data;              ///< strongly-typed pointer to data, may be 0
            const ThisType* representation;     ///< strongly-typed pointer to the image representation, may be 0
        };

        /**
         * Creates a new strongly typed ImageData object storing the image in the local memory.
         * 
         * \param   parent  Image this representation represents, must not be 0.
         * \param   data    Pointer to the image data, must not be 0, GenericImageRepresentationItk takes ownership of this pointer!
         */
177
        static GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>* create(ImageData* parent, typename ItkImageType::Pointer itkImage);
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196

        /**
         * Destructor
         */
        virtual ~GenericImageRepresentationItk();


        /// \see AbstractImageRepresentation::clone()
        virtual ThisType* clone(ImageData* newParent) const;

        /// \see AbstractImageRepresentation::getLocalMemoryFootprint()
        virtual size_t getLocalMemoryFootprint() const;

        /// \see AbstractImageRepresentation::getVideoMemoryFootprint()
        virtual size_t getVideoMemoryFootprint() const;

        /**
         * Returns a WeaklyTypedPointer to the image data.
         * \note    The pointer is still owned by this ImageRepresentationLocal. If you want a copy, use clone().
197
         *          Please make sure not to mess with the pointer even if it's not const for technical reasons...
198
199
         * \return  A WeaklyTypedPointer to the image data.
         */
200
        virtual WeaklyTypedPointer getWeaklyTypedPointer() const;
201
202
203
204
205
206
207
208
209
210
211
212
213
214

        /**
         * Returns a pointer to the itk image.
         * \return  _itkImage
         */
        typename ItkImageType::Pointer getItkImage();

        /**
         * Returns a const pointer to the itk image.
         * \return  _itkImage
         */
        typename ItkImageType::ConstPointer getItkImage() const;

    protected:
215
216
217
218
219
220
221
        /**
         * Creates a new strongly typed ImageData object storing the image in the local memory.
         * 
         * \param   parent  Image this representation represents, must not be 0.
         * \param   data    Pointer to the image data, must not be 0, GenericImageRepresentationItk takes ownership of this pointer!
         */
        GenericImageRepresentationItk(ImageData* parent, typename ItkImageType::Pointer itkImage);
222
223
224
225
226
227
228

        typename ItkImageType::Pointer _itkImage;

    };

// = Template implementation ======================================================================

229
230
231
232
233
234
235
    template<typename BASETYPE, size_t NUMCHANNELS, size_t DIMENSIONALITY>
    GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>* campvis::GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>::create(ImageData* parent, typename ItkImageType::Pointer itkImage) {
        ThisType* toReturn = new ThisType(parent, itkImage);
        toReturn->addToParent();
        return toReturn;
    }

236
237
    template<typename BASETYPE, size_t NUMCHANNELS, size_t DIMENSIONALITY>
    campvis::GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>::GenericImageRepresentationItk(ImageData* parent, typename ItkImageType::Pointer itkImage)
238
        : AbstractImageRepresentationItk(parent)
239
240
241
242
243
244
245
246
247
248
249
250
251
        , _itkImage(itkImage)
    {
        tgtAssert(_parent->getNumChannels() == NUMCHANNELS, "Number of channels must match parent image's number of channels!");
        tgtAssert(_parent->getDimensionality() == DIMENSIONALITY, "The dimensionality must match parent image's dimensionality!");
    }

    template<typename BASETYPE, size_t NUMCHANNELS, size_t DIMENSIONALITY>
    campvis::GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>::~GenericImageRepresentationItk() {
        
    }

    template<typename BASETYPE, size_t NUMCHANNELS, size_t DIMENSIONALITY>
    GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>* campvis::GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>::clone(ImageData* newParent) const {
252
        typename ItkImageType::Pointer newItkImage = _itkImage->Clone();
253
        return ThisType::create(newParent, newItkImage);
254
255
256
257
    }

    template<typename BASETYPE, size_t NUMCHANNELS, size_t DIMENSIONALITY>
    size_t campvis::GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>::getLocalMemoryFootprint() const {
258
        // just an approximation, nobody knows the ITK internals...
259
260
261
262
263
264
265
266
267
        return sizeof(*this) + sizeof(ItkImageType) + getNumElements() * sizeof(ElementType);
    }

    template<typename BASETYPE, size_t NUMCHANNELS, size_t DIMENSIONALITY>
    size_t campvis::GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>::getVideoMemoryFootprint() const {
        return 0;
    }

    template<typename BASETYPE, size_t NUMCHANNELS, size_t DIMENSIONALITY>
268
    WeaklyTypedPointer campvis::GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>::getWeaklyTypedPointer() const {
269
270
271
272
273
274
275
276
277
278
        return WeaklyTypedPointer(TypeTraits<BASETYPE, NUMCHANNELS>::weaklyTypedPointerBaseType, NUMCHANNELS, _itkImage->GetBufferPointer());
    }

    template<typename BASETYPE, size_t NUMCHANNELS, size_t DIMENSIONALITY>
    typename GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>::ItkImageType::Pointer campvis::GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>::getItkImage() {
        return _itkImage;
    }

    template<typename BASETYPE, size_t NUMCHANNELS, size_t DIMENSIONALITY>
    typename GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>::ItkImageType::ConstPointer campvis::GenericImageRepresentationItk<BASETYPE, NUMCHANNELS, DIMENSIONALITY>::getItkImage() const {
279
        return typename ItkImageType::ConstPointer(_itkImage);
280
281
282
283
    }
}

#endif // GENERICIMAGEREPRESENTATIONITK_H__