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

Introducing usage of C++11 lambda functions instead of functors in some...

Introducing usage of C++11 lambda functions instead of functors in some tbb::parallel_for blocks for better readibility
parent 894b868f
......@@ -40,27 +40,6 @@
namespace campvis {
class IntensityHistogramGenerator {
public:
IntensityHistogramGenerator(const ImageRepresentationLocal* intensityData, AbstractTransferFunction::IntensityHistogramType* histogram)
: _intensityData(intensityData)
, _histogram(histogram)
{}
void operator() (const tbb::blocked_range<size_t>& range) const {
for (size_t i = range.begin(); i != range.end(); ++i) {
float value = _intensityData->getElementNormalized(i, 0);
_histogram->addSample(&value);
}
}
protected:
const ImageRepresentationLocal* _intensityData;
AbstractTransferFunction::IntensityHistogramType* _histogram;
};
// ================================================================================================
const std::string AbstractTransferFunction::loggerCat_ = "CAMPVis.core.classification.AbstractTransferFunction";
AbstractTransferFunction::AbstractTransferFunction(const tgt::svec3& size, const tgt::vec2& intensityDomain /*= tgt::vec2(0.f, 1.f)*/)
......@@ -178,7 +157,12 @@ namespace campvis {
float maxs = _intensityDomain.y;
size_t numBuckets = std::min(WeaklyTypedPointer::numBytes(repLocal->getWeaklyTypedPointer()._baseType) << 8, static_cast<size_t>(512));
_intensityHistogram = new IntensityHistogramType(&mins, &maxs, &numBuckets);
tbb::parallel_for(tbb::blocked_range<size_t>(0, repLocal->getNumElements()), IntensityHistogramGenerator(repLocal, _intensityHistogram));
tbb::parallel_for(tbb::blocked_range<size_t>(0, repLocal->getNumElements()), [&] (const tbb::blocked_range<size_t>& range) {
for (size_t i = range.begin(); i != range.end(); ++i) {
float value = repLocal->getElementNormalized(i, 0);
_intensityHistogram->addSample(&value);
}
});
}
_dirtyHistogram = false;
......
......@@ -46,62 +46,6 @@
namespace campvis {
class NormalizedIntensityRangeGenerator {
public:
NormalizedIntensityRangeGenerator(const ImageRepresentationLocal* intensityData, Interval<float>* interval)
: _intensityData(intensityData)
, _interval(interval)
{
*_interval = Interval<float>();
}
void operator() (const tbb::blocked_range<size_t>& range) const {
float localMin = std::numeric_limits<float>::max();
float localMax = -std::numeric_limits<float>::max();
for (size_t i = range.begin(); i != range.end(); ++i) {
float value = _intensityData->getElementNormalized(i, 0);
localMax = std::max(localMax, value);
localMin = std::min(localMin, value);
}
{
// TODO: there is probably a more elegant method...
tbb::spin_mutex::scoped_lock(_mutex);
_interval->nibble(localMin);
_interval->nibble(localMax);
}
}
protected:
const ImageRepresentationLocal* _intensityData;
Interval<float>* _interval;
tbb::spin_mutex _mutex;
};
// ================================================================================================
class IntensityHistogramGenerator {
public:
IntensityHistogramGenerator(const ImageRepresentationLocal* intensityData, ImageRepresentationLocal::IntensityHistogramType* histogram)
: _intensityData(intensityData)
, _histogram(histogram)
{}
void operator() (const tbb::blocked_range<size_t>& range) const {
for (size_t i = range.begin(); i != range.end(); ++i) {
float value = _intensityData->getElementNormalized(i, 0);
_histogram->addSample(&value);
}
}
protected:
const ImageRepresentationLocal* _intensityData;
ImageRepresentationLocal::IntensityHistogramType* _histogram;
};
// ================================================================================================
const std::string ImageRepresentationLocal::loggerCat_ = "CAMPVis.core.datastructures.ImageRepresentationLocal";
ImageRepresentationLocal::ImageRepresentationLocal(ImageData* parent, WeaklyTypedPointer::BaseType baseType)
......@@ -202,7 +146,27 @@ namespace campvis {
}
void ImageRepresentationLocal::computeNormalizedIntensityRange() const {
tbb::parallel_for(tbb::blocked_range<size_t>(0, getNumElements()), NormalizedIntensityRangeGenerator(this, &_normalizedIntensityRange));
_normalizedIntensityRange = Interval<float>(); // reset interval to empty one
tbb::spin_mutex _mutex; // mutex to protect for concurrent access
tbb::parallel_for(tbb::blocked_range<size_t>(0, getNumElements()), [&] (const tbb::blocked_range<size_t>& range) {
float localMin = std::numeric_limits<float>::max();
float localMax = -std::numeric_limits<float>::max();
for (size_t i = range.begin(); i != range.end(); ++i) {
float value = this->getElementNormalized(i, 0);
localMax = std::max(localMax, value);
localMin = std::min(localMin, value);
}
{
// TODO: there is probably a more elegant method...
tbb::spin_mutex::scoped_lock(mutex);
_normalizedIntensityRange.nibble(localMin);
_normalizedIntensityRange.nibble(localMax);
}
});
_intensityRangeDirty = false;
}
......@@ -214,7 +178,12 @@ namespace campvis {
float maxs = i.getRight();
size_t numBuckets = 1024;
_intensityHistogram = new IntensityHistogramType(&mins, &maxs, &numBuckets);
tbb::parallel_for(tbb::blocked_range<size_t>(0, getNumElements()), IntensityHistogramGenerator(this, _intensityHistogram));
tbb::parallel_for(tbb::blocked_range<size_t>(0, getNumElements()), [&] (const tbb::blocked_range<size_t>& range) {
for (size_t i = range.begin(); i != range.end(); ++i) {
float value = this->getElementNormalized(i, 0);
_intensityHistogram->addSample(&value);
}
});
}
ImageRepresentationLocal* ImageRepresentationLocal::convertToGenericLocal(const AbstractImageRepresentation* source, const WeaklyTypedPointer& wtp) {
......
......@@ -39,51 +39,6 @@
namespace campvis {
class ApplyCentralDifferences {
public:
ApplyCentralDifferences(const ImageRepresentationLocal* input, GenericImageRepresentationLocal<float, 4>* output)
: _input(input)
, _output(output)
{
}
void operator() (const tbb::blocked_range<size_t>& range) const {
for (size_t i = range.begin(); i != range.end(); ++i) {
tgt::svec3 pos = _input->getParent()->indexToPosition(i);
const tgt::svec3& size = _input->getSize();
float dx, dy, dz, mdx, mdy, mdz;
dx = dy = dz = mdx = mdy = mdz = 0.f;
if (pos.x != size.x - 1)
dx = _input->getElementNormalized(pos + tgt::svec3(1, 0, 0), 0);
if (pos.y != size.y - 1)
dy = _input->getElementNormalized(pos + tgt::svec3(0, 1, 0), 0);
if (pos.z != size.z - 1)
dz = _input->getElementNormalized(pos + tgt::svec3(0, 0, 1), 0);
if (pos.x != 0)
mdx = _input->getElementNormalized(pos + tgt::svec3(-1, 0, 0), 0);
if (pos.y != 0)
mdy = _input->getElementNormalized(pos + tgt::svec3(0, -1, 0), 0);
if (pos.z != 0)
mdz = _input->getElementNormalized(pos + tgt::svec3(0, 0, -1), 0);
tgt::vec3 gradient(mdx - dx, mdy - dy, mdz - dz);
gradient /= _input->getParent()->getMappingInformation().getVoxelSize() * tgt::vec3(2.f);
_output->setElement(i, tgt::vec4(gradient, tgt::length(gradient)));
}
}
protected:
const ImageRepresentationLocal* _input;
GenericImageRepresentationLocal<float, 4>* _output;
};
// ================================================================================================
const std::string GradientVolumeGenerator::loggerCat_ = "CAMPVis.modules.classification.GradientVolumeGenerator";
GradientVolumeGenerator::GradientVolumeGenerator()
......@@ -105,7 +60,36 @@ namespace campvis {
if (input != 0) {
ImageData* id = new ImageData(input->getDimensionality(), input->getSize(), 4);
GenericImageRepresentationLocal<float, 4>* output = GenericImageRepresentationLocal<float, 4>::create(id, 0);
tbb::parallel_for(tbb::blocked_range<size_t>(0, input->getNumElements()), ApplyCentralDifferences(input, output));
tbb::parallel_for(tbb::blocked_range<size_t>(0, input->getNumElements()), [&] (const tbb::blocked_range<size_t>& range) {
for (size_t i = range.begin(); i != range.end(); ++i) {
tgt::svec3 pos = input->getParent()->indexToPosition(i);
const tgt::svec3& size = input->getSize();
float dx, dy, dz, mdx, mdy, mdz;
dx = dy = dz = mdx = mdy = mdz = 0.f;
if (pos.x != size.x - 1)
dx = input->getElementNormalized(pos + tgt::svec3(1, 0, 0), 0);
if (pos.y != size.y - 1)
dy = input->getElementNormalized(pos + tgt::svec3(0, 1, 0), 0);
if (pos.z != size.z - 1)
dz = input->getElementNormalized(pos + tgt::svec3(0, 0, 1), 0);
if (pos.x != 0)
mdx = input->getElementNormalized(pos + tgt::svec3(-1, 0, 0), 0);
if (pos.y != 0)
mdy = input->getElementNormalized(pos + tgt::svec3(0, -1, 0), 0);
if (pos.z != 0)
mdz = input->getElementNormalized(pos + tgt::svec3(0, 0, -1), 0);
tgt::vec3 gradient(mdx - dx, mdy - dy, mdz - dz);
gradient /= input->getParent()->getMappingInformation().getVoxelSize() * tgt::vec3(2.f);
output->setElement(i, tgt::vec4(gradient, tgt::length(gradient)));
}
});
data.addData(p_targetImageID.getValue(), id);
}
......
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