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

advancedusfusion.cpp 9.63 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
// ================================================================================================
// 
// This file is part of the CAMPVis Software Framework.
// 
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
//      Chair for Computer Aided Medical Procedures
//      Technische Universitt Mnchen
//      Boltzmannstr. 3, 85748 Garching b. Mnchen, Germany
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
// 
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
// 
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// 
// ================================================================================================

#include "advancedusfusion.h"
#include "tgt/logmanager.h"
#include "tgt/shadermanager.h"
#include "tgt/textureunit.h"

#include "core/datastructures/imagedata.h"
#include "core/datastructures/imagerepresentationgl.h"
#include "core/datastructures/imagerepresentationrendertarget.h"
#include "core/pipeline/processordecoratorbackground.h"

#include "core/classification/simpletransferfunction.h"
41 42
#include "core/classification/geometry1dtransferfunction.h"
#include "core/classification/tfgeometry1d.h"
43 44 45 46 47 48

#include "core/tools/quadrenderer.h"

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

49
    GenericOption<std::string> viewOptions[12] = {
50 51
        GenericOption<std::string>("us", "Ultrasound Only"),
        GenericOption<std::string>("smoothed", "Smoothed US Only"),
52
        GenericOption<std::string>("cm", "Confidence Map US Only"),
53 54
        GenericOption<std::string>("mappingSaturationHSV", "Mapping Uncertainty to Saturation (HSV)"),
        GenericOption<std::string>("mappingSaturationHSL", "Mapping Uncertainty to Saturation (HSL)"),
55 56 57
        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)"),
58 59
        GenericOption<std::string>("mappingLAB", "Mapping Uncertainty L*a*b*"),
        GenericOption<std::string>("mappingHunterLAB", "Mapping Uncertainty Hunter L*a*b*"),
60 61
        GenericOption<std::string>("mappingSharpness", "Mapping Uncertainty to Sharpness"),
        GenericOption<std::string>("pixelate", "Pixelate (Experimental)")
62 63
    };

64
    AdvancedUsFusion::AdvancedUsFusion(IVec2Property& canvasSize)
65 66
        : VisualizationProcessor(canvasSize)
        , p_usImageId("UsImageId", "Ultrasound Input Image", "", DataNameProperty::READ)
67
        , p_blurredImageId("BlurredImageId", "Blurred Ultrasound Image", "", DataNameProperty::READ)
68 69 70 71 72
        , p_gradientImageID("GradientImageId", "Gradient Input Image", "", DataNameProperty::READ)
        , p_confidenceImageID("ConfidenceImageId", "Confidence Map Input", "", DataNameProperty::READ)
        , p_targetImageID("targetImageID", "Output Image", "", DataNameProperty::WRITE)
        , p_sliceNumber("sliceNumber", "Slice Number", 0, 0, 0)
        , p_transferFunction("transferFunction", "Transfer Function", new SimpleTransferFunction(256))
73
        , p_confidenceTF("ConfidenceTF", "Confidence to Uncertainty TF", new Geometry1DTransferFunction(256))
74
        , p_view("View", "Image to Render", viewOptions, 12)
75
        , p_confidenceScaling("ConfidenceScaling", "Confidence Scaling", 1.f, .001f, 1000.f)
76
        , p_blurredScaling("BlurredScaling", "Blurred Scaling", 1.f, .001f, 1000.f)
77
        , p_hue("Hue", "Hue for Uncertainty Mapping", .15f, 0.f, 1.f)
78
        , p_use3DTexture("Use3DTexture", "Use 3D Texture", false)
79 80 81
        , _shader(0)
    {
        addProperty(&p_usImageId);
82
        addProperty(&p_blurredImageId);
83 84
        addProperty(&p_gradientImageID);
        addProperty(&p_confidenceImageID);
85
        addProperty(&p_blurredScaling);
86 87 88
        addProperty(&p_targetImageID);
        addProperty(&p_sliceNumber);
        addProperty(&p_transferFunction);
89
        addProperty(&p_confidenceTF);
90
        addProperty(&p_view);
91 92
        addProperty(&p_confidenceScaling);
        addProperty(&p_hue);
93

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

97 98 99 100 101 102 103 104 105
        decoratePropertyCollection(this);
    }

    AdvancedUsFusion::~AdvancedUsFusion() {

    }

    void AdvancedUsFusion::init() {
        VisualizationProcessor::init();
106
        _shader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "modules/advancedusvis/glsl/advancedusfusion.frag", generateHeader(), false);
107 108 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);
    }

    void AdvancedUsFusion::process(DataContainer& data) {
        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 125 126
                if (img.getDataHandle().getTimestamp() != _sourceImageTimestamp) {
                    // source DataHandle has changed
                    updateProperties(img.getDataHandle());
                    _sourceImageTimestamp = img.getDataHandle().getTimestamp();
127 128 129
                    //p_confidenceTF.getTF()->setImageHandle(confidence.getDataHandle());
                    //_shader->setHeaders(generateHeader());
                    //_shader->rebuild();
130 131
                }

132
                std::pair<ImageData*, ImageRepresentationRenderTarget*> rt = ImageRepresentationRenderTarget::createWithImageData(_renderTargetSize.getValue());
133 134 135

                _shader->activate();
                decorateRenderProlog(data, _shader);
136 137
                if (p_use3DTexture.getValue())
                    _shader->setUniform("_sliceNumber", p_sliceNumber.getValue());
138
                _shader->setUniform("_viewIndex", p_view.getValue());
139 140
                _shader->setUniform("_confidenceScaling", p_confidenceScaling.getValue());
                _shader->setUniform("_hue", p_hue.getValue());
141
                _shader->setUniform("_blurredScale", 1.f / p_blurredScaling.getValue());
142
                
143
                tgt::TextureUnit usUnit, blurredUnit, confidenceUnit, tfUnit, tf2Unit;
144 145 146
                img->bind(_shader, usUnit, "_usImage", "_usTextureParams");
                blurred->bind(_shader, blurredUnit, "_blurredImage", "_blurredTextureParams");
                confidence->bind(_shader, confidenceUnit, "_confidenceMap", "_confidenceTextureParams");
147
                p_transferFunction.getTF()->bind(_shader, tfUnit);
148
                p_confidenceTF.getTF()->bind(_shader, tf2Unit, "_confidenceTF", "_confidenceTFParams");
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169

                rt.second->activate();
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                QuadRdr.renderQuad();
                rt.second->deactivate();

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

                data.addData(p_targetImageID.getValue(), rt.first);
                p_targetImageID.issueWrite();
            }
            else {
                LERROR("Input image must have dimensionality of 3.");
            }
        }
        else {
            LERROR("No suitable input image found.");
        }

170
        validate(INVALID_RESULT);
171 172 173 174 175 176
    }

    void AdvancedUsFusion::updateProperties(DataHandle img) {
        p_transferFunction.getTF()->setImageHandle(img);
        const tgt::svec3& imgSize = static_cast<const ImageData*>(img.getData())->getSize();
        if (p_sliceNumber.getMaxValue() != imgSize.z - 1){
177
            p_sliceNumber.setMaxValue(static_cast<int>(imgSize.z) - 1);
178
        }
179 180 181 182 183 184 185 186
        p_use3DTexture.setValue(static_cast<const ImageData*>(img.getData())->getDimensionality() == 3);
    }

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

}