Slice.h 16.9 KB
Newer Older
1
/*****************************************************************************
2
3
4
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
saubatn's avatar
saubatn committed
5
 * (c) 2001-2016 UJF-Grenoble 1, CNRS, TIMC-IMAG UMR 5525 (GMCAO)
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

#ifndef CANONICAL_SLICE_H
#define CANONICAL_SLICE_H

// -- Core stuff
#include "CamiTKAPI.h"
#include "InterfaceBitMap.h"

// -- vtk stuff
#include <vtkSmartPointer.h>
#include <vtkWindowLevelLookupTable.h>
#include <vtkImageMapToColors.h>
#include <vtkActor.h>
#include <vtkImageActor.h>
#include <vtkImageChangeInformation.h>
#include <vtkImageReslice.h>
#include <vtkMatrix4x4.h>
#include <vtkPolyDataMapper.h>
#include <vtkPlaneSource.h>
#include <vtkTransform.h>
#include <vtkPixel.h>
#include <vtkUnstructuredGrid.h>
#include <vtkDataSetMapper.h>
#include <vtkLine.h>
#include <vtkPolygon.h>
50
51
52
53
#include <vtkTextProperty.h>
#include <vtkTextMapper.h>
#include <vtkAxesActor.h>
#include <vtkTransformPolyDataFilter.h>
54

55
56
namespace camitk {
/**
57
 * @ingroup group_sdk_libraries_core_component
58
 *
59
60
 * @brief
 * Display a slice (i.e. an image or BitMap) of an @ref camitk::ImageComponent "ImageComponent"
61
 *
62
63
64
 * Uses vtkImageActor::SetDisplayExtent for 3D and 2D Axial, Coronal and Sagittal representaiton.
 * Re-position the camera for the 2D views.
 *
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
 *
 *  \verbatim
 *       3D Volume                         2D Slice
 *       ________  /|\
 *      /|      /|  |                      _______
 *     /______ / | _|_slice     ===>      /       /        Displayed in
 *    |  |____|_/|  |  number            /______ /         the window
 *    | /     |//
 *    |/______|/
 *
 *                                          ________________
 *                                         | vtkLookUpTable |
 *                                      ---|                |
 *                                     |   |    lut         |
 *                                     |   |________________|
80
 *  setOriginalVolume(..)              |
81
82
83
84
85
86
87
88
89
90
91
92
93
94
 *   |                                 | setLookUpTable
 *   |                   setInput      |                                   __________________
 *   |   ________________       _______v____________                      |  vtkImageActor   |
 *   |  |  vtkImageData  |     | vtkImageMapToColor |                     |(setDisplayExtent)|
 *   |_\|                |----\|                    |-------------------\ |                  |
 *     /| originalVolume |----/|   imgToMapFilter   |-------------------/ |   image2DActor   |
 *      |________________|     |____________________|     | |             |__________________|
 *                                                        | |
 *                                                        | |              _________________________            __________________
 *                                                        | |             |  vtkTransformFilter     |          |  vtkImageActor   |
 *                                                        |  -----------\ |(setWorldTransformation) | --------\|(setDisplayExtent)|
 *                                                         -------------/ |                         | --------/|                  |
 *                                                                        |                         |          |   image3DActor   |
 *                                                                        |_________________________|          |__________________|
95
96
97
98
99
100
101
 *
 *
 *
 * \endverbatim
 *
 */

