advancedusfusion.cpp 9.99 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
// 
// ================================================================================================

#include "advancedusfusion.h"
26
27
28
#include "cgt/logmanager.h"
#include "cgt/shadermanager.h"
#include "cgt/textureunit.h"
29
30
31

#include "core/datastructures/imagedata.h"
#include "core/datastructures/imagerepresentationgl.h"
32
#include "core/datastructures/renderdata.h"
33
34
35
#include "core/pipeline/processordecoratorbackground.h"

#include "core/classification/simpletransferfunction.h"
36
37
#include "core/classification/geometry1dtransferfunction.h"
#include "core/classification/tfgeometry1d.h"
38
39
40
41
42
43

#include "core/tools/quadrenderer.h"

namespace campvis {
    const std::string AdvancedUsFusion::loggerCat_ = "CAMPVis.modules.vis.AdvancedUsFusion";

44
    GenericOption<std::string> viewOptions[13] = {
45
46
        GenericOption<std::string>("us", "Ultrasound Only"),
        GenericOption<std::string>("smoothed", "Smoothed US Only"),
47
        GenericOption<std::string>("cm", "Confidence Map US Only"),
48
49
        GenericOption<std::string>("mappingSaturationHSV", "Mapping Uncertainty to Saturation (HSV)"),
        GenericOption<std::string>("mappingSaturationHSL", "Mapping Uncertainty to Saturation (HSL)"),
50
51
52
        GenericOption<std::string>("mappingSaturationTSL", "Mapping Uncertainty to Saturation (TSL)"),
        GenericOption<std::string>("mappingChromacityHCL", "Mapping Uncertainty to Chromacity (HCL)"),
        GenericOption<std::string>("mappingChromacityHCY", "Mapping Uncertainty to Chromacity (HCY)"),
53
54
        GenericOption<std::string>("mappingLAB", "Mapping Uncertainty L*a*b*"),
        GenericOption<std::string>("mappingHunterLAB", "Mapping Uncertainty Hunter L*a*b*"),
55
        GenericOption<std::string>("mappingSharpness", "Mapping Uncertainty to Sharpness"),
56
57
        GenericOption<std::string>("pixelate", "Pixelate (Experimental)"),
        GenericOption<std::string>("colorOverlay", "Color Overlay")
58
59
    };

60
61
    AdvancedUsFusion::AdvancedUsFusion(IVec2Property* viewportSizeProp)
        : VisualizationProcessor(viewportSizeProp)
62
        , p_usImageId("UsImageId", "Ultrasound Input Image", "", DataNameProperty::READ)
63
        , p_blurredImageId("BlurredImageId", "Blurred Ultrasound Image", "", DataNameProperty::READ)
64
65
66
        , p_gradientImageID("GradientImageId", "Gradient Input Image", "", DataNameProperty::READ)
        , p_confidenceImageID("ConfidenceImageId", "Confidence Map Input", "", DataNameProperty::READ)
        , p_targetImageID("targetImageID", "Output Image", "", DataNameProperty::WRITE)
67
        , p_renderToTexture("RenderToTexture", "Render to an OpenGL Texture", false)
68
        , p_sliceNumber("sliceNumber", "Slice Number", 0, 0, 0)
69
        , p_transferFunction("transferFunction", "Transfer Function", new SimpleTransferFunction(256))
70
        , p_confidenceTF("ConfidenceTF", "Confidence to Uncertainty TF", new Geometry1DTransferFunction(256))
71
        , p_view("View", "Image to Render", viewOptions, 13)
72
        , p_blurredScaling("BlurredScaling", "Blurred Scaling", 1.f, .001f, 1000.f, 0.1f)
Sebastian Pölsterl's avatar
Sebastian Pölsterl committed
73
        , p_confidenceScaling("ConfidenceScaling", "Confidence Scaling", 1.f, .001f, 1000.f, 0.1f)
74
        , p_hue("Hue", "Hue for Uncertainty Mapping", .15f, 0.f, 1.f)
75
        , p_use3DTexture("Use3DTexture", "Use 3D Texture", false)
76
77
        , _shader(0)
    {
78
79
80
81
82
        addProperty(p_usImageId, INVALID_PROPERTIES | INVALID_RESULT);
        addProperty(p_blurredImageId);
        addProperty(p_gradientImageID);
        addProperty(p_confidenceImageID);
        addProperty(p_blurredScaling);
83
        addProperty(p_renderToTexture);
84
85
86
87
88
89
90
        addProperty(p_targetImageID);
        addProperty(p_sliceNumber);
        addProperty(p_transferFunction);
        addProperty(p_confidenceTF);
        addProperty(p_view);
        addProperty(p_confidenceScaling);
        addProperty(p_hue);
91

92
        Geometry1DTransferFunction* tf = static_cast<Geometry1DTransferFunction*>(p_confidenceTF.getTF());
93
        tf->addGeometry(TFGeometry1D::createQuad(cgt::vec2(0.f, 1.f), cgt::col4(0, 0, 0, 96), cgt::col4(0, 0, 0, 0)));
94

95
96
97
98
99
100
101
102
103
        decoratePropertyCollection(this);
    }

