The name of the initial branch for new projects is now "main" instead of "master". Existing projects remain unchanged. More information: https://doku.lrz.de/display/PUBLIC/GitLab

advancedusfusion.cpp 10.3 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[14] = {
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
        GenericOption<std::string>("pixelate", "Pixelate (Experimental)"),
57 58
        GenericOption<std::string>("colorOverlay", "Color Overlay"),
        GenericOption<std::string>("mappingHybrid", "Hybrid Mapping to Chroma and Sharpness")
59 60
    };

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

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

99 100 101 102 103 104 105 106 107
        decoratePropertyCollection(this);
    }

    AdvancedUsFusion::~AdvancedUsFusion() {

    }

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

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

118
    void AdvancedUsFusion::updateResult(DataContainer& data) {
119
        ImageRepresentationGL::ScopedRepresentation img(data, p_usImageId.getValue());
120
        ImageRepresentationGL::ScopedRepresentation blurred(data, p_blurredImageId.getValue());
121 122
        ImageRepresentationGL::ScopedRepresentation confidence(data, p_confidenceImageID.getValue());

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

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

                    _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);
                    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));
                }
178 179 180 181 182 183
            }
            else {
                LERROR("Input image must have dimensionality of 3.");
            }
        }
        else {
184
            LDEBUG("No suitable input image found.");
185 186 187
        }
    }

188
    void AdvancedUsFusion::updateProperties(DataContainer& dc) {
189
        ScopedTypedData<ImageData> img(dc, p_usImageId.getValue());
190

191
        p_transferFunction.setImageHandle(img.getDataHandle());
192 193 194 195 196 197
        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);
198
        }
199 200

        p_mixFactor.setVisible(p_view.getOptionId() == "mappingHybrid");
201 202 203 204 205 206 207
    }

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

}