102
class CAMITK_API Slice : public InterfaceBitMap {
103
public:
104
105
106
107
108
    /* -------------------------------------------------------------------- */
    /**@{                                                                   */
    /**@name Constructors / Destructors                                     */
    /**@{                                                                   */
    /* -------------------------------------------------------------------- */
109

110
111
    /** Common slices orientation: axial, sagittal, coronal axial_neuro.
     * Axial, Sagittal and Coronal orientation are given in Radiologist point of view.
112
     * The neurologist point of view is displayed in axial_neuro.
113
     *
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
     * The ImageComponent is supposed to be given in RAI orientation !
     * (see Image Reorientation Action Documentation).
     * @image imageRAI.png
     *
     * AXIAL:     from feet  to head of the patient
     * @image axialView.png
     *
     * CORONAL:   from the front to back  of the patient
     * @image coronalView.png
     *
     * SAGITTAL:  from the right to left of the patient
     * @image sagittalView.png
     *
     * AXIAL_NEURO: from head to feet (other side of AXIAL
     *
     */
130
    enum SliceOrientation {
131
132
133
134
135
        AXIAL,
        CORONAL,
        SAGITTAL,
        AXIAL_NEURO
    };
136

137
138
139
140
141
    /** @cond
     * TODO CAMITK_DEPRECATED. this enum option is deprecated. It will be removed in CamiTK 4.0
     * Deprecated.
     * Use SliceOrientation for Slice or ArbitrarySlice class instead.
     */
142
    Slice(vtkSmartPointer<vtkImageData> volume, PossibleOrientation AXIAL_ORIENTATION, vtkSmartPointer<vtkWindowLevelLookupTable> lookupTable=NULL);
143
    ///@cond
144

145
146
    /// Constructor
    Slice(vtkSmartPointer<vtkImageData> volume, SliceOrientation AXIAL_ORIENTATION, vtkSmartPointer<vtkWindowLevelLookupTable> lookupTable=NULL);
147

148
    /// virtual destructor
149
    virtual ~Slice();
150

151
152
153
154
155
    /* -------------------------------------------------------------------- */
    /**@}                                                                   */
    /**@name          InterfaceBitMap implementation                          */
    /**@{                                                                   */
    /* -------------------------------------------------------------------- */
156
157
158

    /// set the original volume image data (the source vtkImageData before any reslice) and refresh the vtk pipeline
    virtual void setOriginalVolume(vtkSmartPointer<vtkImageData> img);
159

160
161
    /// set the transformation for 3D image representation
    virtual void setImageWorldTransform(vtkSmartPointer<vtkTransform>);
162

163

164
    /** Return the vtkImageActor (vtkProp) representing a slice to be displayed in the 2D viewers. */
165
166
    virtual vtkSmartPointer<vtkImageActor> get2DImageActor() const;

167
    /** Return the vtkImageActor (vtkProp) representing a slice to be displayed in the 3D viewers. */
168
169
170
171
172
173
174
175
176
    virtual vtkSmartPointer<vtkImageActor> get3DImageActor() const;


    /** Return the vtkActor used to pick pixels in the slices. */
    virtual vtkSmartPointer<vtkActor> getPickPlaneActor() const;

    /** Return the vtkActor used to pick pixels in the slices. */
    virtual vtkSmartPointer<vtkActor> getPixelActor();

177
178
    /** Return 2D Axes at the proper slice origin */
    virtual vtkSmartPointer<vtkAxesActor> get2DAxesActor();
179

180
181
182
183
184
    /** This method is called when the associated plane has been picked in the InteractiveViewer,
     *  the given coordinates is position where the plane was picked.
     */
    virtual void pixelPicked(double, double, double);

185
186
187
    /** Compute the volume coordinates (xyz) from the resliced coordinates (ijk)
    * @param ijk: given resliced coordiantes (generally from a pixel picked in the pickPlane)
    * @param xyz: output (should be allocated before calling this function)
188
    *     volume coordinates (with image at the origin in RAI convention) computed from the input
189
190
    */
    /// Todo: put this method in abstract slice
191
    void reslicedToVolumeCoords(const double *ijk, double *xyz);
192
    /// Todo, idem...
193
    void volumeToReslicedCoords(const double *xyz, double *ijk);
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

    virtual void updatePickPlane();

    /** Return the number of slices in the image data set. */
    virtual int getNumberOfSlices() const;

    /** Return the index of the current displayed slice. */
    virtual int getSlice() const;

    /** Set the current slice index.
     * If the slice index is less than the first slice index, the first slice is displayed.
     * If the slice index is more than the last slice index, the last slice is displayed.
     * @param s the index of the slice to display (base 0). */
    virtual void setSlice(int s);

209
    /// Set the slice corresponding to the given real image (RAI) coordinates
210
211
    virtual void setSlice(double x, double y, double z);

212
213
214
    /** Return the number of colors in the images.
    * If color is coded on 1 byte, the images are on 256 grey level.
    * If color is coded on 2 bytes, the images are on 4096 grey level (not 65536). */
215
216
217
218
219
    virtual int getNumberOfColors() const;

