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

Further work on IVUS TC project:

Improved color mixing of predicate-based classification.
parent 622bc116
......@@ -26,7 +26,7 @@ IF(${ModuleEnabled})
SET(ThisModShaderDirectories "modules/advancedusvis/glsl")
SET(ThisModShaderDirectories "modules/advancedusvis/sampledata")
SET(ThisModDependencies vis io preprocessing)
SET(ThisModDependencies vis io preprocessing randomwalk)
ENDIF(${ModuleEnabled})
SET(ThisModStatus TESTING)
......
......@@ -39,6 +39,22 @@ namespace campvis {
class AbstractPointPredicate : public MetaProperty {
public:
// class AbstractColorModulationDecorator {
// public:
// AbstractColorModulationDecorator(AbstractPointPredicate* parent)
// : _parent(parent)
// {}
//
// virtual ~AbstractColorModulationDecorator() {}
//
// virtual const std::string& getHuePart() const = 0;
// virtual const std::string& getSaturationPart() const = 0;
// virtual const std::string& getIntensityPart() const = 0;
// protected:
// AbstractPointPredicate* _parent;
// };
AbstractPointPredicate(const std::string& inputVariable, const std::string& name, const std::string& title);
virtual ~AbstractPointPredicate();
......@@ -164,6 +180,8 @@ namespace campvis {
virtual std::string getPredicateEvaluationGlslString() const;
virtual void setupShader(tgt::Shader* shader) const;
const std::string& getRangeUniformname() const { return _rangeUniformName; };
Vec2Property p_range;
protected:
......
......@@ -31,7 +31,9 @@ namespace campvis {
const std::string PointPredicateHistogram::loggerCat_ = "CAMPVis.modules.advancedusvis.PointPredicateHistogram";;
PointPredicateHistogram::PointPredicateHistogram() {
PointPredicateHistogram::PointPredicateHistogram()
: _glslModulationHackForIvus(false)
{
}
......@@ -81,37 +83,78 @@ namespace campvis {
toReturn += _predicates[i]->getGlslHeader();
}
toReturn +=
"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";
for (size_t i = 0; i < _predicates.size(); ++i) {
if (_predicates[i]->isEnabled()) {
toReturn +=
" if " + _predicates[i]->getPredicateEvaluationGlslString() + " {\n"
" float imp = pow(" + _predicates[i]->getImportanceUniformName() + " * " + StringUtils::toString(_predicates.size()) + ", 2.0);\n"
" impSum.x += " + _predicates[i]->getColorUniformName() + ".x * " + _predicates[i]->getColorUniformName() + ".y * imp;\n"
" impSum.y += " + _predicates[i]->getColorUniformName() + ".y * imp;\n"
" impSum.z += " + _predicates[i]->getIntensityHackUniformName() + ";\n"
" impSum.a += 1.0;\n"
" hueCount += " + _predicates[i]->getColorUniformName() + ".y * imp;\n"
" impCount += imp;\n"
" }\n";
if (_glslModulationHackForIvus) {
toReturn +=
"vec4 performPredicateBasedShading(" + _predicateFunctionArgumentString + ") {\n"
" vec4 enumerator = vec4(0.0, 0.0, 0.0, 0.0);\n"
" vec4 denominator = vec4(0.0, 0.0, 0.0, 0.0);\n";
for (size_t i = 0; i < _predicates.size(); ++i) {
if (_predicates[i]->isEnabled()) {
toReturn +=
" if (" + _predicates[i]->getImportanceUniformName() + " > 0.01 && " + _predicates[i]->getPredicateEvaluationGlslString() + ") {\n"
" float kappa = pow(" + _predicates[i]->getImportanceUniformName() + " * " + StringUtils::toString(_predicates.size()) + ", 2.0);\n";
if (RangePointPredicate* tester = dynamic_cast<RangePointPredicate*>(_predicates[i]))
toReturn += " float chromaFactor = (" + _predicates[i]->getInputVariable() + " - " + tester->getRangeUniformname() + ".x) / (" + tester->getRangeUniformname() + ".y - " + tester->getRangeUniformname() + ".x);\n";
else
toReturn += " float chromaFactor = " + _predicates[i]->getInputVariable() + ";\n";
toReturn +=
/* hue */ " enumerator.x = kappa * " + _predicates[i]->getColorUniformName() + ".x * " + _predicates[i]->getColorUniformName() + ".y * chromaFactor;\n"
/* chroma */ " enumerator.y = kappa * " + _predicates[i]->getColorUniformName() + ".y * chromaFactor;\n"
/* intensity */ " enumerator.z = cm;\n"
/* importance */ " enumerator.w = kappa;\n"
" denominator.x += kappa * " + _predicates[i]->getColorUniformName() + ".y * chromaFactor;\n"
" denominator.y += kappa;\n"
" denominator.z += 1.0;\n"
" denominator.w += 1.0;\n"
" }\n";
}
}
toReturn +=
" if (denominator.w > 0.0) {\n"
" return enumerator / denominator;\n"
" }\n"
" else\n"
" return vec4(0.0);\n"
"}\n\n";
}
else {
toReturn +=
"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";
for (size_t i = 0; i < _predicates.size(); ++i) {
if (_predicates[i]->isEnabled()) {
toReturn +=
" if " + _predicates[i]->getPredicateEvaluationGlslString() + " {\n"
" float imp = pow(" + _predicates[i]->getImportanceUniformName() + " * " + StringUtils::toString(_predicates.size()) + ", 2.0);\n"
" impSum.x += " + _predicates[i]->getColorUniformName() + ".x * " + _predicates[i]->getColorUniformName() + ".y * imp;\n"
" impSum.y += " + _predicates[i]->getColorUniformName() + ".y * imp;\n"
" impSum.z += " + _predicates[i]->getIntensityHackUniformName() + ";\n"
" impSum.a += 1.0;\n"
" hueCount += " + _predicates[i]->getColorUniformName() + ".y * imp;\n"
" impCount += imp;\n"
" }\n";
}
}
toReturn +=
" if (impCount > 0.0) {\n"
" impSum.x /= hueCount;\n"
" impSum.y /= impCount;\n"
" impSum.a = impCount / impSum.a;\n"
" }\n"
" else\n"
" impSum = vec4(0.0);\n"
" return impSum;\n"
"}\n\n";
toReturn +=
" if (impCount > 0.0) {\n"
" impSum.x /= hueCount;\n"
" impSum.y /= impCount;\n"
" impSum.a = impCount / impSum.a;\n"
" }\n"
" else\n"
" impSum = vec4(0.0);\n"
" return impSum;\n"
"}\n\n";
}
toReturn +=
"uint computePredicateBitfield(" + _predicateFunctionArgumentString + ") {\n"
......
......@@ -102,6 +102,8 @@ namespace campvis {
/// Signal emitted when this predicate histogram's GLSL header has changed
sigslot::signal0 s_headerChanged;
bool _glslModulationHackForIvus;
private:
/// Slot called when a predicate's configuration has changed
void onPredicateConfigurationChanged();
......@@ -113,6 +115,7 @@ namespace campvis {
/// The GLSL predicate function argument string (without parentheses).
std::string _predicateFunctionArgumentString;
static const std::string loggerCat_;
};
......
......@@ -74,6 +74,9 @@ namespace campvis {
layout->addWidget(narf, 1, 0, 1, 3);
_lwPredicates->setVisible(false);
narf->setVisible(false);
_slHue = new QSlider(Qt::Vertical, mainWidget);
_slHue->setMinimum(0);
_slHue->setMaximum(100);
......
......@@ -142,8 +142,8 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
float imp = pr.a;
if (imp > 0.0) {
if (pr.z > 0.0)
color = clamp(color + pr.z, 0.0, 1.0);
// if (pr.z > 0.0)
// color = clamp(color + pr.z, 0.0, 1.0);
#ifdef ENABLE_SHADING
// compute gradient (needed for shading and normals)
......@@ -153,10 +153,11 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
// perform predicate-based shading
color.a = 1.0 - pow(1.0 - color.a, _samplingStepSize * SAMPLING_BASE_INTERVAL_RCP);
vec3 hsl = rgb2hsv(color.rgb * color.a);
vec3 hsl = rgb2hcy(color.rgb * color.a);
hsl.xy += pr.xy;
hsl.x = mod(hsl.x, 1.0);
color.rgb = hsv2rgb(hsl);
//hsl.z = cm / 2.0;
color.rgb = hcy2rgb(hsl);
// perform depth-based shading
const float DBS = 0.01;
......
......@@ -56,10 +56,18 @@ void main() {
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);
vec3 hcy = vec3(pr.xy, cm * smoothstep(0.0, 0.5, pr.y));
vec3 mixed = hcy2rgb(hcy);
//vec3 mixed = mix(vec3(ivus), hcy2rgb(hcy), min(cm, pr.y));
//vec3 mixed = mix(vec3(1.0), vec3(1.0, 0.5, 0.0), max(cm, pr.y));
out_Color = vec4(mixed, 1.0);
//vec3 hsl = rgb2hcy(vec3(ivus));
//hsl.xy += pr.xy;
//hsl.x = mod(hsl.x, 1.0);
//hsl.y *= cm;
//out_Color = vec4(hcy2rgb(hsl), 1.0);
}
else if (_useSolidColor) {
out_Color = _color;
......
......@@ -17,7 +17,7 @@ IF(${ModuleEnabled})
)
SET(ThisModShaderDirectories "modules/ivus_tc/glsl")
SET(ThisModDependencies base io devil vis)
SET(ThisModDependencies base io devil vis advancedusvis)
ENDIF(${ModuleEnabled})
SET(ThisModStatus EXPERIMENTAL)
......
......@@ -66,52 +66,63 @@ namespace campvis {
_imageReader.init();
p_readImagesButton.s_clicked.connect(this, &IvusTcDemo::readAndProcessImages);
_lsp.p_ambientColor.setValue(tgt::vec3(.75f));
_lsp.p_shininess.setValue(8.f);
_ve.p_inputVolume.setValue("image.ivus");
_ve.p_outputImage.setValue("combine");
_ve.getVolumeRenderer()->getRaycastingProcessor()->p_samplingRate.setValue(1.f);
_ve.getVolumeRenderer()->getRaycastingProcessor()->p_samplingRate.setValue(.5f);
_renderTargetID.setValue("combine");
_imageReader.p_fileExtension.setValue("bmp");
_imageReader.p_imageSpacing.setValue(tgt::vec3(.1f, .1f, .75f));
_imageReader.p_imageSpacing.setValue(tgt::vec3(.1f, .1f, .6f));
// initialize predicates with default config
PointPredicateHistogramProperty* php = &p_predicateHistogram;
if (php != nullptr) {
PointPredicateHistogram* histogram = php->getPredicateHistogram();
histogram->_glslModulationHackForIvus = true;
AbstractPointPredicate* vpToAdd = 0;
vpToAdd = new RangePointPredicate("ivus", "IvusIntensity", "IVUS Intensity");
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));
vpToAdd->p_color.setValue(tgt::vec2(0.667f, 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));
vpToAdd->p_color.setValue(tgt::vec2(0.165f, 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));
vpToAdd->p_color.setValue(tgt::vec2(0.9f, 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));
vpToAdd->p_color.setValue(tgt::vec2(0.f, 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));
vpToAdd->p_color.setValue(tgt::vec2(0.35f, 1.f));
histogram->addPredicate(vpToAdd);
histogram->resetPredicates(false);
std::vector<float> adjustment(histogram->getPredicates().size(), 0.f);
adjustment[0] = -1.f;
php->adjustImportances(adjustment, php->getCurrentHistogramDistribution());
addProperty(*php);
php->addSharedProperty(_ve.getNestedProperty("VolumeRendererProperties::RaycasterProps::PredicateHistogram"));
......
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