Commit 975ff690 authored by schultezub's avatar schultezub

Further work on AdvancedUsFusion module:

 * introducing CMBatchGeneration pipeline
 * added fan geometry to ConfidenceMapGenerator
 * added DevilImageReader read to local intensity
 * fixed XYZ color space conversion
 * added Hunter Lab conversion (broken)


git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@475 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent d5f2e973
......@@ -29,6 +29,7 @@
#include "application/campvisapplication.h"
#include "modules/advancedusvis/pipelines/advancedusvis.h"
#include "modules/advancedusvis/pipelines/cmbatchgeneration.h"
#include "modules/vis/pipelines/ixpvdemo.h"
#include "modules/vis/pipelines/dvrvis.h"
#include "modules/vis/pipelines/slicevis.h"
......@@ -47,10 +48,11 @@ using namespace campvis;
**/
int main(int argc, char** argv) {
CampVisApplication app(argc, argv);
app.addVisualizationPipeline("Advanced Ultrasound Visualization", new AdvancedUsVis());
//app.addVisualizationPipeline("IXPV", new IxpvDemo());
//app.addVisualizationPipeline("Advanced Ultrasound Visualization", new AdvancedUsVis());
app.addVisualizationPipeline("Confidence Map Generation", new CmBatchGeneration());
// app.addVisualizationPipeline("IXPV", new IxpvDemo());
//app.addVisualizationPipeline("SliceVis", new SliceVis());
//app.addVisualizationPipeline("DVRVis", new DVRVis());
// app.addVisualizationPipeline("DVRVis", new DVRVis());
#ifdef HAS_KISSCL
//app.addVisualizationPipeline("DVR with OpenCL", new OpenCLPipeline());
#endif
......
......@@ -306,13 +306,13 @@ vec3 rgb2xyz(in vec3 RGB) {
* \return The given color in RGB space.
*/
vec3 xyz2rgb(in vec3 XYZ) {
XYZ /= 100.0;
const mat3 conversionMatrix = mat3(
3.240479, -1.537150, -0.498535,
-0.969256, 1.875992, 0.041556,
0.055648, -0.204043, 1.057311);
XYZ = XYZ * conversionMatrix / 100.0;
bvec3 tmp = greaterThan(XYZ, vec3(0.0031308));
XYZ = (vec3(tmp) * (1.055 * pow(XYZ, vec3(1.0/2.4)) - 0.055))
+ (vec3(not(tmp)) * (XYZ * 12.92));
......@@ -359,6 +359,41 @@ vec3 lab2xyz(in vec3 LAB) {
return XYZ * colorspace_LabWts_;
}
/**
* Converts a color from XYZ space to Hunter L*a*b* space.
* \see http://easyrgb.com
* \param XYZ color in XYZ space
* \return The given color in Hunter L*a*b* space.
*/
vec3 xyz2hlab(in vec3 XYZ) {
vec3 hLab = vec3(0.0);
hLab.x = 10.0 * sqrt(XYZ.y);
hLab.y = 17.5 * (((1.02 * XYZ.x) - XYZ.y) / sqrt(XYZ.y));
hLab.z = 7.0 * ((XYZ.y - (0.847 * XYZ.z)) / sqrt(XYZ.y));
return hLab;
}
/**
* Converts a color from Hunter L*a*b* space to XYZ space.
* \see http://easyrgb.com
* \param LAB color in Hunter L*a*b* space
* \return The given color in XYZ space.
*/
vec3 hlab2xyz(in vec3 LAB) {
vec3 XYZ = vec3(0.0);
XYZ.y = pow(LAB.x / 10.0, 2.0);
XYZ.x = LAB.y / 17.5 * LAB.x / 10.0;
XYZ.z = LAB.z / 7.0 * LAB.x / 10.0;
XYZ.x = (XYZ.x + LAB.y) / 1.02;
XYZ.z = -(XYZ.z - LAB.y) / 0.847;
return XYZ;
}
/**
* Converts a color from L*a*b* space to L*C*H* space.
* \see http://easyrgb.com
......
......@@ -2,6 +2,7 @@
#define INTERVAL_H__
#include "tgt/tgt_math.h"
#include "tgt/vector.h"
#include <limits>
namespace campvis {
......@@ -35,6 +36,12 @@ namespace campvis {
*/
Interval(T left, T right, bool leftOpen=false, bool rightOpen=false);
/**
* Creates a new closed Interval<T> with the given vec2 as values
* \param vec Vector with interval borders
*/
explicit Interval(const tgt::Vector2<T>& vec);
/**
* Destructor
*/
......@@ -192,7 +199,6 @@ namespace campvis {
};
// ---------------------------------------- implementation ----------------------------------------
template<typename T>
......@@ -220,6 +226,17 @@ namespace campvis {
, _rightOpen(rightOpen)
{}
template<typename T>
Interval<T>::Interval(const tgt::Vector2<T>& vec)
: _left(vec.x)
, _right(vec.y)
, _leftOpen(false)
, _rightOpen(false)
{
if (_left > _right)
std::swap(_left, _right);
}
template<typename T>
Interval<T>::~Interval() {
}
......
......@@ -133,10 +133,17 @@ void main() {
out_Color.xyz = lch2rgb(lch);
break;
case 9:
out_Color = lookupTF(_transferFunction, _transferFunctionParams, texel.a);
vec3 hlch = lab2lch(xyz2hlab(rgb2xyz(out_Color.xyz)));
//hlch.z = 6.2831853 * _hue;
//hlch.y = 100.0 * (1.0 - confidence);
out_Color.xyz = xyz2rgb(hlab2xyz(lch2lab(hlch)));
break;
case 10:
float intensity = mix(blurred.a, (2.0 * texel.a - blurred.a), confidence);
out_Color = lookupTF(_transferFunction, _transferFunctionParams, intensity);
break;
case 10:
case 11:
float lod = max(floor((1.0 - confidence) * 6.0), 0.0);
vec4 lodTexel = texture(_usImage, texCoord, lod);
......
// ================================================================================================
//
// 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.
//
// ================================================================================================
#include "cmbatchgeneration.h"
#include "tgt/event/keyevent.h"
#include "core/classification/geometry1dtransferfunction.h"
#include "core/classification/tfgeometry1d.h"
#include "core/tools/simplejobprocessor.h"
#include "core/tools/job.h"
namespace campvis {
CmBatchGeneration::CmBatchGeneration()
: VisualizationPipeline()
, _usReader(_effectiveRenderTargetSize)
, _confidenceGenerator()
, _usBlurFilter()
, _usFusion(_effectiveRenderTargetSize)
{
addProcessor(&_usReader);
addProcessor(&_confidenceGenerator);
addProcessor(&_usFusion);
addProcessor(&_usBlurFilter);
}
CmBatchGeneration::~CmBatchGeneration() {
}
void CmBatchGeneration::init() {
VisualizationPipeline::init();
_usReader.s_validated.connect(this, &CmBatchGeneration::onProcessorValidated);
//_usReader.p_url.setValue("D:\\Medical Data\\US Confidence Vis\\CurefabCS\\Stent_Patient_ B-Mode_2013-02-11T14.56.46z\\01_us.mhd");
//_usReader.p_url.setValue("D:\\Medical Data\\US Confidence Vis\\01\\BMode_01.mhd");
//_usReader.p_url.setValue("D:\\Medical Data\\US Confidence Vis\\UltrasoundBoneData\\SynthesEvaluationUnterschenkel");
_usReader.p_url.setValue("D:\\Medical Data\\US Confidence Vis\\transcranial\\us.png");
_usReader.p_targetImageID.setValue("us.image");
_usReader.p_importType.selectById("localIntensity");
_usReader.p_targetImageID.connect(&_confidenceGenerator.p_sourceImageID);
_usReader.p_targetImageID.connect(&_usFusion.p_usImageId);
_usReader.p_targetImageID.connect(&_usBlurFilter.p_sourceImageID);
_confidenceGenerator.p_targetImageID.setValue("confidence.image.generated");
_confidenceGenerator.p_targetImageID.connect(&_usFusion.p_confidenceImageID);
_confidenceGenerator.p_curvilinear.setValue(true);
//_confidenceGenerator.p_origin.setValue(tgt::vec2(320.f, 444s.f));
//_confidenceGenerator.p_angles.setValue(tgt::vec2(225.f / 180.f * tgt::PIf, 315.f / 180.f * tgt::PIf));
_confidenceGenerator.p_origin.setValue(tgt::vec2(320.f, 35.f));
_confidenceGenerator.p_angles.setValue(tgt::vec2(45.f / 180.f * tgt::PIf, 135.f / 180.f * tgt::PIf));
_confidenceGenerator.p_lengths.setValue(tgt::vec2(0.f, 410.f));
_usFusion.p_targetImageID.setValue("us.fused");
_usFusion.p_view.selectById("mappingSharpness");
_usFusion.p_sliceNumber.setValue(0);
_usBlurFilter.p_targetImageID.setValue("us.blurred");
_usBlurFilter.p_targetImageID.connect(&_usFusion.p_blurredImageId);
_usBlurFilter.p_filterMode.selectById("gauss");
_usBlurFilter.p_sigma.setValue(4.f);
// TODO: replace this hardcoded domain by automatically determined from image min/max values
Geometry1DTransferFunction* tf = new Geometry1DTransferFunction(128, tgt::vec2(0.f, 1.f));
tf->addGeometry(TFGeometry1D::createQuad(tgt::vec2(0.f, 1.f), tgt::col4(0, 0, 0, 255), tgt::col4(255, 255, 255, 255)));
_usFusion.p_transferFunction.replaceTF(tf);
_renderTargetID.setValue("us.fused");
}
void CmBatchGeneration::deinit() {
VisualizationPipeline::deinit();
}
void CmBatchGeneration::execute() {
/*
if (!_usReader.getInvalidationLevel().isValid()) {
SimpleJobProc.enqueueJob(makeJob(this, &CmBatchGeneration::foobar));
}
if (!_usDenoiseilter.getInvalidationLevel().isValid()) {
SimpleJobProc.enqueueJob(makeJob<CmBatchGeneration, AbstractProcessor*>(this, &CmBatchGeneration::executeProcessor, &_usDenoiseilter));
}
if (!_confidenceGenerator.getInvalidationLevel().isValid()) {
SimpleJobProc.enqueueJob(makeJob<CmBatchGeneration, AbstractProcessor*>(this, &CmBatchGeneration::executeProcessor, &_confidenceGenerator));
}
for (std::vector<AbstractProcessor*>::iterator it = _processors.begin(); it != _processors.end(); ++it) {
if (! (*it)->getInvalidationLevel().isValid())
lockGLContextAndExecuteProcessor(*it);
}*/
}
void CmBatchGeneration::keyEvent(tgt::KeyEvent* e) {
}
const std::string CmBatchGeneration::getName() const {
return "CmBatchGeneration";
}
void CmBatchGeneration::onProcessorValidated(AbstractProcessor* processor) {
if (processor = &_usReader) {
}
}
}
\ No newline at end of file
// ================================================================================================
//
// 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 CMBATCHGENERATION_H__
#define CMBATCHGENERATION_H__
#include "core/datastructures/imagerepresentationlocal.h"
#include "core/eventhandlers/mwheeltonumericpropertyeventhandler.h"
#include "core/eventhandlers/transfuncwindowingeventhandler.h"
#include "core/eventhandlers/trackballnavigationeventhandler.h"
#include "core/pipeline/visualizationpipeline.h"
#include "modules/devil/processors/devilimagereader.h"
#include "modules/io/processors/mhdimagereader.h"
#include "modules/io/processors/csvdimagereader.h"
#include "modules/advancedusvis/processors/advancedusfusion.h"
#include "modules/preprocessing/processors/gradientvolumegenerator.h"
#include "modules/preprocessing/processors/lhhistogram.h"
#include "modules/itk/processors/itkimagefilter.h"
#include "modules/vis/processors/proxygeometrygenerator.h"
#include "modules/vis/processors/eepgenerator.h"
#include "modules/vis/processors/simpleraycaster.h"
#include "modules/vis/processors/quadview.h"
#include "modules/randomwalk/processors/confidencemapgenerator.h"
namespace campvis {
class CmBatchGeneration : public VisualizationPipeline {
public:
/**
* Creates a VisualizationPipeline.
*/
CmBatchGeneration();
/**
* Virtual Destructor
**/
virtual ~CmBatchGeneration();
/// \see VisualizationPipeline::init()
virtual void init();
/// \see VisualizationPipeline::deinit()
virtual void deinit();
/// \see AbstractPipeline::getName()
virtual const std::string getName() const;
/**
* Execute this pipeline.
**/
virtual void execute();
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);
DevilImageReader _usReader;
ConfidenceMapGenerator _confidenceGenerator;
ItkImageFilter _usBlurFilter;
AdvancedUsFusion _usFusion;
};
}
#endif // CMBATCHGENERATION_H__
......@@ -44,7 +44,7 @@
namespace campvis {
const std::string AdvancedUsFusion::loggerCat_ = "CAMPVis.modules.vis.AdvancedUsFusion";
GenericOption<std::string> viewOptions[11] = {
GenericOption<std::string> viewOptions[12] = {
GenericOption<std::string>("us", "Ultrasound Only"),
GenericOption<std::string>("smoothed", "Smoothed US Only"),
GenericOption<std::string>("sharpened", "Sharpened US Only"),
......@@ -53,7 +53,8 @@ namespace campvis {
GenericOption<std::string>("mappingSaturationTSL", "Mapping Uncertainty to Saturation (TSL)"),
GenericOption<std::string>("mappingChromacityHCL", "Mapping Uncertainty to Chromacity (HCL)"),
GenericOption<std::string>("mappingChromacityHCY", "Mapping Uncertainty to Chromacity (HCY)"),
GenericOption<std::string>("mappingLAB", "Mapping Uncertainty L*a*b"),
GenericOption<std::string>("mappingLAB", "Mapping Uncertainty L*a*b*"),
GenericOption<std::string>("mappingHunterLAB", "Mapping Uncertainty Hunter L*a*b*"),
GenericOption<std::string>("mappingSharpness", "Mapping Uncertainty to Sharpness"),
GenericOption<std::string>("pixelate", "Pixelate (Experimental)")
};
......@@ -67,7 +68,7 @@ namespace campvis {
, p_targetImageID("targetImageID", "Output Image", "", DataNameProperty::WRITE)
, p_sliceNumber("sliceNumber", "Slice Number", 0, 0, 0)
, p_transferFunction("transferFunction", "Transfer Function", new SimpleTransferFunction(256))
, p_view("View", "Image to Render", viewOptions, 11)
, p_view("View", "Image to Render", viewOptions, 12)
, p_confidenceScaling("ConfidenceScaling", "Confidence Scaling", 1.f, .001f, 1000.f)
, p_hue("Hue", "Hue for Uncertainty Mapping", .15f, 0.f, 1.f)
, p_use3DTexture("Use3DTexture", "Use 3D Texture", false)
......
......@@ -48,16 +48,22 @@
namespace campvis {
const std::string DevilImageReader::loggerCat_ = "CAMPVis.modules.io.DevilImageReader";
GenericOption<std::string> importOptions[3] = {
GenericOption<std::string>("rt", "Render Target"),
GenericOption<std::string>("texture", "OpenGL Texture"),
GenericOption<std::string>("localIntensity", "Local Intensity Image")
};
DevilImageReader::DevilImageReader(IVec2Property& canvasSize)
: VisualizationProcessor(canvasSize)
, p_url("url", "Image URL", "")
, p_targetImageID("targetImageName", "Target Image ID", "DevilImageReader.output", DataNameProperty::WRITE)
, p_useRenderTarget("UseRenderTarget", "Read Into RenderTarget", false)
, p_importType("ImportType", "Import Type", importOptions, 3)
, _devilTextureReader(0)
{
addProperty(&p_url);
addProperty(&p_targetImageID);
addProperty(&p_useRenderTarget);
addProperty(&p_importType);
_devilTextureReader = new tgt::TextureReaderDevil();
}
......@@ -81,7 +87,7 @@ namespace campvis {
void DevilImageReader::process(DataContainer& data) {
tgt::Texture* tex = _devilTextureReader->loadTexture(p_url.getValue(), tgt::Texture::LINEAR, false, true, true, false);
if (tex != 0) {
if (p_useRenderTarget.getValue()) {
if (p_importType.getOptionValue() == "rt") {
ImageData id (2, tex->getDimensions(), tex->getNumChannels());
ImageRepresentationGL* image = ImageRepresentationGL::create(&id, tex);
......@@ -113,12 +119,33 @@ namespace campvis {
data.addData(p_targetImageID.getValue(), rt.first);
p_targetImageID.issueWrite();
}
else {
else if (p_importType.getOptionValue() == "texture") {
ImageData* id = new ImageData(2, tex->getDimensions(), tex->getNumChannels());
ImageRepresentationGL::create(id, tex);
data.addData(p_targetImageID.getValue(), id);
p_targetImageID.issueWrite();
}
else if (p_importType.getOptionValue() == "localIntensity") {
// TODO: Clean up pre-MICCAI mess!
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
tex->downloadTexture();
size_t numElements = tgt::hmul(tex->getDimensions());
ImageData* id = new ImageData(2, tex->getDimensions(), 1);
// TODO: use macro magic to switch through the different data types and number of channels
if (tex->getDataType() == GL_UNSIGNED_BYTE && tex->getNumChannels() == 3) {
tgt::Vector3<uint8_t>* data = reinterpret_cast<tgt::Vector3<uint8_t>*>(tex->getPixelData());
uint8_t* copy = new uint8_t[numElements];
for (size_t i = 0; i < numElements; ++i) {
copy[i] = data[i].x;
}
GenericImageRepresentationLocal<uint8_t, 1>::create(id, copy);
}
delete tex;
data.addData(p_targetImageID.getValue(), id);
p_targetImageID.issueWrite();
}
}
else {
LERROR("Could not load image.");
......
......@@ -35,6 +35,7 @@
#include "core/pipeline/visualizationprocessor.h"
#include "core/properties/datanameproperty.h"
#include "core/properties/genericproperty.h"
#include "core/properties/optionproperty.h"
namespace tgt {
class Shader;
......@@ -80,7 +81,7 @@ namespace campvis {
StringProperty p_url; ///< URL for file to read
DataNameProperty p_targetImageID; ///< image ID for read image
BoolProperty p_useRenderTarget; ///< Flag whether to read into a render target
GenericOptionProperty<std::string> p_importType;
protected:
tgt::Shader* _shader;
......
......@@ -31,11 +31,15 @@
#include "tbb/tbb.h"
#include "tgt/logmanager.h"
#include "tgt/tgt_math.h"
#include "tgt/vector.h"
#include "core/tools/interval.h"
#include "core/datastructures/imagedata.h"
#include "core/datastructures/genericimagerepresentationlocal.h"
#include "modules/randomwalk/ext/RandomWalksLib/ConfidenceMaps2DFacade.h"
#include <algorithm>
#include <vector>
namespace campvis {
......@@ -47,28 +51,26 @@ namespace campvis {
GenericOption<std::string>("Eigen-CG-Custom", "Eigen-CG-Custom"),
};
class CMGenerator {
public:
CMGenerator(const ImageRepresentationLocal* input, float* output, const std::string& solver, float alpha, float beta, float gamma, bool normalizeValues)
CMGenerator(
const ImageRepresentationLocal* input, float* output, const ConfidenceMapGenerator* processor)
: _input(input)
, _output(output)
, _solver(solver)
, _alpha(alpha)
, _beta(beta)
, _gamma(gamma)
, _normalizeValues(normalizeValues)
, _processor(processor)
{
tgtAssert(input != 0, "Pointer to Input must not be 0.");
tgtAssert(output != 0, "Pointer to Output must not be 0.");
_numElementsPerSlice = tgt::hmul(_input->getSize().xy());
_fanAngles = Interval<float>(_processor->p_angles.getValue());
_fanSize = Interval<float>(_processor->p_lengths.getValue());
}
void operator() (const tbb::blocked_range<size_t>& range) const {
// Get each slice of the range through the confidence map generator
ConfidenceMaps2DFacade _cmGenerator;
_cmGenerator.setSolver(_solver);
_cmGenerator.setSolver(_processor->p_solver.getOptionValue());
std::vector<double> inputValues;
const tgt::svec3& imageSize = _input->getSize();
inputValues.resize(_numElementsPerSlice);
......@@ -76,25 +78,74 @@ namespace campvis {
for (size_t slice = range.begin(); slice < range.end(); ++slice) {
// Since the confidence map generator expects a vector of double, we need to copy the image data...
// meanwhile, we transform the pixel order to column-major:
for (size_t i = 0; i < _numElementsPerSlice; ++i) {
size_t row = i / imageSize.y;
size_t column = i % imageSize.y;
size_t index = row + imageSize.x * column;
inputValues[i] = static_cast<double>(_input->getElementNormalized(index + offset, 0));
if (! _processor->p_curvilinear.getValue()) {
// meanwhile, we transform the pixel order to column-major:
for (size_t i = 0; i < _numElementsPerSlice; ++i) {
size_t row = i / imageSize.y;
size_t column = i % imageSize.y;
size_t index = row + imageSize.x * column;
inputValues[i] = static_cast<double>(_input->getElementNormalized(index + offset, 0));
}
}
else {
// meanwhile, we transform the polar fan geometry to cartesian:
// x, y are the indices of the target (column-major) array
for (size_t y = 0; y < imageSize.x; ++y) {
float phi = _fanAngles.getLeft() + static_cast<float>(y) / static_cast<float>(imageSize.x) * _fanAngles.size();
for (size_t x = 0; x < imageSize.y; ++x) {
float r = _fanSize.getLeft() + static_cast<float>(x) / static_cast<float>(imageSize.y) * _fanSize.size();
tgt::vec3 cc(r * cos(phi) + _processor->p_origin.getValue().x, r * sin(phi) + _processor->p_origin.getValue().y, 0.f);
tgtAssert(x + imageSize.y * y < _numElementsPerSlice, "asdasd");
inputValues[x + imageSize.y * y] = static_cast<double>(_input->getElementNormalizedLinear(cc, 0));
}
}
}
// compute confidence map
_cmGenerator.setImage(inputValues, _input->getSize().y, _input->getSize().x, _alpha, _normalizeValues);
std::vector<double> tmp = _cmGenerator.computeMap(_beta, _gamma);
_cmGenerator.setImage(inputValues, _input->getSize().y, _input->getSize().x, _processor->p_alpha.getValue(), _processor->p_normalizeValues.getValue());
std::vector<double> tmp = _cmGenerator.computeMap(_processor->p_beta.getValue(), _processor->p_gamma.getValue());
// copy back
for (size_t i = 0; i < _numElementsPerSlice; ++i) {
size_t row = i / imageSize.y;
size_t column = i % imageSize.y;
size_t index = row + imageSize.x * column;
_output[index + offset] = static_cast<float>(tmp[i]);