    /// move the pixel selection green indicator (pixelActor) to the given real position
    virtual void setPixelRealPosition(double, double, double);

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245

    ///@cond
    // TODO CAMITK_DEPRECATED. This section list all the methods marked as deprecated. They are to be removed in CamiTK 4.0
    /** Deprecated.
     * Return the displayed images as a vtkImageData. */
    virtual vtkSmartPointer<vtkImageData> getImageData()const {
        return NULL;
    };
    /** Deprecated. Should be implemented only on ArbitrarySlice.
     * Return the current angle applied to the arbitrary slice */
    virtual double getRotationX() const {
        return 0.0;
    };
    /** Deprecated. Should be implemented only on ArbitrarySlice.
     * Return the current angle applied to the arbitrary slice */
    virtual double getRotationY() const {
        return 0.0;
    };
    /** Deprecated. Should be implemented only on ArbitrarySlice.
     * Return the current angle applied to the arbitrary slice */
    virtual double getRotationZ() const {
        return 0.0;
    };

    /** Deprecated. Should be implemented only on ArbitrarySlice.
     * Set the current angle to the arbitrary slice */
246
    virtual void setRotationX(double angle) {};
247
248
    /** Deprecated. Should be implemented only on ArbitrarySlice.
     * Set the current angle to the arbitrary slice */
249
    virtual void setRotationY(double angle) {};
250
251
    /** Deprecated. Should be implemented only on ArbitrarySlice.
     * Set the current angle to the arbitrary slice */
252
    virtual void setRotationZ(double angle) {};
253
254
    /** Deprecated. Should be implemented only on ArbitrarySlice.
     * Set the current angle to the arbitrary slice */
255
    void applyRotation() {};
256
257
    ///@endcond

258
    // TODO : put all of this into a dedicated interface
259
    /// The additional map for prop (include at least "label" and "glyph")
260
    QMap<QString, vtkSmartPointer<vtkProp> > extraProp;
261
262

    /// Return the vtkProp (actors, volumes and annotations) corresponding to the given name
263
264
265
266
267
268
269
270
271
272
273
274
    virtual vtkSmartPointer<vtkProp> getProp(const QString &);

    /// return the number of additional prop
    virtual unsigned int getNumberOfProp() const;

    /// return an additional prop by its index
    virtual vtkSmartPointer<vtkProp> getProp(unsigned int);

    /** insert an additional prop, defining it by its name (default visibility = false)
     *  @return true if the additional prop was added (i.e. another additional prop of the same name does not exist)
     */
    virtual bool addProp(const QString &,  vtkSmartPointer<vtkProp>);
275

276
277
278
279
    /** remove a given additional prop.
     * @return true if effictively done
     */
    virtual bool removeProp(const QString &);
280
    // END TODO
281

282
283

protected:
284
285
286
287
288
    /* -------------------------------------------------------------------- */
    /**@}                                                                   */
    /**@name          Protected utility methods                             */
    /**@{                                                                   */
    /* -------------------------------------------------------------------- */
289

290
291
292
293
294
295
    /** Initialize Attributes */
    virtual void init();

    /** Initialize actors and everything they need.*/
    virtual void initActors();

296

297
298
299
300
301
302
303
304
305
306
    ///@cond
    // TODO CAMITK_DEPRECATED. This section list all the methods marked as deprecated. They are to be removed in CamiTK 4.0
    /** Deprecated.
     * Use setSliceOrientation(SliceOrientation orientation) instead.
     * Set the orientation (and the transform matrix) of the slice.*/
    void setSliceOrientation(PossibleOrientation orientation);

