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

advancedusfusion.cpp 10.2 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
    }

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

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

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

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

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

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

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

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

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

}