Commit aa87d2b8 authored by schultezub's avatar schultezub
Browse files

Introducing CsvdImageReader, some fixes in MhdImageReader and VtkImageReader

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@455 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 7c829bae
// ================================================================================================
//
// 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 "csvdimagereader.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include "tgt/filesystem.h"
#include "core/datastructures/imagedata.h"
#include "core/datastructures/imagerepresentationdisk.h"
#include "core/datastructures/genericimagerepresentationlocal.h"
#include "core/tools/textfileparser.h"
namespace campvis {
const std::string CsvdImageReader::loggerCat_ = "CAMPVis.modules.io.CsvdImageReader";
CsvdImageReader::CsvdImageReader()
: AbstractProcessor()
, p_url("url", "Image URL", "")
, p_targetImageID("targetImageName", "Target Image ID", "CsvdImageReader.output", DataNameProperty::WRITE)
, p_imageOffset("ImageOffset", "Image Offset in mm", tgt::vec3(0.f), tgt::vec3(-10000.f), tgt::vec3(10000.f))
, p_voxelSize("VoxelSize", "Voxel Size in mm", tgt::vec3(1.f), tgt::vec3(-100.f), tgt::vec3(100.f))
{
addProperty(&p_url);
addProperty(&p_targetImageID);
addProperty(&p_imageOffset);
addProperty(&p_voxelSize);
}
CsvdImageReader::~CsvdImageReader() {
}
void CsvdImageReader::process(DataContainer& data) {
try {
// start parsing
TextFileParser tfp(p_url.getValue(), true, "=");
tfp.parse<TextFileParser::ItemSeparatorLines>();
// init optional parameters with sane default values
size_t dimensionality = 3;
tgt::svec3 size;
WeaklyTypedPointer::BaseType pt;
size_t numChannels = 1;
tgt::vec3 voxelSize(1.f);
tgt::vec3 imageOffset(0.f);
// dimensionality and size
if (tfp.hasKey("Size")) {
size = tfp.getSvec3("Size");
}
else {
LERROR("Error while parsing CSVD header: No Size specified.");
return;
}
// element type
std::string et = tfp.getString("ElementType");
if (et == "UINT8")
pt = WeaklyTypedPointer::UINT8;
else if (et == "INT8")
pt = WeaklyTypedPointer::INT8;
else if (et == "UINT16")
pt = WeaklyTypedPointer::UINT16;
else if (et == "INT16")
pt = WeaklyTypedPointer::INT16;
else if (et == "UINT32")
pt = WeaklyTypedPointer::UINT32;
else if (et == "INT32")
pt = WeaklyTypedPointer::INT32;
else if (et == "FLOAT")
pt = WeaklyTypedPointer::FLOAT;
else {
LERROR("Error while parsing MHD header: Unsupported element type: " << et);
return;
}
// dimensionality and size
if (tfp.hasKey("CsvFileBaseName")) {
ImageData* image = new ImageData(dimensionality, size, 1);
ImageRepresentationLocal* rep = 0;
size_t index = 0;
std::string url = StringUtils::trim(tfp.getString("CsvFileBaseName"));
url = tgt::FileSystem::cleanupPath(tgt::FileSystem::dirName(p_url.getValue()) + "/" + url);
// start parsing of CSV files
#define DISPATCH_PARSING(WTP_TYPE, C_TYPE, TMP_TYPE) \
if (pt == WTP_TYPE) {\
C_TYPE* dataArray = new C_TYPE[tgt::hmul(size)]; \
for (size_t slice = 0; slice < size.z; ++slice) { \
std::stringstream ss; \
ss << url << slice << ".csv"; \
std::string concatenated = ss.str(); \
\
std::ifstream file(concatenated.c_str(), std::ifstream::in); \
if (!file.is_open() || file.bad()) \
throw tgt::FileException("Could not open file " + ss.str() + " for reading.", p_url.getValue()); \
\
TMP_TYPE tmp; \
for (size_t column = 0; column < size.y; ++column) { \
for (size_t row = 0; row < size.x && file.good(); ++row) { \
file >> tmp; \
dataArray[index++] = static_cast<C_TYPE>(tmp); \
file.get(); /* TODO: simple hack to advance to next character - but there might be more than one... */ \
} \
} \
} \
rep = GenericImageRepresentationLocal<C_TYPE, 1>::create(image, dataArray); \
}
DISPATCH_PARSING(WeaklyTypedPointer::UINT8 , uint8_t, uint16_t)
else DISPATCH_PARSING(WeaklyTypedPointer::INT8 , int8_t, int16_t)
else DISPATCH_PARSING(WeaklyTypedPointer::UINT16, uint16_t, uint16_t)
else DISPATCH_PARSING(WeaklyTypedPointer::INT16 , int16_t, int16_t)
else DISPATCH_PARSING(WeaklyTypedPointer::UINT32, uint32_t, uint32_t)
else DISPATCH_PARSING(WeaklyTypedPointer::INT32 , int32_t, int32_t)
else DISPATCH_PARSING(WeaklyTypedPointer::FLOAT , float, float)
if (rep != 0) {
// all parsing done - lets create the image:
image->setMappingInformation(ImageMappingInformation(size, imageOffset + p_imageOffset.getValue(), voxelSize + p_voxelSize.getValue()));
data.addData(p_targetImageID.getValue(), image);
p_targetImageID.issueWrite();
}
else {
throw tgt::FileException("Error while parsing the data.", p_url.getValue());
}
}
else {
LERROR("Error while parsing CSVD header: No file names specified.");
return;
}
}
catch (tgt::Exception& e) {
LERROR("Error while parsing MHD header: " << e.what());
return;
}
catch (std::exception& e) {
LERROR("Error while parsing MHD header: " << e.what());
return;
}
_invalidationLevel.setValid();
}
}
\ 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 CSVDIMAGEREADER_H__
#define CSVDIMAGEREADER_H__
#include <string>
#include "core/pipeline/abstractprocessor.h"
#include "core/properties/datanameproperty.h"
#include "core/properties/numericproperty.h"
namespace campvis {
/**
* Reads a CSVD to read multiple CSV image files into the pipeline.
* This YANF (yet another neat format) is proudly provided by Christian Schulte zu Berge.
*/
class CsvdImageReader : public AbstractProcessor {
public:
/**
* Constructs a new CsvdImageReader Processor
**/
CsvdImageReader();
/**
* Destructor
**/
virtual ~CsvdImageReader();
/**
* Reads the MHD file into an ImageRepresentationDisk representation
* \param data DataContainer to work on
*/
virtual void process(DataContainer& data);
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "CsvdImageReader"; };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Reads a CSVD to read multiple CSV image files into the pipeline."; };
StringProperty p_url; ///< URL for file to read
DataNameProperty p_targetImageID; ///< image ID for read image
Vec3Property p_imageOffset; ///< Image Offset in mm
Vec3Property p_voxelSize; ///< Voxel Size in mm
protected:
static const std::string loggerCat_;
};
}
#endif // CSVDIMAGEREADER_H__
\ No newline at end of file
......@@ -72,6 +72,7 @@ namespace campvis {
size_t dimensionality;
tgt::svec3 size;
WeaklyTypedPointer::BaseType pt;
size_t numChannels = 1;
size_t offset = 0;
EndianHelper::Endianness e = EndianHelper::LITTLE_ENDIAN;
......@@ -92,7 +93,7 @@ namespace campvis {
// dimensionality and size
dimensionality = tfp.getSizeT("NDims");
if (dimensionality == 2)
size = tgt::svec3(tfp.getSvec2("DimSize"), 0);
size = tgt::svec3(tfp.getSvec2("DimSize"), 1);
else if (dimensionality == 3)
size = tfp.getSvec3("DimSize");
else {
......@@ -138,7 +139,9 @@ namespace campvis {
if (tfp.hasKey("Position")) {
imageOffset = tfp.getVec3("Position");
}
if (tfp.hasKey("ElementNumberOfChannels")) {
numChannels = tfp.getSizeT("ElementNumberOfChannels");
}
// get raw image location:
url = StringUtils::trim(tfp.getString("ElementDataFile"));
......@@ -169,7 +172,7 @@ namespace campvis {
// all parsing done - lets create the image:
ImageData* image = new ImageData(dimensionality, size, 1);
ImageData* image = new ImageData(dimensionality, size, numChannels);
ImageRepresentationDisk::create(image, url, pt, offset, e);
image->setMappingInformation(ImageMappingInformation(size, imageOffset + p_imageOffset.getValue(), voxelSize + p_voxelSize.getValue()));
data.addData(p_targetImageID.getValue(), image);
......
......@@ -164,23 +164,23 @@ namespace campvis {
#define DISPATCH_PARSING(VTK_TYPE, C_TYPE, TMP_TYPE) \
do { \
if (splitted[3] == VTK_TYPE) { \
C_TYPE* data = new C_TYPE[numPoints]; \
C_TYPE* dataArray = new C_TYPE[numPoints]; \
TMP_TYPE tmp; \
for (size_t i = 0; i < numPoints && file.good(); ++i) { \
file >> tmp; \
data[i] = static_cast<C_TYPE>(tmp); \
dataArray[i] = static_cast<C_TYPE>(tmp); \
} \
rep = GenericImageRepresentationLocal<C_TYPE, 1>::create(image, data); \
rep = GenericImageRepresentationLocal<C_TYPE, 1>::create(image, dataArray); \
} \
} while (0)
DISPATCH_PARSING("unsigned_char", uint8_t, uint16_t);
DISPATCH_PARSING("char", int8_t, int16_t);
DISPATCH_PARSING("unsigned_short", uint16_t, uint16_t);
DISPATCH_PARSING("short", int16_t, int16_t);
DISPATCH_PARSING("unsigned_int", uint32_t, uint32_t);
DISPATCH_PARSING("int", int32_t, int32_t);
DISPATCH_PARSING("float", float, float);
DISPATCH_PARSING("unsigned_char" , uint8_t, uint16_t);
DISPATCH_PARSING("char" , int8_t, int16_t);
DISPATCH_PARSING("unsigned_short" , uint16_t, uint16_t);
DISPATCH_PARSING("short" , int16_t, int16_t);
DISPATCH_PARSING("unsigned_int" , uint32_t, uint32_t);
DISPATCH_PARSING("int" , int32_t, int32_t);
DISPATCH_PARSING("float" , float, float);
if (rep != 0) {
// all parsing done - lets create the image:
......
......@@ -146,7 +146,7 @@ namespace campvis {
float* outputValues = new float[numElements];
tbb::parallel_for(
tbb::blocked_range<size_t>(0, imageSize.z, imageSize.z),
tbb::blocked_range<size_t>(0, imageSize.z),
CMGenerator(input, outputValues, p_solver.getOptionValue(), p_alpha.getValue(), p_beta.getValue(), p_gamma.getValue(), p_normalizeValues.getValue()));
ImageData* output = new ImageData(input->getDimensionality(), input->getSize(), 1);
......
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