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

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

Introducing nlopt binding stub and prototype optimization implementation

parent b3384a78
// ================================================================================================
//
// 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.
//
// ================================================================================================
in vec3 ex_TexCoord;
out vec4 out_Color;
//out float out_Value;
#include "tools/texture3d.frag"
uniform sampler3D _referenceTexture;
uniform TextureParameters3D _referenceTextureParams;
uniform sampler3D _movingTexture;
uniform TextureParameters3D _movingTextureParams;
//uniform mat4 _registrationMatrix;
uniform mat4 _registrationInverse;
void main() {
ivec2 texel = ivec2(ex_TexCoord.xy * _referenceTextureParams._size.xy);
float depth = _referenceTextureParams._size.z;
float sad = 0.0;
float ssd = 0.0;
for (float z = _referenceTextureParams._sizeRCP.z / 2.0; z < 1.0; z += _referenceTextureParams._sizeRCP.z) {
vec3 referenceLookupTexCoord = vec3(ex_TexCoord.xy, z);
vec4 movingLookupTexCoord = _registrationInverse * vec4(referenceLookupTexCoord, 1.0);
//movingLookupTexCoord.xyz /= movingLookupTexCoord.z;
// if (all(greaterThanEqual(movingLookupTexCoord.xyz, vec3(0.0))) && all(lessThanEqual(movingLookupTexCoord.xyz, vec3(1.0)))) {
float referenceValue = texture(_referenceTexture, referenceLookupTexCoord).a;
float movingValue = texture(_movingTexture, movingLookupTexCoord.xyz).a;
float difference = referenceValue - movingValue;
sad += abs(difference);
ssd += difference * difference;
// }
}
//out_Value = toReturn;
out_Color = vec4(ssd, sad, 0.0, 1.0);
}
// ================================================================================================
//
// 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 Universität München
// Boltzmannstr. 3, 85748 Garching b. München, 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 "reducertest.h"
#include "tgt/event/keyevent.h"
#include "core/classification/geometry1dtransferfunction.h"
#include "core/classification/tfgeometry1d.h"
#include "core/datastructures/renderdata.h"
#include "core/tools/glreduction.h"
namespace campvis {
ReducerTest::ReducerTest(DataContainer* dc)
: AutoEvaluationPipeline(dc)
, _imageReader()
, _sliceExtractor(&_canvasSize)
, _sm()
, _wheelHandler(&_sliceExtractor.p_zSliceNumber)
, _tfWindowingHandler(&_sliceExtractor.p_transferFunction)
{
addProcessor(&_imageReader);
addProcessor(&_sliceExtractor);
addProcessor(&_sm);
addEventListenerToBack(&_wheelHandler);
addEventListenerToBack(&_tfWindowingHandler);
}
ReducerTest::~ReducerTest() {
}
void ReducerTest::init() {
AutoEvaluationPipeline::init();
_imageReader.p_url.setValue("D:\\Medical Data\\smallHeart.mhd");
_imageReader.p_targetImageID.setValue("reader.output");
_imageReader.p_targetImageID.addSharedProperty(&_sliceExtractor.p_sourceImageID);
_imageReader.p_targetImageID.addSharedProperty(&_sm.p_referenceId);
_imageReader.p_targetImageID.addSharedProperty(&_sm.p_movingId);
_imageReader.s_validated.connect(this, &ReducerTest::onProcessorValidated);
_sliceExtractor.p_xSliceNumber.setValue(0);
_sliceExtractor.s_validated.connect(this, &ReducerTest::onProcessorValidated);
// TODO: replace this hardcoded domain by automatically determined from image min/max values
Geometry1DTransferFunction* tf = new Geometry1DTransferFunction(128, tgt::vec2(0.f, .08f));
tf->addGeometry(TFGeometry1D::createQuad(tgt::vec2(0.f, 1.f), tgt::col4(0, 0, 0, 0), tgt::col4(255, 255, 255, 255)));
_sliceExtractor.p_transferFunction.replaceTF(tf);
_renderTargetID.setValue("renderTarget");
_renderTargetID.addSharedProperty(&(_sliceExtractor.p_targetImageID));
}
void ReducerTest::keyEvent(tgt::KeyEvent* e) {
if (e->pressed()) {
switch (e->keyCode()) {
case tgt::KeyEvent::K_UP:
_sliceExtractor.p_xSliceNumber.increment();
break;
case tgt::KeyEvent::K_DOWN:
_sliceExtractor.p_xSliceNumber.decrement();
break;
default:
break;
}
}
}
void ReducerTest::onProcessorValidated(AbstractProcessor* processor) {
if (processor == &_imageReader) {
ScopedTypedData<ImageData> img(*_data, _imageReader.p_targetImageID.getValue());
if (img != 0) {
_sliceExtractor.p_transferFunction.getTF()->setImageHandle(img.getDataHandle());
}
}
if (processor == &_sliceExtractor) {
ScopedTypedData<RenderData> rd(*_data, _sliceExtractor.p_targetImageID.getValue());
if (rd != 0 && rd->getColorTexture() != 0) {
// GlReduction reducer;
// reducer.reduce(rd->getColorTexture());
}
}
}
}
// ================================================================================================
//
// 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 Universität München
// Boltzmannstr. 3, 85748 Garching b. München, 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.
//
// ================================================================================================
#ifndef REDUCERTEST_H__
#define REDUCERTEST_H__
#include "core/datastructures/imagerepresentationlocal.h"
#include "core/eventhandlers/mwheeltonumericpropertyeventlistener.h"
#include "core/eventhandlers/transfuncwindowingeventlistener.h"
#include "core/pipeline/autoevaluationpipeline.h"
#include "modules/io/processors/mhdimagereader.h"
#include "modules/vis/processors/sliceextractor.h"
#include "modules/preprocessing/processors/gradientvolumegenerator.h"
#include "modules/preprocessing/processors/lhhistogram.h"
#include "modules/registration/processors/similaritymeasure.h"
namespace campvis {
class ReducerTest : public AutoEvaluationPipeline {
public:
/**
* Creates a AutoEvaluationPipeline.
*/
ReducerTest(DataContainer* dc);
/**
* Virtual Destructor
**/
virtual ~ReducerTest();
/// \see AutoEvaluationPipeline::init()
virtual void init();
/// \see AbstractPipeline::getName()
virtual const std::string getName() const { return getId(); };
static const std::string getId() { return "ReducerTest"; };
virtual void keyEvent(tgt::KeyEvent* e);
protected:
/**
* Slot getting called when one of the observed processors got validated.
* Updates the camera properties, when the input image has changed.
* \param processor The processor that emitted the signal
*/
virtual void onProcessorValidated(AbstractProcessor* processor);
MhdImageReader _imageReader;
SliceExtractor _sliceExtractor;
SimilarityMeasure _sm;
MWheelToNumericPropertyEventListener _wheelHandler;
TransFuncWindowingEventListener _tfWindowingHandler;
};
}
#endif // REDUCERTEST_H__
......@@ -44,6 +44,11 @@
#include "core/tools/quadrenderer.h"
namespace campvis {
static const GenericOption<nlopt::algorithm> optimizers[3] = {
GenericOption<nlopt::algorithm>("cobyla", "COBYLA", nlopt::LN_COBYLA),
GenericOption<nlopt::algorithm>("newuoa", "NEWUOA", nlopt::LN_NEWUOA),
GenericOption<nlopt::algorithm>("neldermead", "Nelder-Mead Simplex", nlopt::LN_NELDERMEAD)
};
const std::string SimilarityMeasure::loggerCat_ = "CAMPVis.modules.vis.SimilarityMeasure";
......@@ -54,14 +59,19 @@ namespace campvis {
, p_translation("Translation", "Moving Image Translation", tgt::vec3(0.f), tgt::vec3(-1000.f), tgt::vec3(1000.f), tgt::vec3(1.f), tgt::vec3(1.f))
, p_rotation("Rotation", "Moving Image Rotation", tgt::vec3(0.f), tgt::vec3(-tgt::PIf), tgt::vec3(tgt::PIf), tgt::vec3(.1f), tgt::vec3(2.f))
, p_viewportSize("ViewportSize", "Viewport Size", tgt::ivec2(1), tgt::ivec2(1), tgt::ivec2(1000), tgt::ivec2(1), AbstractProcessor::VALID)
, p_compute("ComputeSimilarity", "Compute Similarity")
, p_computeSimilarity("ComputeSimilarity", "Compute Similarity")
, p_optimizer("Optimizer", "Optimizer", optimizers, 3)
, p_performOptimization("PerformOptimization", "Perform Optimization", AbstractProcessor::INVALID_RESULT | PERFORM_OPTIMIZATION)
, _shader(0)
, _glr(0)
{
addProperty(&p_referenceId);
addProperty(&p_movingId);
addProperty(&p_translation);
addProperty(&p_rotation);
addProperty(&p_compute);
addProperty(&p_computeSimilarity);
addProperty(&p_optimizer);
addProperty(&p_performOptimization);
_viewportSizeProperty = &p_viewportSize;
}
......@@ -75,11 +85,16 @@ namespace campvis {
_shader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "modules/registration/glsl/similaritymeasure.frag", "", false);
_shader->setAttributeLocation(0, "in_Position");
_shader->setAttributeLocation(1, "in_TexCoord");
_glr = new GlReduction();
}
void SimilarityMeasure::deinit() {
VisualizationProcessor::deinit();
ShdrMgr.dispose(_shader);
delete _glr;
_glr = 0;
}
void SimilarityMeasure::process(DataContainer& data) {
......@@ -87,65 +102,12 @@ namespace campvis {
ImageRepresentationGL::ScopedRepresentation movingImage(data, p_movingId.getValue());
if (referenceImage != 0 && movingImage != 0) {
const tgt::svec3& size = referenceImage->getSize();
p_viewportSize.setValue(size.xy());
// reserve texture units
tgt::TextureUnit referenceUnit, movingUnit;
referenceUnit.activate();
// create temporary texture for result
tgt::Texture* similarityTex = new tgt::Texture(0, tgt::ivec3(p_viewportSize.getValue(), 1), GL_RGBA, GL_RGBA32F, GL_FLOAT, tgt::Texture::NEAREST);
similarityTex->uploadTexture();
similarityTex->setWrapping(tgt::Texture::CLAMP);
// activate FBO and attach texture
_fbo->activate();
const tgt::ivec2& windowSize = p_viewportSize.getValue();
glViewport(0, 0, static_cast<GLsizei>(windowSize.x), static_cast<GLsizei>(windowSize.y));
_fbo->attachTexture(similarityTex);
//_fbo->attachTexture(&similarityTex);
LGL_ERROR;
// bind input images
_shader->activate();
referenceImage->bind(_shader, referenceUnit, "_referenceTexture", "_referenceTextureParams");
movingImage->bind(_shader, movingUnit, "_movingTexture", "_movingTextureParams");
tgt::mat4 registrationMatrix = tgt::mat4::createTranslation(p_translation.getValue())
* tgt::mat4::createRotationZ(p_rotation.getValue().z)
* tgt::mat4::createRotationY(p_rotation.getValue().y)
* tgt::mat4::createRotationX(p_rotation.getValue().x);
const tgt::mat4& w2t = movingImage->getParent()->getMappingInformation().getWorldToTextureMatrix();
const tgt::mat4& t2w = referenceImage->getParent()->getMappingInformation().getTextureToWorldMatrix();
registrationMatrix = w2t * registrationMatrix * t2w;
tgt::mat4 registrationInverse;
if (! registrationMatrix.invert(registrationInverse))
tgtAssert(false, "Could not invert registration matrix. This should not happen!");
// render quad to compute similarity measure by shader
//_shader->setUniform("_registrationMatrix", registrationMatrix);
_shader->setUniform("_registrationInverse", registrationInverse);
QuadRdr.renderQuad();
_shader->deactivate();
// detach texture and reduce it
data.addData("All glory to the HYPNOTOAD!", new RenderData(_fbo));
_fbo->detachAll();
_fbo->deactivate();
// reduce the juice
GlReduction reducer;
float similarity = reducer.reduce(similarityTex);
if (getInvalidationLevel() & PERFORM_OPTIMIZATION) {
performOptimization(referenceImage, movingImage);
}
float similarity = computeSimilarity(referenceImage, movingImage, p_translation.getValue(), p_rotation.getValue());
LDEBUG("Similarity Measure: " << similarity);
tgt::TextureUnit::setZeroUnit();
LGL_ERROR;
}
else {
LERROR("No suitable input image found.");
......@@ -162,5 +124,124 @@ namespace campvis {
validate(AbstractProcessor::INVALID_PROPERTIES);
}
void SimilarityMeasure::performOptimization(const ImageRepresentationGL* referenceImage, const ImageRepresentationGL* movingImage) {
tgtAssert(referenceImage != 0, "Reference Image must not be 0.");
tgtAssert(movingImage != 0, "Moving Image must not be 0.");
MyFuncData_t mfd = { this, referenceImage, movingImage, 0 };
nlopt::opt opt(p_optimizer.getOptionValue(), 6);
opt.set_min_objective(&SimilarityMeasure::optimizerFunc, &mfd);
opt.set_xtol_rel(1e-4);
std::vector<double> x(6);
x[0] = p_translation.getValue().x;
x[1] = p_translation.getValue().y;
x[2] = p_translation.getValue().z;
x[3] = p_rotation.getValue().x;
x[4] = p_rotation.getValue().y;
x[5] = p_rotation.getValue().z;
std::vector<double> stepSize(6);
stepSize[0] = 8.0;
stepSize[1] = 8.0;
stepSize[2] = 8.0;
stepSize[3] = 0.5;
stepSize[4] = 0.5;
stepSize[5] = 0.5;
opt.set_initial_step(stepSize);
double minf;
nlopt::result result = opt.optimize(x, minf);
if (result >= nlopt::SUCCESS) {
LDEBUG("Optimization successful, took " << mfd._count << " steps.");
p_translation.setValue(tgt::vec3(x[0], x[1], x[2]));
p_rotation.setValue(tgt::vec3(x[3], x[4], x[5]));
}
validate(PERFORM_OPTIMIZATION);
}
float SimilarityMeasure::computeSimilarity(const ImageRepresentationGL* referenceImage, const ImageRepresentationGL* movingImage, const tgt::vec3& translation, const tgt::vec3& rotation) {
tgtAssert(referenceImage != 0, "Reference Image must not be 0.");
tgtAssert(movingImage != 0, "Moving Image must not be 0.");
const tgt::svec3& size = referenceImage->getSize();
p_viewportSize.setValue(size.xy());
// reserve texture units
tgt::TextureUnit referenceUnit, movingUnit;
referenceUnit.activate();
// create temporary texture for result
tgt::Texture* similarityTex = new tgt::Texture(0, tgt::ivec3(p_viewportSize.getValue(), 1), GL_RGBA, GL_RGBA32F, GL_FLOAT, tgt::Texture::NEAREST);
similarityTex->uploadTexture();
similarityTex->setWrapping(tgt::Texture::CLAMP);
// activate FBO and attach texture
_fbo->activate();
const tgt::ivec2& windowSize = p_viewportSize.getValue();
glViewport(0, 0, static_cast<GLsizei>(windowSize.x), static_cast<GLsizei>(windowSize.y));
_fbo->attachTexture(similarityTex);
//_fbo->attachTexture(&similarityTex);
LGL_ERROR;
// bind input images
_shader->activate();
referenceImage->bind(_shader, referenceUnit, "_referenceTexture", "_referenceTextureParams");
movingImage->bind(_shader, movingUnit, "_movingTexture", "_movingTextureParams");
tgt::mat4 registrationMatrix = tgt::mat4::createTranslation(translation)
* tgt::mat4::createRotationZ(rotation.z)
* tgt::mat4::createRotationY(rotation.y)
* tgt::mat4::createRotationX(rotation.x);
const tgt::mat4& w2t = movingImage->getParent()->getMappingInformation().getWorldToTextureMatrix();
const tgt::mat4& t2w = referenceImage->getParent()->getMappingInformation().getTextureToWorldMatrix();
registrationMatrix = w2t * registrationMatrix * t2w;
tgt::mat4 registrationInverse;
if (! registrationMatrix.invert(registrationInverse))
tgtAssert(false, "Could not invert registration matrix. This should not happen!");
// render quad to compute similarity measure by shader
//_shader->setUniform("_registrationMatrix", registrationMatrix);
_shader->setUniform("_registrationInverse", registrationInverse);
QuadRdr.renderQuad();
_shader->deactivate();
// detach texture and reduce it
//data.addData("All glory to the HYPNOTOAD!", new RenderData(_fbo));
_fbo->detachAll();
_fbo->deactivate();
// reduce the juice
float similarity = _glr->reduce(similarityTex);
delete similarityTex;
tgt::TextureUnit::setZeroUnit();
LGL_ERROR;
return similarity;
}
double SimilarityMeasure::optimizerFunc(const std::vector<double>& x, std::vector<double>& grad, void* my_func_data) {
tgtAssert(x.size() == 6, "Must have 6 values in x.");
tgtAssert(my_func_data != 0, "my_func_data must not be 0");
MyFuncData_t* mfd = static_cast<MyFuncData_t*>(my_func_data);
++mfd->_count;
tgt::vec3 translation(x[0], x[1], x[2]);
tgt::vec3 rotation(x[3], x[4], x[5]);
float similarity = mfd->_object->computeSimilarity(mfd->_reference, mfd->_moving, translation, rotation);
LDEBUG(translation << rotation << " : " << similarity);
return similarity;
}
}
......@@ -45,6 +45,8 @@
#include "core/properties/numericproperty.h"
#include "core/properties/transferfunctionproperty.h"
#include <nlopt.hpp>
namespace tgt {
class Shader;
}
......@@ -52,12 +54,18 @@ namespace tgt {
namespace campvis {
class FaceGeometry;
class ImageData;
class ImageRepresentationGL;
class GlReduction;
/**
* Computes a Similarity Measure using OpenGL
*/
class SimilarityMeasure : public VisualizationProcessor {
public:
enum AdditionalInvalidationLevels {
PERFORM_OPTIMIZATION = 1U << 6
};
/**
* Constructs a new SimilarityMeasure Processor
**/
......@@ -91,15 +99,33 @@ namespace campvis {
Vec3Property p_translation; ///< Moving image translation
Vec3Property p_rotation; ///< Moving image rotation
ButtonProperty p_compute;
ButtonProperty p_computeSimilarity;
GenericOptionProperty<nlopt::algorithm> p_optimizer;
ButtonProperty p_performOptimization;
private:
struct MyFuncData_t {
SimilarityMeasure* _object;
const ImageRepresentationGL* _reference;
const ImageRepresentationGL* _moving;
size_t _count;
};
protected:
/// \see AbstractProcessor::updateProperties
void updateProperties(DataContainer& dc);
void performOptimization(const ImageRepresentationGL* referenceImage, const ImageRepresentationGL* movingImage);
float computeSimilarity(const ImageRepresentationGL* referenceImage, const ImageRepresentationGL* movingImage, const tgt::vec3& translation, const tgt::vec3& rotation);
static double optimizerFunc(const std::vector<double>& x, std::vector<double>& grad, void* my_func_data);
IVec2Property p_viewportSize;
tgt::Shader* _shader; ///< Shader for slice rendering
GlReduction* _glr;
static const std::string loggerCat_;
};
......
......@@ -18,3 +18,6 @@ FILE(GLOB ThisModHeaders RELATIVE ${ModulesDir}
SET(ThisModShaderDirectories "modules/registration/glsl")
LIST(APPEND ThisModIncludeDirs "C:/Users/Christian/Documents/code/ext/nlopt-2.4/api")
LIST(APPEND ThisModExternalLibs nlopt)
LIST(APPEND ThisModLinkDirectories "C:/Users/Christian/Documents/code/ext/nlopt-2.4/build-x64/Debug" "C:/Users/Christian/Documents/code/ext/nlopt-2.4/build-x64/Release")
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