Commit c9f4bd06 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Introducing IvusTcSliceExtractor processor using Predicate Histogram Widget...

Introducing IvusTcSliceExtractor processor using Predicate Histogram Widget for classification setup.
So far just a draft - it is working but the results are not really beautiful.
parent db9ae330
......@@ -11,7 +11,7 @@ IF(${ModuleEnabled})
# Header files (including GLSL files so that they'll appear in VS projects)
FILE(GLOB ThisModHeaders RELATIVE ${ModulesDir}
modules/advancedusvis/datastructures/*.frag
modules/advancedusvis/datastructures/*.h
modules/advancedusvis/glsl/*.frag
modules/advancedusvis/glsl/*.vert
modules/advancedusvis/pipelines/*.h
......
......@@ -60,11 +60,12 @@ namespace campvis {
s_headerChanged.emitSignal();
}
void PointPredicateHistogram::resetPredicates() {
void PointPredicateHistogram::resetPredicates(bool resetColors) {
float imp = 1.f / _predicates.size();
for (size_t i = 0; i < _predicates.size(); ++i) {
_predicates[i]->p_importance.setValue(imp);
_predicates[i]->p_color.setValue(tgt::vec2(0.f));
if (resetColors)
_predicates[i]->p_color.setValue(tgt::vec2(0.f));
}
s_configurationChanged.emitSignal();
......@@ -81,7 +82,7 @@ namespace campvis {
}
toReturn +=
"vec4 performPredicateBasedShading(in float intensity, in float gradientMagnitude, in float gradientAngle, float viewAngle, in float snr, in float vesselness, in float confidence, in uint label) {\n"
"vec4 performPredicateBasedShading(" + _predicateFunctionArgumentString + ") {\n"
" float impCount = 0.0;\n"
" float hueCount = 0.0;\n"
" vec4 impSum = vec4(0.0, 0.0, 0.0, 1.0);\n";
......@@ -113,7 +114,7 @@ namespace campvis {
"}\n\n";
toReturn +=
"uint computePredicateBitfield(in float intensity, in float gradientMagnitude, in float gradientAngle, float viewAngle, in float snr, in float vesselness, in float confidence, in uint label) {\n"
"uint computePredicateBitfield(" + _predicateFunctionArgumentString + ") {\n"
" uint toReturn = 0U;\n";
for (size_t i = 0; i < _predicates.size(); ++i) {
......@@ -155,4 +156,8 @@ namespace campvis {
_predicates[i]->unlockAllProperties();
}
void PointPredicateHistogram::setPredicateFunctionArgumentString(const std::string& pfas) {
_predicateFunctionArgumentString = pfas;
}
}
\ No newline at end of file
......@@ -70,7 +70,7 @@ namespace campvis {
/**
* Resets the predicate histogram to default setting.
*/
void resetPredicates();
void resetPredicates(bool resetColors = true);
/**
* Returns the vector of predicates.
......@@ -90,6 +90,12 @@ namespace campvis {
*/
void setupRenderShader(tgt::Shader* shader) const;
/**
* Sets the GLSL predicate function argument string.
* \param pfas the GLSL predicate function argument string (without parentheses)
*/
void setPredicateFunctionArgumentString(const std::string& pfas);
/// Signal emitted when this predicate histogram's configuration (importance, color, ...) has changed
sigslot::signal0 s_configurationChanged;
......@@ -104,6 +110,8 @@ namespace campvis {
/// vector of all voxel predicates
std::vector<AbstractPointPredicate*> _predicates;
/// The GLSL predicate function argument string (without parentheses).
std::string _predicateFunctionArgumentString;
static const std::string loggerCat_;
......
......@@ -70,6 +70,7 @@ namespace campvis {
}
void PointPredicateEvaluator::init() {
p_histogram.getPredicateHistogram()->setPredicateFunctionArgumentString("in float intensity, in float gradientMagnitude, in float gradientAngle, float viewAngle, in float snr, in float vesselness, in float confidence, in uint label");
VisualizationProcessor::init();
_shader = ShdrMgr.loadWithCustomGlslVersion("core/glsl/passthrough.vert", "", "modules/advancedusvis/glsl/pointpredicateevaluator.frag", generateHeader(), "400");
......
......@@ -62,8 +62,10 @@ namespace campvis {
}
void PointPredicateRaycaster::init() {
p_predicateHistogram.s_headerChanged.connect(this, &PointPredicateRaycaster::onHistogramHeaderChanged);
p_predicateHistogram.getPredicateHistogram()->setPredicateFunctionArgumentString("in float intensity, in float gradientMagnitude, in float gradientAngle, float viewAngle, in float snr, in float vesselness, in float confidence, in uint label");
RaycastingProcessor::init();
p_predicateHistogram.s_headerChanged.connect(this, &PointPredicateRaycaster::onHistogramHeaderChanged);
}
void PointPredicateRaycaster::deinit() {
......
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// 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
//
// 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.
//
// ================================================================================================
in vec3 ex_TexCoord;
in vec4 ex_Color;
out vec4 out_Color;
#include "tools/colorspace.frag"
#include "tools/texture3d.frag"
#include "tools/transferfunction.frag"
uniform sampler3D _ivus;
uniform TextureParameters3D _ivusParams;
uniform sampler3D _cm;
uniform TextureParameters3D _cmParams;
uniform sampler3D _tc;
uniform TextureParameters3D _tcParams;
uniform sampler3D _plaque;
uniform TextureParameters3D _plaqueParams;
uniform mat4 _texCoordsMatrix;
uniform bool _useTexturing = true;
uniform bool _useSolidColor = true;
uniform vec4 _color = vec4(1.0, 1.0, 1.0, 1.0);
void main() {
if (_useTexturing) {
vec3 texel = (_texCoordsMatrix * vec4(ex_TexCoord, 1.0)).xyz;
float ivus = texture(_ivus, texel).r;
float cm = texture(_cm, texel).r;
vec4 tc = texture(_tc, texel);
float plaque = texture(_plaque, texel).r;
vec4 pr = performPredicateBasedShading(ivus, cm, tc, plaque);
vec3 hsl = rgb2hsv(vec3(ivus));
hsl.xy += pr.xy;
hsl.x = mod(hsl.x, 1.0);
out_Color = vec4(hsv2rgb(hsl), 1.0);
}
else if (_useSolidColor) {
out_Color = _color;
}
else {
out_Color = ex_Color;
}
}
......@@ -31,6 +31,8 @@
#include "core/classification/geometry1dtransferfunction.h"
#include "core/classification/tfgeometry1d.h"
#include "modules/ivus_tc/processors/ivustcsliceextractor.h"
namespace campvis {
IvusTcDemo::IvusTcDemo(DataContainer* dc)
......@@ -39,7 +41,7 @@ namespace campvis {
, p_readImagesButton("ReadImagesButton", "Read Images")
, _lsp()
, _imageReader(&_canvasSize)
, _ve(&_canvasSize)
, _ve(&_canvasSize, new IvusTcSliceExtractor(nullptr))
{
// Use AbstractPipeline overload to avoid automatic evaluation of _imageReader processor
// AbstractPipeline::addProcessor(&_imageReader);
......@@ -60,22 +62,56 @@ namespace campvis {
AutoEvaluationPipeline::init();
_imageReader.init();
p_readImagesButton.s_clicked.connect(this, &IvusTcDemo::readAndProcessImages);
_ve.p_inputVolume.setValue("image.ivus");
_ve.p_outputImage.setValue("combine");
_renderTargetID.setValue("combine");
_imageReader.p_inputDirectory.setValue("D:/Medical Data/IVUS/H52 LAD1/IVUS");
_imageReader.p_fileExtension.setValue("bmp");
_imageReader.p_outputImage.setValue("reader.output");
_imageReader.p_outputImage.addSharedProperty(&_ve.p_inputVolume);
Geometry1DTransferFunction* dvrTF = new Geometry1DTransferFunction(128, tgt::vec2(0.f, .05f));
dvrTF->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.12f, .15f), tgt::col4(85, 0, 0, 128), tgt::col4(255, 0, 0, 128)));
dvrTF->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.19f, .28f), tgt::col4(89, 89, 89, 155), tgt::col4(89, 89, 89, 155)));
dvrTF->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.41f, .51f), tgt::col4(170, 170, 128, 64), tgt::col4(192, 192, 128, 64)));
static_cast<TransferFunctionProperty*>(_ve.getNestedProperty("VolumeRendererProperties::RaycasterProps::TransferFunction"))->replaceTF(dvrTF);
static_cast<FloatProperty*>(_ve.getNestedProperty("VolumeRendererProperties::RaycasterProps::SamplingRate"))->setValue(4.f);
// initialize predicates with default config
PointPredicateHistogramProperty* php = dynamic_cast<PointPredicateHistogramProperty*>(_ve.getNestedProperty("SliceExtractorProperties::PredicateHistogram"));
if (php != nullptr) {
PointPredicateHistogram* histogram = php->getPredicateHistogram();
AbstractPointPredicate* vpToAdd = 0;
// vpToAdd = new RangePointPredicate("ivus", "IvusIntensity", "IVUS Intensity Range");
// static_cast<RangePointPredicate*>(vpToAdd)->p_range.setValue(tgt::vec2(0.f, 1.f));
// histogram->addPredicate(vpToAdd);
vpToAdd = new RangePointPredicate("cm", "ConfidenceMap", "Confidence");
static_cast<RangePointPredicate*>(vpToAdd)->p_range.setValue(tgt::vec2(0.25f, 1.f));
histogram->addPredicate(vpToAdd);
vpToAdd = new RangePointPredicate("tc.r", "Calcified", "Calcified Tissue");
static_cast<RangePointPredicate*>(vpToAdd)->p_range.setValue(tgt::vec2(0.15f, 1.f));
vpToAdd->p_color.setValue(tgt::vec2(0.f, 1.f));
histogram->addPredicate(vpToAdd);
vpToAdd = new RangePointPredicate("tc.g", "Fibrotic", "Fibrotic Tissue");
static_cast<RangePointPredicate*>(vpToAdd)->p_range.setValue(tgt::vec2(0.15f, 1.f));
vpToAdd->p_color.setValue(tgt::vec2(0.2f, 1.f));
histogram->addPredicate(vpToAdd);
vpToAdd = new RangePointPredicate("tc.b", "Lipidic", "Lipidic Tissue");
static_cast<RangePointPredicate*>(vpToAdd)->p_range.setValue(tgt::vec2(0.15f, 1.f));
vpToAdd->p_color.setValue(tgt::vec2(0.4f, 1.f));
histogram->addPredicate(vpToAdd);
vpToAdd = new RangePointPredicate("tc.a", "Necrotic", "Necrotic Tissue");
static_cast<RangePointPredicate*>(vpToAdd)->p_range.setValue(tgt::vec2(0.15f, 1.f));
vpToAdd->p_color.setValue(tgt::vec2(0.6f, 1.f));
histogram->addPredicate(vpToAdd);
vpToAdd = new RangePointPredicate("plaque", "Plaque", "Plaque Mask");
static_cast<RangePointPredicate*>(vpToAdd)->p_range.setValue(tgt::vec2(0.5f, 1.f));
vpToAdd->p_color.setValue(tgt::vec2(0.8f, 1.f));
histogram->addPredicate(vpToAdd);
histogram->resetPredicates(false);
addProperty(*php);
}
}
void IvusTcDemo::deinit() {
......
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// 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
//
// 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.
//
// ================================================================================================
#include "ivustcsliceextractor.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/renderdata.h"
#include "core/classification/simpletransferfunction.h"
#include "core/tools/quadrenderer.h"
namespace campvis {
const std::string IvusTcSliceExtractor::loggerCat_ = "CAMPVis.modules.vis.IvusTcSliceExtractor";
IvusTcSliceExtractor::IvusTcSliceExtractor(IVec2Property* viewportSizeProp)
: SliceRenderProcessor(viewportSizeProp, "modules/ivus_tc/glsl/ivustcsliceextractor.frag", "400")
, p_cmImage("CmImage", "Confidence Map Image", "image.cm", DataNameProperty::READ)
, p_tcImage("TcImage", "Tissue Classification Image", "image.tc", DataNameProperty::READ)
, p_plaqueImage("PlaqueImage", "Plaque Mask Image", "image.plaque", DataNameProperty::READ)
, p_predicateHistogram("PredicateHistogram", "predicate Histogram")
{
addProperty(p_cmImage);
addProperty(p_tcImage);
addProperty(p_plaqueImage);
addProperty(p_predicateHistogram);
invalidate(AbstractProcessor::INVALID_SHADER);
p_predicateHistogram.getPredicateHistogram()->setPredicateFunctionArgumentString("in float ivus, in float cm, in vec4 tc, in float plaque");
}
IvusTcSliceExtractor::~IvusTcSliceExtractor() {
}
void IvusTcSliceExtractor::renderImageImpl(DataContainer& dataContainer, const ImageRepresentationGL::ScopedRepresentation& img) {
ImageRepresentationGL::ScopedRepresentation cm(dataContainer, p_cmImage.getValue());
ImageRepresentationGL::ScopedRepresentation tc(dataContainer, p_tcImage.getValue());
ImageRepresentationGL::ScopedRepresentation plaque(dataContainer, p_plaqueImage.getValue());
if (cm && tc && plaque) {
// prepare OpenGL
_shader->activate();
tgt::TextureUnit ivusUnit, cmUnit, tcUnit, plaqueUnit;
img->bind(_shader, ivusUnit, "_ivus", "_ivusParams");
cm->bind(_shader, cmUnit, "_cm", "_cmParams");
tc->bind(_shader, tcUnit, "_tc", "_tcParams");
plaque->bind(_shader, plaqueUnit, "_plaque", "_plaqueParams");
{
tgt::Shader::IgnoreUniformLocationErrorGuard guard(_shader);
p_predicateHistogram.getPredicateHistogram()->setupRenderShader(_shader);
}
tgt::mat4 identity = tgt::mat4::identity;
_shader->setUniform("_texCoordsMatrix", _texCoordMatrix);
_shader->setUniform("_modelMatrix", identity);
_shader->setUniform("_viewMatrix", _viewMatrix);
_shader->setUniform("_projectionMatrix", identity);
_shader->setUniform("_useTexturing", true);
_shader->setUniform("_useSolidColor", true);
// render slice
FramebufferActivationGuard fag(this);
createAndAttachColorTexture();
createAndAttachDepthTexture();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QuadRdr.renderQuad();
if (p_renderCrosshair.getValue())
renderCrosshair(img);
renderGeometry(dataContainer, img);
_shader->deactivate();
tgt::TextureUnit::setZeroUnit();
dataContainer.addData(p_targetImageID.getValue(), new RenderData(_fbo));
}
}
void IvusTcSliceExtractor::onHistogramHeaderChanged() {
invalidate(INVALID_SHADER);
}
std::string IvusTcSliceExtractor::getGlslHeader() {
return SliceRenderProcessor::getGlslHeader() + p_predicateHistogram.getPredicateHistogram()->getGlslHeader();
}
}
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// 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
//
// 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.
//
// ================================================================================================
#ifndef IVUSTCSLICEEXTRACTOR_H__
#define IVUSTCSLICEEXTRACTOR_H__
#include "core/pipeline/slicerenderprocessor.h"
#include "modules/advancedusvis/properties/pointpredicatehistogramproperty.h"
namespace campvis {
/**
* IVUS Tissue Classification Slice Rendering with Predicate Histogram-based classification.
*/
class IvusTcSliceExtractor : public SliceRenderProcessor {
public:
/**
* Constructs a new IvusTcSliceExtractor Processor
**/
IvusTcSliceExtractor(IVec2Property* viewportSizeProp);
/**
* Destructor
**/
virtual ~IvusTcSliceExtractor();
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "IvusTcSliceExtractor"; };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "IVUS Tissue Classification Slice Rendering with Predicate Histogram-based classification."; };
/// \see AbstractProcessor::getAuthor()
virtual const std::string getAuthor() const { return "Christian Schulte zu Berge <christian.szb@in.tum.de>"; };
/// \see AbstractProcessor::getProcessorState()
virtual ProcessorState getProcessorState() const { return AbstractProcessor::EXPERIMENTAL; };
DataNameProperty p_cmImage;
DataNameProperty p_tcImage;
DataNameProperty p_plaqueImage;
PointPredicateHistogramProperty p_predicateHistogram;
protected:
/// \see SliceRenderProcessor::renderImageImpl
virtual void renderImageImpl(DataContainer& dataContainer, const ImageRepresentationGL::ScopedRepresentation& img);
virtual std::string getGlslHeader();
private:
void onHistogramHeaderChanged();
static const std::string loggerCat_;
};
}
#endif // IVUSTCSLICEEXTRACTOR_H__
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment