Commit 543f0a26 authored by Declara Denis's avatar Declara Denis Committed by Christian Schulte zu Berge
Browse files

Improved CudaConfidenceMaps Piepline

* CMake has been improved and now supports for example module dependencies
  and works for visual studio compilations
* An image cropping stage has been added to the pipeline to trim any
  garbage that might show up at the border during image acquisition.
* Added support for 2D images to the GlImageCrop Processor
parent 2914991a
# CMake file for vis module
# modules/cudaconfidencemaps/cudaconfidencemaps.cmake
# CMake file for the cuda confidence maps module
IF(${ModuleEnabled})
# Find CUDA
# Set module status (valid values are STABLE, TESTING and EXPERIMENTAL)
SET(ThisModStatus EXPERIMENTAL)
# Set whether this module has external dependencies that are not shipped with CAMPVis.
SET(ThisModExternalDependencies TRUE)
# The files and assignments need only to be parsed if the module is enabled
IF(ModuleEnabled)
FIND_PACKAGE(CUDA REQUIRED)
if(CUDA_FOUND)
IF(CUDA_FOUND)
# Source files:
FILE(GLOB ThisModSources RELATIVE ${ModulesDir}
modules/cudaconfidencemaps/core/*.cpp
......@@ -21,35 +27,42 @@ IF(${ModuleEnabled})
modules/cudaconfidencemaps/processors/*.h
)
IF(NOT WIN32)
# Define the GLSL shader path, so that all needed shaders will be deployed to target directory
SET(ThisModShaderDirectories "modules/cudaconfidencemaps/glsl")
# Define dependency modules
SET(ThisModDependencies preprocessing advancedusvis openigtlink fontrendering)
IF(WIN32)
SET(CUDA_PROPAGATE_HOST_FLAGS ON)
ELSE()
# Otherwise -std=c++11 is passed to the compiler on linux. However official
# c++11 support for cuda is only available in CUDA 7
set(CUDA_PROPAGATE_HOST_FLAGS OFF)
SET(CUDA_PROPAGATE_HOST_FLAGS OFF)
ENDIF()
IF(CMAKE_BUILD_TYPE MATCHES RELEASE)
# Enable optimizations when building a release version
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};-O3)
IF(CMAKE_BUILD_TYPE MATCHES RELEASE)
SET(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};-O3)
ENDIF()
# Build CUDA sources
file(GLOB cuda_SOURCES modules/cudaconfidencemaps/core/*.cu)
CUDA_ADD_LIBRARY(CudaConfidenceMaps_CUDA STATIC
# CUSP Include directory
CUDA_INCLUDE_DIRECTORIES(${ThisModDir}/ext/cusplibrary-0.4.0)
# Build CUDA portion of the code (STATICALLY!?)
FILE(GLOB cuda_SOURCES modules/cudaconfidencemaps/core/*.cu)
CUDA_ADD_LIBRARY(cudaconfidencemaps-cuda STATIC
${cuda_SOURCES}
)
# Make sure code can find the CUSP include files included with this module
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};"-I ${ThisModDir}/ext/cusplibrary-0.4.0")
LIST(APPEND ThisModExternalLibs CudaConfidenceMaps_CUDA)
#SET(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};"-I ${ThisModDir}/ext/cusplibrary-0.4.0")
set(CUDA_NVCC_FLAGS "ajkladjfl" CACHE STRING "adsf")
SET(ThisModShaderDirectories "modules/cudaconfidencemaps/glsl")
SET(ThisModDependencies base io)
else()
# Link CUDA code to module
LIST(APPEND ThisModExternalLibs cudaconfidencemaps-cuda)
ELSE()
MESSAGE(FATAL_ERROR "Could not find CUDA SDK.")
endif()
ENDIF(${ModuleEnabled})
ENDIF()
SET(ThisModStatus EXPERIMENTAL)
SET(ThisModExternalDependencies TRUE)
ENDIF(ModuleEnabled)
\ No newline at end of file
......@@ -33,6 +33,7 @@ namespace campvis {
CudaConfidenceMapsDemo::CudaConfidenceMapsDemo(DataContainer* dc)
: AutoEvaluationPipeline(dc)
, _usIgtlReader()
, _usCropFilter(&_canvasSize)
, _usBlurFilter(&_canvasSize)
, _usResampler(&_canvasSize)
, _usMapsSolver()
......@@ -56,6 +57,7 @@ namespace campvis {
, _statisticsLastUpdateTime()
{
addProcessor(&_usIgtlReader);
addProcessor(&_usCropFilter);
addProcessor(&_usBlurFilter);
addProcessor(&_usResampler);
addProcessor(&_usMapsSolver);
......@@ -96,7 +98,10 @@ namespace campvis {
// Create connectors
_usIgtlReader.p_targetImagePrefix.setValue("us.igtl.");
_usBlurFilter.p_inputImage.setValue("us.igtl.ImageClient");
_usCropFilter.p_inputImage.setValue("us.igtl.CAMPUS");
_usCropFilter.p_outputImage.setValue("us");
_usBlurFilter.p_inputImage.setValue("us");
_usBlurFilter.p_outputImage.setValue("us.blurred");
_usBlurFilter.p_outputImage.addSharedProperty(&_usResampler.p_inputImage);
_usBlurFilter.p_outputImage.addSharedProperty(&_usFusion.p_blurredImageId);
......@@ -107,7 +112,7 @@ namespace campvis {
_usMapsSolver.p_outputConfidenceMap.setValue("us.confidence");
_usMapsSolver.p_outputConfidenceMap.addSharedProperty(&_usFusion.p_confidenceImageID);
_usFusion.p_usImageId.setValue("us.igtl.ImageClient");
_usFusion.p_usImageId.setValue("us");
_usFusion.p_targetImageID.setValue("us.fusion");
_usFusion.p_view.setValue(12);
_usFusion.p_renderToTexture.setValue(true);
......@@ -150,12 +155,13 @@ namespace campvis {
// Make sure that the whole pipeline gets invalidated
_usBlurFilter.invalidate(AbstractProcessor::INVALID_RESULT);
_usBlurFilter.invalidate(AbstractProcessor::INVALID_RESULT);
_usCropFilter.invalidate(AbstractProcessor::INVALID_RESULT);
_usResampler.invalidate(AbstractProcessor::INVALID_RESULT);
_usMapsSolver.invalidate(AbstractProcessor::INVALID_RESULT);
_usFusion.invalidate(AbstractProcessor::INVALID_RESULT);
executeProcessorAndCheckOpenGLState(&_usIgtlReader);
executeProcessorAndCheckOpenGLState(&_usCropFilter);
executeProcessorAndCheckOpenGLState(&_usBlurFilter);
executeProcessorAndCheckOpenGLState(&_usResampler);
......@@ -166,20 +172,22 @@ namespace campvis {
executeProcessorAndCheckOpenGLState(&_usFusion);
executeProcessorAndCheckOpenGLState(&_usFanRenderer);
auto endTime = tbb::tick_count::now();
if ((startTime - _statisticsLastUpdateTime).seconds() > 0.5f) {
_statisticsLastUpdateTime = startTime;
tbb::tick_count endTime = tbb::tick_count::now();
auto ms = (endTime - startTime).seconds() * 1000.0f;
auto solverMs = (solverEndTime - solverStartTime).seconds() * 1000.0f;
std::stringstream string;
string << "Execution time: " << static_cast<int>(ms) << "ms" << std::endl;
string << "Solver time: " << static_cast<int>(solverMs) << "ms" << std::endl;
string << "CG Iterations: " << _usMapsSolver.getActualConjugentGradientIterations() << std::endl;
string << "Error: " << _usMapsSolver.getResidualNorm() << std::endl;
_usFanRenderer.p_text.setValue(string.str());
}
auto endTime = tbb::tick_count::now();
auto ms = (solverEndTime - solverStartTime).seconds() * 1000.0f;
auto iterationsPerMs = _usMapsSolver.getActualConjugentGradientIterations() / ms;
......
......@@ -29,8 +29,8 @@
#include "modules/base/processors/matrixprocessor.h"
#include "core/pipeline/autoevaluationpipeline.h"
#include "modules/devil/processors/devilimagereader.h"
#include "modules/preprocessing/processors/glgaussianfilter.h"
#include "modules/preprocessing/processors/glimagecrop.h"
#include "modules/preprocessing/processors/glimageresampler.h"
#include "modules/cudaconfidencemaps/processors/cudaconfidencemapssolver.h"
#include "modules/cudaconfidencemaps/processors/usfanrenderer.h"
......@@ -72,7 +72,7 @@ namespace campvis {
protected:
OpenIGTLinkClient _usIgtlReader;
DevilImageReader _usReader;
GlImageCrop _usCropFilter;
GlGaussianFilter _usBlurFilter;
GlImageResampler _usResampler;
CudaConfidenceMapsSolver _usMapsSolver;
......
......@@ -42,13 +42,13 @@ namespace campvis {
, p_resetResult("ResetSolution", "Reset solution vector")
, p_use8Neighbourhood("Use8Neighbourhood", "Use 8 Neighbourhood (otherwise 4)", true)
, p_iterations("IterationCount", "Conjugate Gradient Iterations", 200, 1, 500)
, p_gradientScaling("GradientScaling", "Scaling factor for gradients", 2.0f, 0.001, 10)
, p_paramAlpha("Alpha", "Alpha (TGC)", 2.0f, 0.001, 10)
, p_paramBeta("Beta", "Beta (Weight mapping)", 20.0f, 0.001, 200)
, p_paramGamma("Gamma", "Gamma (Diagonal penalty)", 0.03f, 0.001, 0.5)
, p_gradientScaling("GradientScaling", "Scaling factor for gradients", 2.0f, 0.001f, 10.0f)
, p_paramAlpha("Alpha", "Alpha (TGC)", 2.0f, 0.001f, 10.0f)
, p_paramBeta("Beta", "Beta (Weight mapping)", 20.0f, 0.001f, 200.0f)
, p_paramGamma("Gamma", "Gamma (Diagonal penalty)", 0.03f, 0.001f, 0.5f)
, p_useAlphaBetaFilter("UseAlphaBetaFilter", "Use Alpha-Beta-Filter", true)
, p_filterAlpha("FilterAlpha", "Filter Alpha", 0.36f, 0.0, 1.0)
, p_filterBeta("FilterBeta", "Filter Beta", 0.005f, 0.0, 1.0)
, p_filterAlpha("FilterAlpha", "Filter Alpha", 0.36f, 0.0f, 1.0f)
, p_filterBeta("FilterBeta", "Filter Beta", 0.005f, 0.0f, 1.0f)
, _solver()
{
......@@ -99,7 +99,7 @@ namespace campvis {
auto image = (unsigned char*)img->getWeaklyTypedPointer()._pointer;
_solver.uploadImage(image, size.x, size.y, gradientScaling, alpha, beta, gamma, use8Neighbourhood);
_solver.solve(iterations, 1e-10);
_solver.solve(iterations, 1e-10f);
const float *solution = _solver.getSolution(size.x, size.y);
......
......@@ -101,7 +101,7 @@ namespace campvis {
float innerRadius = p_innerRadius.getValue();
// calculate bounding box of the US fan
cgt::vec3 bbCenter = cgt::vec3(0, cos(halfAngle)*innerRadius/2.0f + 0.5, 0.0f);
cgt::vec3 bbCenter = cgt::vec3(0.0f, cos(halfAngle)*innerRadius/2.0f + 0.5f, 0.0f);
float bbHeight = 1.0f - cos(halfAngle)*innerRadius;
float bbWidth = sin(halfAngle) * 2.0f;
......@@ -136,7 +136,7 @@ namespace campvis {
FramebufferActivationGuard fag(this);
createAndAttachColorTexture();
glClearColor(0.1, 0.1, 0.1, 0.0);
glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
_grid->render(GL_TRIANGLE_STRIP);
_shader->deactivate();
......
......@@ -26,11 +26,15 @@ in vec3 ex_TexCoord;
out vec4 out_Color;
#include "tools/gradient.frag"
#include "tools/texture3d.frag"
#include "tools/transferfunction.frag"
#ifdef GLIMAGECROP_3D
uniform sampler3D _texture;
uniform TextureParameters3D _textureParams;
#endif
#ifdef GLIMAGECROP_2D
uniform sampler2D _texture;
#endif
uniform ivec3 _outputSize;
uniform ivec3 _offset;
......@@ -39,6 +43,14 @@ uniform int _zTexel;
void main() {
//ivec2 texel = ivec2(((1.0 / vec2(_outputSize.xy)) + ex_TexCoord.xy) * vec2(_outputSize.xy));
ivec2 texel = ivec2(ex_TexCoord.xy * vec2(_outputSize.xy));
#ifdef GLIMAGECROP_3D
vec4 intensity = texelFetch(_texture, ivec3(texel, _zTexel) + _offset, 0);
#endif
#ifdef GLIMAGECROP_2D
vec4 intensity = texelFetch(_texture, texel + _offset.xy, 0);
#endif
out_Color = intensity;
}
......@@ -26,16 +26,12 @@ in vec3 ex_TexCoord;
out vec4 out_Color;
#ifdef GLRESAMPLER_3D
#include "tools/texture3d.frag"
uniform sampler3D _texture;
uniform TextureParameters3D _textureParams;
uniform float _zTexCoord;
#endif
#ifdef GLRESAMPLER_2D
#include "tools/texture2d.frag"
uniform sampler2D _texture;
uniform TextureParameters2D _textureParams;
#endif
void main() {
......
......@@ -62,13 +62,18 @@ namespace campvis {
void GlImageCrop::init() {
VisualizationProcessor::init();
_shader = ShdrMgr.load("core/glsl/passthrough.vert", "modules/preprocessing/glsl/glimagecrop.frag", "");
_shader->setAttributeLocation(0, "in_Position");
_shader->setAttributeLocation(1, "in_TexCoord");
_shader2D = ShdrMgr.load("core/glsl/passthrough.vert", "modules/preprocessing/glsl/glimagecrop.frag", "#define GLIMAGECROP_2D\n");
_shader2D->setAttributeLocation(0, "in_Position");
_shader2D->setAttributeLocation(1, "in_TexCoord");
_shader3D = ShdrMgr.load("core/glsl/passthrough.vert", "modules/preprocessing/glsl/glimagecrop.frag", "#define GLIMAGECROP_3D\n");
_shader3D->setAttributeLocation(0, "in_Position");
_shader3D->setAttributeLocation(1, "in_TexCoord");
}
void GlImageCrop::deinit() {
ShdrMgr.dispose(_shader);
ShdrMgr.dispose(_shader2D);
ShdrMgr.dispose(_shader3D);
VisualizationProcessor::deinit();
}
......@@ -77,18 +82,24 @@ namespace campvis {
if (img != 0) {
cgt::ivec3 outputSize = cgt::abs(p_urb.getValue() - p_llf.getValue());
bool isTexture2D = img->getParent()->getDimensionality() == 2;
if (isTexture2D) {
outputSize.z = 1;
}
cgt::TextureUnit inputUnit;
inputUnit.activate();
// create texture for result
cgt::Texture* resultTexture = new cgt::Texture(GL_TEXTURE_3D, outputSize, img->getTexture()->getInternalFormat(), cgt::Texture::LINEAR);
cgt::Texture* resultTexture = new cgt::Texture(isTexture2D ? GL_TEXTURE_2D : GL_TEXTURE_3D, outputSize, img->getTexture()->getInternalFormat(), cgt::Texture::LINEAR);
// activate shader and bind textures
_shader->activate();
_shader->setUniform("_offset", p_llf.getValue());
_shader->setUniform("_outputSize", outputSize);
img->bind(_shader, inputUnit);
auto shader = isTexture2D ? _shader2D : _shader3D;
shader->activate();
shader->setUniform("_offset", p_llf.getValue());
shader->setUniform("_outputSize", outputSize);
img->bind(shader, inputUnit);
// activate FBO and attach texture
_fbo->activate();
......@@ -96,16 +107,18 @@ namespace campvis {
// render quad to compute difference measure by shader
for (int z = 0; z < outputSize.z; ++z) {
_shader->setUniform("_zTexel", z);
if (!isTexture2D) {
shader->setUniform("_zTexel", z);
}
_fbo->attachTexture(resultTexture, GL_COLOR_ATTACHMENT0, 0, z);
QuadRdr.renderQuad();
}
_fbo->detachAll();
_fbo->deactivate();
_shader->deactivate();
shader->deactivate();
// put resulting image into DataContainer
ImageData* id = new ImageData(3, outputSize, img.getImageData()->getNumChannels());
ImageData* id = new ImageData(isTexture2D ? 2 : 3, outputSize, img.getImageData()->getNumChannels());
ImageRepresentationGL::create(id, resultTexture);
const ImageMappingInformation& imi = img->getParent()->getMappingInformation();
id->setMappingInformation(ImageMappingInformation(img->getSize(), imi.getOffset() + (cgt::vec3(p_llf.getValue()) * imi.getVoxelSize()), imi.getVoxelSize(), imi.getCustomTransformation()));
......
......@@ -84,7 +84,8 @@ namespace campvis {
/// \see AbstractProcessor::updateProperties
virtual void updateProperties(DataContainer& dataContainer);
cgt::Shader* _shader; ///< Shader for resampling
cgt::Shader* _shader2D; ///< Shader for cropping 2D data
cgt::Shader* _shader3D; ///< Shader for cropping 3D data
static const std::string loggerCat_;
};
......
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