Commit 2fd4c075 authored by Declara Denis's avatar Declara Denis Committed by Christian Schulte zu Berge
Browse files

Extended the confidence maps pipeline:

* Added GlImageResampler processor to lower the resolution of the US image
* Exposed solver parameters to the GUI
* Added AdvancedUSVisualization processor to display the data
parent daf5ef93
#include "cm_cusp.h"
#include "cm_cusp_cuda_exports.h"
CuspConfidenceMapSolver::CuspConfidenceMapSolver(int width, int height, float gradientScaling,
float alpha, float beta, float gamma)
: width(width), height(height), gradientScaling(gradientScaling),
alpha(alpha), beta(beta), gamma(gamma), gpuData(CUSP_CM_createGpuData(width, height)) { }
CuspConfidenceMapSolver::CuspConfidenceMapSolver(int width, int height)
: width(width), height(height)
, gpuData(CUSP_CM_createGpuData(width, height)) { }
CuspConfidenceMapSolver::~CuspConfidenceMapSolver()
{
CUSP_CM_destroyGpuData(gpuData);
CUSP_CM_destroyGpuData(gpuData);
}
void CuspConfidenceMapSolver::createSystem(const unsigned char* image, int width, int height)
void CuspConfidenceMapSolver::createSystem(const unsigned char* image, int width, int height,
float gradientScaling,
float alpha, float beta, float gamma)
{
if (width != this->width || height != this->height) {
CUSP_CM_resizeGpuData(*gpuData, width, height);
}
if (width != this->width || height != this->height) {
CUSP_CM_resizeGpuData(*gpuData, width, height);
}
this->width = width;
this->height = height;
this->width = width;
this->height = height;
CUSP_CM_buildEquationSystem(*gpuData, image, width, height, alpha, beta, gamma, gradientScaling);
CUSP_CM_buildEquationSystem(*gpuData, image, width, height, alpha, beta, gamma, gradientScaling);
}
void CuspConfidenceMapSolver::setInitialSolution(const std::vector<float> &val)
{
CUSP_CM_setInitialSolution(*gpuData, val);
CUSP_CM_setInitialSolution(*gpuData, val);
}
void CuspConfidenceMapSolver::solve()
void CuspConfidenceMapSolver::solve(int iterations)
{
CUSP_CM_uploadSystem(*gpuData);
CUSP_CM_solveSystem(*gpuData, 100, 1e-20);
CUSP_CM_downloadSolution(*gpuData);
CUSP_CM_uploadSystem(*gpuData);
CUSP_CM_solveSystem(*gpuData, iterations, 1e-20);
CUSP_CM_downloadSolution(*gpuData);
}
const float* CuspConfidenceMapSolver::getSolution(int &width, int &height) const
{
const float *ptr = CUSP_CM_getSolutionPtr(*gpuData);
width = width; height = height; // FIXME: height and width are not actually checked against the size of the buffer...
return ptr;
const float *ptr = CUSP_CM_getSolutionPtr(*gpuData);
width = width; height = height; // FIXME: height and width are not actually checked against the size of the buffer...
return ptr;
}
......@@ -139,7 +139,7 @@ void CUSP_CM_buildEquationSystem(CuspGPUData &gpudata, const unsigned char* imag
// Gather all of the options together
ComputeLaplacianData data;
data.alpha = alpha; data.beta = beta; data.gamma = gamma;
data.gradientScaling = 1.0f / 0.1764f;
data.gradientScaling = gradientScaling;
data.image = image;
data.width = width; data.height = height;
data.centralDiagonal = 4;
......
......@@ -6,25 +6,21 @@ class CuspGPUData;
class CuspConfidenceMapSolver
{
public:
CuspConfidenceMapSolver(int width, int height, float gradientScaling,
float alpha, float beta, float gamma);
CuspConfidenceMapSolver(int width, int height);
virtual ~CuspConfidenceMapSolver();
virtual ~CuspConfidenceMapSolver();
virtual void createSystem(const unsigned char* image, int width, int height);
virtual void setInitialSolution(const std::vector<float> &val);
virtual void solve();
virtual void createSystem(const unsigned char* image, int width, int height,
float gradientScaling, float alpha, float beta, float gamma);
virtual void setInitialSolution(const std::vector<float> &val);
virtual void solve(int iterations);
virtual const float* getSolution(int &width, int &height) const;
virtual const float* getSolution(int &width, int &height) const;
private:
// Input image data
int width, height;
// Input image data
int width, height;
// Solver parameters
float gradientScaling;
float alpha, beta, gamma;
// Matrices and Vectors
CuspGPUData* gpuData;
// Matrices and Vectors
CuspGPUData* gpuData;
};
\ No newline at end of file
......@@ -22,6 +22,7 @@ IF(${ModuleEnabled})
)
# Build CUDA sources
set(CUDA_PROPAGATE_HOST_FLAGS OFF) # Otherwise -std=c++11 is passed, which does not work with cuda compilers
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};-O3)
file(GLOB cuda_SOURCES modules/cudaconfidencemaps/core/*.cu)
cuda_add_library(
......
......@@ -32,14 +32,15 @@ namespace campvis {
: AutoEvaluationPipeline(dc)
, _usIgtlReader()
, _usBlurFilter(&_canvasSize)
//, _usResampler(&_canvasSize)
, _usResampler(&_canvasSize)
, _usMapsSolver()
, _usFusion(&_canvasSize)
{
addProcessor(&_usIgtlReader);
addProcessor(&_usBlurFilter);
//addProcessor(&_usResampler);
addProcessor(&_usResampler);
addProcessor(&_usMapsSolver);
addProcessor(&_usFusion);
}
CudaConfidenceMapsDemo::~CudaConfidenceMapsDemo() {
......@@ -48,22 +49,31 @@ namespace campvis {
void CudaConfidenceMapsDemo::init() {
AutoEvaluationPipeline::init();
// Create connectors
// Set intial options
_usIgtlReader.p_receiveImages.setValue(true);
_usIgtlReader.p_receiveTransforms.setValue(false);
_usIgtlReader.p_receivePositions.setValue(false);
_usResampler.p_resampleScale.setValue(0.25f);
// Create connectors
_usIgtlReader.p_targetImagePrefix.setValue("us.igtl.");
_usBlurFilter.p_inputImage.setValue("us.igtl.ImageClient");
_usBlurFilter.p_outputImage.setValue("us.blurred");
_usBlurFilter.p_outputImage.addSharedProperty(&_usMapsSolver.p_inputImage);
_usBlurFilter.p_outputImage.addSharedProperty(&_usResampler.p_inputImage);
_usBlurFilter.p_outputImage.addSharedProperty(&_usFusion.p_blurredImageId);
//_usResampler.p_outputImage.setValue("us.resampled");
//_usResampler.p_outputImage.addSharedProperty(&_usMapsSolver.p_inputImage);
_usResampler.p_outputImage.setValue("us.resampled");
_usResampler.p_outputImage.addSharedProperty(&_usMapsSolver.p_inputImage);
_usMapsSolver.p_outputConfidenceMap.setValue("us.confidence");
_usMapsSolver.p_outputConfidenceMap.addSharedProperty(&_usFusion.p_confidenceImageID);
_usFusion.p_usImageId.setValue("us.igtl.ImageClient");
_usFusion.p_targetImageID.setValue("us.fusion");
_usFusion.p_view.setValue(12);
_renderTargetID.setValue("us.blurred");
_renderTargetID.setValue("us.fusion");
}
void CudaConfidenceMapsDemo::deinit() {
......
......@@ -32,7 +32,7 @@
#include "modules/preprocessing/processors/glimageresampler.h"
#include "modules/cudaconfidencemaps/processors/cudaconfidencemapssolver.h"
#include "modules/openigtlink/processors/openigtlinkclient.h"
#include "modules/advancedusvis/processors/advancedusfusion.h"
#include "core/properties/buttonproperty.h"
......@@ -68,8 +68,9 @@ namespace campvis {
OpenIGTLinkClient _usIgtlReader;
DevilImageReader _usReader;
GlGaussianFilter _usBlurFilter;
//GlImageResampler _usResampler;
GlImageResampler _usResampler;
CudaConfidenceMapsSolver _usMapsSolver;
AdvancedUsFusion _usFusion;
};
}
......
......@@ -38,34 +38,24 @@ namespace campvis {
: AbstractProcessor()
, p_inputImage("InputImage", "Input Image", "", DataNameProperty::READ)
, p_outputConfidenceMap("OutputConfidenceMap", "Output Confidence Map", "us.confidence", DataNameProperty::WRITE)
, _solver(512, 512, 2.0f, 2.0f, 20.0f, 0.03f)
, p_resetResult("ResetSolution", "Reset solution vector")
, p_iterations("IterationCount", "Conjugate Gradient Iterations", 200, 1, 10000)
, 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)
, _solver(128, 128)
{
addProperty(p_inputImage);
addProperty(p_outputConfidenceMap);
/*
_stopExecution = false;
_receiverRunning = false;
addProperty(p_address, VALID);
addProperty(p_port, VALID);
addProperty(p_deviceName, VALID);
addProperty(p_connect, VALID);
addProperty(p_disconnect, VALID);
addProperty(p_receiveTransforms, INVALID_PROPERTIES);
addProperty(p_receiveImages, INVALID_PROPERTIES);
addProperty(p_targetTransformPrefix, VALID);
addProperty(p_targetImagePrefix, VALID);
addProperty(p_imageOffset, VALID);
addProperty(p_voxelSize, VALID);
addProperty(p_receivePositions, INVALID_PROPERTIES);
addProperty(p_targetPositionPrefix, VALID);
invalidate(INVALID_PROPERTIES);*/
addProperty(p_resetResult);
addProperty(p_iterations);
addProperty(p_gradientScaling);
addProperty(p_paramAlpha);
addProperty(p_paramBeta);
addProperty(p_paramGamma);
}
CudaConfidenceMapsSolver::~CudaConfidenceMapsSolver() {
......@@ -91,15 +81,30 @@ namespace campvis {
void CudaConfidenceMapsSolver::updateResult(DataContainer& data) {
ImageRepresentationLocal::ScopedRepresentation img(data, p_inputImage.getValue());
if (img != 0) {
int iterations = p_iterations.getValue();
float gradientScaling = p_gradientScaling.getValue();
float alpha = p_paramAlpha.getValue();
float beta = p_paramBeta.getValue();
float gamma = p_paramGamma.getValue();
cgt::ivec3 size = img->getSize();
_solver.createSystem((unsigned char*)img->getWeaklyTypedPointer()._pointer, size.x, size.y);
_solver.solve();
size_t elementCount = cgt::hmul(size);
unsigned char *flippedData = new unsigned char[elementCount];
for (size_t i = 0; i < elementCount; ++i) {
flippedData[elementCount-i-1] = ((unsigned char*)img->getWeaklyTypedPointer()._pointer)[i];
}
_solver.createSystem(flippedData, size.x, size.y,
gradientScaling, alpha, beta, gamma);
delete[] flippedData;
_solver.solve(iterations);
const float *solution = _solver.getSolution(size.x, size.y);
ImageData *id = new ImageData(img->getParent()->getDimensionality(), size, img->getParent()->getNumChannels());
size_t elementCount = cgt::hmul(size);
float *imgData = new float[elementCount];
memcpy(imgData, solution, sizeof(float)*elementCount);
for (size_t i = 0; i < elementCount; ++i) {
imgData[elementCount-i-1] = solution[i];
}
WeaklyTypedPointer wtpData(WeaklyTypedPointer::FLOAT, 1, imgData);
ImageRepresentationLocal::create(id, wtpData);
......
......@@ -45,12 +45,7 @@
namespace campvis {
/**
* OpenIGTLink Client processor. Connects to a specified server and receives all OpenIGTLink messages.
* Processes the messages according to the currently set properties p_receiveTransform, p_receivePositions
* and p_receiveImage and puts them into the received data into the respective data containers.
* This Class contains modified code from the OpenIGTLink ReceiveClient example.
*/
class CudaConfidenceMapsSolver : public AbstractProcessor {
public:
/**
......@@ -85,22 +80,24 @@ namespace campvis {
/// \see AbstractProcessor::updateProperties
virtual void updateProperties(DataContainer& dataContainer);
/// Callback slot for connect button. can also be called from outside.
void connect();
/// Callback slot for disconnect button. can also be called from outside.
void disconnect();
DataNameProperty p_inputImage; ///< ID for input volume
DataNameProperty p_inputImage; ///< ID for input volume
DataNameProperty p_outputConfidenceMap; ///< ID for output gradient volume
ButtonProperty p_resetResult;
NumericProperty<int> p_iterations; /// < Number of CG-Iterations to do
FloatProperty p_gradientScaling;
FloatProperty p_paramAlpha;
FloatProperty p_paramBeta;
FloatProperty p_paramGamma;
protected:
CuspConfidenceMapSolver _solver;
static const std::string loggerCat_;
// this is thread management stuff
// very similar to the Runnable base class
};
}
......
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