    AdvancedUsFusion::~AdvancedUsFusion() {

    }

    void AdvancedUsFusion::init() {
        VisualizationProcessor::init();
104
        _shader = ShdrMgr.load("core/glsl/passthrough.vert", "modules/advancedusvis/glsl/advancedusfusion.frag", generateHeader());
105
106
107
108
109
110
111
112
113
        _shader->setAttributeLocation(0, "in_Position");
        _shader->setAttributeLocation(1, "in_TexCoord");
    }

    void AdvancedUsFusion::deinit() {
        VisualizationProcessor::deinit();
        ShdrMgr.dispose(_shader);
    }

114
    void AdvancedUsFusion::updateResult(DataContainer& data) {
115
        ImageRepresentationGL::ScopedRepresentation img(data, p_usImageId.getValue());
116
        ImageRepresentationGL::ScopedRepresentation blurred(data, p_blurredImageId.getValue());
117
118
        ImageRepresentationGL::ScopedRepresentation confidence(data, p_confidenceImageID.getValue());

119
        if (img != 0 && blurred != 0 && confidence != 0) {
120
            if (img->getDimensionality() >= 2) {
121
122
                _shader->activate();
                decorateRenderProlog(data, _shader);
123
124
                if (p_use3DTexture.getValue())
                    _shader->setUniform("_sliceNumber", p_sliceNumber.getValue());
125
                _shader->setUniform("_viewIndex", p_view.getValue());
126
127
                _shader->setUniform("_confidenceScaling", p_confidenceScaling.getValue());
                _shader->setUniform("_hue", p_hue.getValue());
128
                _shader->setUniform("_blurredScale", 1.f / p_blurredScaling.getValue());
129
                
130
                cgt::TextureUnit usUnit, blurredUnit, confidenceUnit, tfUnit, tf2Unit;
131
132
133
                img->bind(_shader, usUnit, "_usImage", "_usTextureParams");
                blurred->bind(_shader, blurredUnit, "_blurredImage", "_blurredTextureParams");
                confidence->bind(_shader, confidenceUnit, "_confidenceMap", "_confidenceTextureParams");
134
                p_transferFunction.getTF()->bind(_shader, tfUnit);
135
                p_confidenceTF.getTF()->bind(_shader, tf2Unit, "_confidenceTF", "_confidenceTFParams");
136

137
138
                if (p_renderToTexture.getValue() == true) {
                    cgt::vec3 size = img->getSize();
139
                    cgt::Texture* resultTexture = new cgt::Texture(GL_TEXTURE_2D, size, GL_RGB8, cgt::Texture::LINEAR);
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

                    _fbo->activate();
                    glViewport(0, 0, static_cast<GLsizei>(size.x), static_cast<GLsizei>(size.y));
                    _fbo->attachTexture(resultTexture, GL_COLOR_ATTACHMENT0, 0, 0);
                    LGL_ERROR;

                    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                    QuadRdr.renderQuad();

                    _fbo->detachAll();
                    _fbo->deactivate();
                    _shader->deactivate();
                    ImageData* id = new ImageData(img->getParent()->getDimensionality(), size, 3);
                    ImageRepresentationGL::create(id, resultTexture);
                    const ImageMappingInformation& imi = img->getParent()->getMappingInformation();
                    id->setMappingInformation(img->getParent()->getMappingInformation());
                    cgt::TextureUnit::setZeroUnit();

                    data.addData(p_targetImageID.getValue(), id);
                }
                else {
                    FramebufferActivationGuard fag(this);
                    createAndAttachColorTexture();
                    createAndAttachDepthTexture();

                    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                    QuadRdr.renderQuad();

                    decorateRenderEpilog(_shader);
                    _shader->deactivate();
                    cgt::TextureUnit::setZeroUnit();

                    data.addData(p_targetImageID.getValue(), new RenderData(_fbo));
                }
174
175
176
177
178
179
            }
            else {
                LERROR("Input image must have dimensionality of 3.");
            }
        }
        else {
180
            LDEBUG("No suitable input image found.");
181
182
183
        }
    }

184
    void AdvancedUsFusion::updateProperties(DataContainer& dc) {
185
        ScopedTypedData<ImageData> img(dc, p_usImageId.getValue());
186

187
        p_transferFunction.setImageHandle(img.getDataHandle());
188
189
190
191
192
193
        if (img != nullptr) {
            const cgt::svec3& imgSize = img->getSize();
            if (static_cast<cgt::svec3::ElemType> (p_sliceNumber.getMaxValue()) != imgSize.z - 1){
                p_sliceNumber.setMaxValue(static_cast<int>(imgSize.z) - 1);
            }
            p_use3DTexture.setValue(img->getDimensionality() == 3);
194
        }
195
196
197
198
199
200
201
    }

    std::string AdvancedUsFusion::generateHeader() const {
        std::string toReturn = getDecoratedHeader();
        if (p_use3DTexture.getValue())
            toReturn += "#define USE_3D_TEX 1\n";
        return toReturn;
202
203
204
    }

}