    /** Deprecated.
     * Set transformation for axial, sagittal and coronal (axial as default for arbitrary)*/
    void setInitialSlicerTransformation() {};
307

308
309
310
311
    /** Deprecated.
     *  Update the coordsTransform attribute (to do when either slicer transformation or
     *  slice number has changed). */
    void updateLocalTransformation() {};
312

313
314
315
    /** Deprecated.
     * Computes local coordiantes from original coordinates and slicer transformation */
    void computeReslicedDimensions() {};
316

317
318
    /** Deprecated.
        Sets the given rotation transformation to the reslicer without
319
    *  checking anything
320
    *  WARNING : This method is not implemented
321
    */
322
    void setTransformOrientation(double *xCosines, double *yCosines, double *zCosines);
323

324
325
326
327
328
329
    /** Deprecated.
     *  Sets the given origin to the reslicer without checking anything.
     *  Warning, if the origin is not at (0,0,s) or any combination, the
     *  pickPlane may not be correctly placed.
     *  WARNING : This method is not implemented
     */
330
    void setTransformOrigin(double *resliceOrigin);
331

332
    ///@endcond
333
334
335
336
337
338
339
340
341


    /* -------------------------------------------------------------------- */
    /**@}                                                                   */
    /**@name          Attributes / Members of the class                     */
    /**@{                                                                   */
    /* ---------------------------------------------------------------------*/

    /** Direction of the reslice */
342
    SliceOrientation sliceOrientation;
343
344
345

    /** Smart pointer to the original volume to reslice (input of the vtk pipeline) */
    vtkSmartPointer<vtkImageData> originalVolume;
346

347
348
349
350
    /// Table containing first and last indices of the image in each direction
    /// 0 & 1 -> x; 2 and 3 -> y; 4 & 5 -> z
    int extent[6];

351
352
353
354
355
    /** Keep track of the slice number                                      */
    int currentSliceIndex;

    /// Common lookup table
    vtkSmartPointer<vtkWindowLevelLookupTable>  lut;
356

357
358
    /** Original volume dimensions in number of voxels (x, y and z) */
    int originalDimensions[3];
359

360
361
    /** Voxel size of the original image volume. Used to compute point coordinates between real world and index world.*/
    double originalSpacing[3];
362

363
364
    /** Real size (originalDimension * originalSpacing in x, y and z) of the original image */
    double originalSize[3];
365
366
367
368
369
370

    /// To be able to extract a slice
    vtkSmartPointer<vtkImageMapToColors>		imgToMapFilter;

    /// 3D actor
    vtkSmartPointer<vtkImageActor>				image3DActor;
371
    /// 2D actor
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
    vtkSmartPointer<vtkImageActor>              image2DActor;
    /**@}                                                                   */


    /**@}                                                                   */
    /**@name          Uses for picking                                      */
    /**@{                                                                   */

    /** A plane used for picking. This plane has the same size and position as the displayed slice. However, it is a
    * real vtkActor that can be easily picked (using 'p' ot 'Ctrl+left click'). */
    vtkSmartPointer<vtkPlaneSource> pickPlane;

    /** Mapper of the the pickPlane. */
    vtkSmartPointer<vtkPolyDataMapper> pickPlaneMapper;

    /** Actor representing the pickPlane. */
    vtkSmartPointer<vtkActor> pickPlaneActor;
389

390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410

    /**
     * Init the pixel actor for pixel picking
     */
    void initPixelActor();

    /** Update the pixel actor position according to the specified pixel picked by the user
     * i.e. Compute and draw the bounding box around the selected pixel.
     * @param x:
     * The absciss value of the selected pixel
     * @param y:
     * The ordinate value of the selected pixel
     * @param z:
     * The depth value of the selected pixel. In the plane, it's always +/- 0.01 in order to the pixel actor to be
     * visible over the slice.
     **/
    void updatePixelActorPosition(double x, double y, double z);


    /** Actor representing a pixel, displayed over the image. */
    vtkSmartPointer<vtkActor> pixelActor;
411
412


413
414
415
    void update2DAxesActorPosition();
    void init2DAxesActor();
    vtkSmartPointer<vtkAxesActor> axes2DActor;
416

417
418
419
420
421
422

};

}

#endif // CANONICAL_SLICE_H